Merge changes from topic "RemoteAnimationCanceled_with_Occluded-tm-dev" into tm-dev am: 97641ffe50 am: 574cd4ca97

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18976454

Change-Id: Iabc0b5ea5f85fa844c4c834f9bb8ad842f7aefab
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java
index 452bb0a..0620721 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java
@@ -19,6 +19,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 
+import android.graphics.Rect;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.perftests.utils.ManualBenchmarkState;
@@ -86,6 +87,7 @@
         final InsetsVisibilities mRequestedVisibilities = new InsetsVisibilities();
         final InsetsState mOutInsetsState = new InsetsState();
         final InsetsSourceControl[] mOutControls = new InsetsSourceControl[0];
+        final Rect mOutAttachedFrame = new Rect();
 
         TestWindow() {
             mLayoutParams.setTitle(TestWindow.class.getName());
@@ -104,7 +106,7 @@
                 long startTime = SystemClock.elapsedRealtimeNanos();
                 session.addToDisplay(this, mLayoutParams, View.VISIBLE,
                         Display.DEFAULT_DISPLAY, mRequestedVisibilities, inputChannel,
-                        mOutInsetsState, mOutControls);
+                        mOutInsetsState, mOutControls, mOutAttachedFrame);
                 final long elapsedTimeNsOfAdd = SystemClock.elapsedRealtimeNanos() - startTime;
                 state.addExtraResult("add", elapsedTimeNsOfAdd);
 
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
index c43c8329..9b64edf 100644
--- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
@@ -164,6 +164,13 @@
             @ElapsedRealtimeLong long elapsedRealtime);
 
     /**
+     * Puts the list of apps in the {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RARE}
+     * bucket.
+     * @param restoredApps the list of restored apps
+     */
+    void restoreAppsToRare(@NonNull Set<String> restoredApps, int userId);
+
+    /**
      * Put the specified app in the
      * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED}
      * bucket. If it has been used by the user recently, the restriction will delayed until an
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 9e3e355..5d9f335 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -23,6 +23,7 @@
 import static android.app.usage.UsageStatsManager.REASON_MAIN_PREDICTED;
 import static android.app.usage.UsageStatsManager.REASON_MAIN_TIMEOUT;
 import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
+import static android.app.usage.UsageStatsManager.REASON_SUB_DEFAULT_APP_RESTORED;
 import static android.app.usage.UsageStatsManager.REASON_SUB_DEFAULT_APP_UPDATE;
 import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY;
 import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_USER_FLAG_INTERACTION;
@@ -1605,6 +1606,26 @@
     }
 
     @Override
+    public void restoreAppsToRare(Set<String> restoredApps, int userId) {
+        final int reason = REASON_MAIN_DEFAULT | REASON_SUB_DEFAULT_APP_RESTORED;
+        final long nowElapsed = mInjector.elapsedRealtime();
+        for (String packageName : restoredApps) {
+            // If the package is not installed, don't allow the bucket to be set.
+            if (!mInjector.isPackageInstalled(packageName, 0, userId)) {
+                Slog.e(TAG, "Tried to restore bucket for uninstalled app: " + packageName);
+                continue;
+            }
+
+            final int standbyBucket = getAppStandbyBucket(packageName, userId, nowElapsed, false);
+            // Only update the standby bucket to RARE if the app is still in the NEVER bucket.
+            if (standbyBucket == STANDBY_BUCKET_NEVER) {
+                setAppStandbyBucket(packageName, userId, STANDBY_BUCKET_RARE, reason,
+                        nowElapsed, false);
+            }
+        }
+    }
+
+    @Override
     public void setAppStandbyBucket(@NonNull String packageName, int bucket, int userId,
             int callingUid, int callingPid) {
         setAppStandbyBuckets(
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 1796c7b..8bfb1ae 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -488,8 +488,6 @@
     field public static final int WINDOWING_MODE_FULLSCREEN = 1; // 0x1
     field public static final int WINDOWING_MODE_MULTI_WINDOW = 6; // 0x6
     field public static final int WINDOWING_MODE_PINNED = 2; // 0x2
-    field public static final int WINDOWING_MODE_SPLIT_SCREEN_PRIMARY = 3; // 0x3
-    field public static final int WINDOWING_MODE_SPLIT_SCREEN_SECONDARY = 4; // 0x4
     field public static final int WINDOWING_MODE_UNDEFINED = 0; // 0x0
   }
 
@@ -1863,7 +1861,6 @@
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public String getUserType();
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List<android.content.pm.UserInfo> getUsers(boolean, boolean, boolean);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean hasBaseUserRestriction(@NonNull String, @NonNull android.os.UserHandle);
-    method public static boolean isGuestUserEphemeral();
     method public static boolean isSplitSystemUser();
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo preCreateUser(@NonNull String) throws android.os.UserManager.UserOperationException;
   }
@@ -3402,7 +3399,8 @@
     method @NonNull public android.window.WindowContainerTransaction reparentTasks(@Nullable android.window.WindowContainerToken, @Nullable android.window.WindowContainerToken, @Nullable int[], @Nullable int[], boolean);
     method @NonNull public android.window.WindowContainerTransaction scheduleFinishEnterPip(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect);
     method @NonNull public android.window.WindowContainerTransaction setActivityWindowingMode(@NonNull android.window.WindowContainerToken, int);
-    method @NonNull public android.window.WindowContainerTransaction setAdjacentRoots(@NonNull android.window.WindowContainerToken, @NonNull android.window.WindowContainerToken, boolean);
+    method @NonNull public android.window.WindowContainerTransaction setAdjacentRoots(@NonNull android.window.WindowContainerToken, @NonNull android.window.WindowContainerToken);
+    method @Deprecated @NonNull public android.window.WindowContainerTransaction setAdjacentRoots(@NonNull android.window.WindowContainerToken, @NonNull android.window.WindowContainerToken, boolean);
     method @NonNull public android.window.WindowContainerTransaction setAdjacentTaskFragments(@NonNull android.os.IBinder, @Nullable android.os.IBinder, @Nullable android.window.WindowContainerTransaction.TaskFragmentAdjacentParams);
     method @NonNull public android.window.WindowContainerTransaction setAppBounds(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect);
     method @NonNull public android.window.WindowContainerTransaction setBounds(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 7141259..90c37d1 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6433,6 +6433,20 @@
     }
 
     /**
+     * Ensures the activity's result is immediately returned to the caller when {@link #finish()}
+     * is invoked
+     *
+     * <p>Should be invoked alongside {@link #setResult(int, Intent)}, so the provided results are
+     * in place before finishing. Must only be invoked during MediaProjection setup.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
+    public final void setForceSendResultForMediaProjection() {
+        ActivityClient.getInstance().setForceSendResultForMediaProjection(mToken);
+    }
+
+    /**
      * Call this to set the result that your activity will return to its
      * caller.
      *
diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java
index 73678d9..1d3b5e2 100644
--- a/core/java/android/app/ActivityClient.java
+++ b/core/java/android/app/ActivityClient.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.res.Configuration;
@@ -184,6 +185,15 @@
         }
     }
 
+    @RequiresPermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
+    void setForceSendResultForMediaProjection(IBinder token) {
+        try {
+            getActivityClientController().setForceSendResultForMediaProjection(token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     public boolean isTopOfTask(IBinder token) {
         try {
             return getActivityClientController().isTopOfTask(token);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 5d1d225..e25e374 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2210,7 +2210,6 @@
             pw.print(((baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0));
             pw.print(" activityType="); pw.print(activityTypeToString(getActivityType()));
             pw.print(" windowingMode="); pw.print(windowingModeToString(getWindowingMode()));
-            pw.print(" supportsSplitScreenMultiWindow="); pw.print(supportsSplitScreenMultiWindow);
             pw.print(" supportsMultiWindow=");
             pw.println(supportsMultiWindow);
             if (taskDescription != null) {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index ae8809d..546efaa 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3423,26 +3423,12 @@
         }
     }
 
-    /**
-     * Returns {@code true} if the {@link android.app.ActivityManager.ProcessState} of the current
-     * process is cached.
-     */
-    @Override
-    @VisibleForTesting
-    public boolean isCachedProcessState() {
-        synchronized (mAppThread) {
-            return mLastProcessState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
-        }
-    }
-
     @Override
     public void updateProcessState(int processState, boolean fromIpc) {
-        final boolean wasCached;
         synchronized (mAppThread) {
             if (mLastProcessState == processState) {
                 return;
             }
-            wasCached = isCachedProcessState();
             mLastProcessState = processState;
             updateVmProcessState(processState);
             if (localLOGV) {
@@ -3450,22 +3436,6 @@
                         + (fromIpc ? " (from ipc" : ""));
             }
         }
-
-        // Handle the pending configuration if the process state is changed from cached to
-        // non-cached. Except the case where there is a launching activity because the
-        // LaunchActivityItem will handle it.
-        if (wasCached && !isCachedProcessState() && mNumLaunchingActivities.get() == 0) {
-            final Configuration pendingConfig =
-                    mConfigurationController.getPendingConfiguration(false /* clearPending */);
-            if (pendingConfig == null) {
-                return;
-            }
-            if (Looper.myLooper() == mH.getLooper()) {
-                handleConfigurationChanged(pendingConfig);
-            } else {
-                sendMessage(H.CONFIGURATION_CHANGED, pendingConfig);
-            }
-        }
     }
 
     /** Update VM state based on ActivityManager.PROCESS_STATE_* constants. */
@@ -5893,16 +5863,16 @@
 
         final boolean movedToDifferentDisplay = isDifferentDisplay(activity.getDisplayId(),
                 displayId);
-        final Configuration currentConfig = activity.mCurrentConfig;
-        final int diff = currentConfig.diffPublicOnly(newConfig);
-        final boolean hasPublicConfigChange = diff != 0;
+        final Configuration currentResConfig = activity.getResources().getConfiguration();
+        final int diff = currentResConfig.diffPublicOnly(newConfig);
+        final boolean hasPublicResConfigChange = diff != 0;
         final ActivityClientRecord r = getActivityClient(activityToken);
         // TODO(b/173090263): Use diff instead after the improvement of AssetManager and
         // ResourcesImpl constructions.
-        final boolean shouldUpdateResources = hasPublicConfigChange
-                || shouldUpdateResources(activityToken, currentConfig, newConfig, amOverrideConfig,
-                movedToDifferentDisplay, hasPublicConfigChange);
-        final boolean shouldReportChange = shouldReportChange(diff, currentConfig, newConfig,
+        final boolean shouldUpdateResources = hasPublicResConfigChange
+                || shouldUpdateResources(activityToken, currentResConfig, newConfig,
+                amOverrideConfig, movedToDifferentDisplay, hasPublicResConfigChange);
+        final boolean shouldReportChange = shouldReportChange(activity.mCurrentConfig, newConfig,
                 r != null ? r.mSizeConfigurations : null,
                 activity.mActivityInfo.getRealConfigChanged());
         // Nothing significant, don't proceed with updating and reporting.
@@ -5926,9 +5896,6 @@
                 amOverrideConfig, contextThemeWrapperOverrideConfig);
         mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig, displayId);
 
-        activity.mConfigChangeFlags = 0;
-        activity.mCurrentConfig = new Configuration(newConfig);
-
         // Apply the ContextThemeWrapper override if necessary.
         // NOTE: Make sure the configurations are not modified, as they are treated as immutable
         // in many places.
@@ -5939,8 +5906,10 @@
             activity.dispatchMovedToDisplay(displayId, configToReport);
         }
 
+        activity.mConfigChangeFlags = 0;
         if (shouldReportChange) {
             activity.mCalled = false;
+            activity.mCurrentConfig = new Configuration(newConfig);
             activity.onConfigurationChanged(configToReport);
             if (!activity.mCalled) {
                 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
@@ -5955,8 +5924,6 @@
      * Returns {@code true} if {@link Activity#onConfigurationChanged(Configuration)} should be
      * dispatched.
      *
-     * @param publicDiff Usually computed by {@link Configuration#diffPublicOnly(Configuration)}.
-     *                   This parameter is to prevent we compute it again.
      * @param currentConfig The current configuration cached in {@link Activity#mCurrentConfig}.
      *                      It is {@code null} before the first config update from the server side.
      * @param newConfig The updated {@link Configuration}
@@ -5965,9 +5932,10 @@
      * @return {@code true} if the config change should be reported to the Activity
      */
     @VisibleForTesting
-    public static boolean shouldReportChange(int publicDiff, @Nullable Configuration currentConfig,
+    public static boolean shouldReportChange(@Nullable Configuration currentConfig,
             @NonNull Configuration newConfig, @Nullable SizeConfigurationBuckets sizeBuckets,
             int handledConfigChanges) {
+        final int publicDiff = currentConfig.diffPublicOnly(newConfig);
         // Don't report the change if there's no public diff between current and new config.
         if (publicDiff == 0) {
             return false;
diff --git a/core/java/android/app/ActivityThreadInternal.java b/core/java/android/app/ActivityThreadInternal.java
index b9ad5c3..72506b9 100644
--- a/core/java/android/app/ActivityThreadInternal.java
+++ b/core/java/android/app/ActivityThreadInternal.java
@@ -32,8 +32,6 @@
 
     boolean isInDensityCompatMode();
 
-    boolean isCachedProcessState();
-
     Application getApplication();
 
     ArrayList<ComponentCallbacks2> collectComponentCallbacks(boolean includeUiContexts);
diff --git a/core/java/android/app/ConfigurationController.java b/core/java/android/app/ConfigurationController.java
index 1a77b65..18dc1ce1 100644
--- a/core/java/android/app/ConfigurationController.java
+++ b/core/java/android/app/ConfigurationController.java
@@ -124,12 +124,6 @@
      * @param config The new configuration.
      */
     void handleConfigurationChanged(@NonNull Configuration config) {
-        if (mActivityThread.isCachedProcessState()) {
-            updatePendingConfiguration(config);
-            // If the process is in a cached state, delay the handling until the process is no
-            // longer cached.
-            return;
-        }
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
         handleConfigurationChanged(config, null /* compat */);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl
index 0138186..7aeb2b2 100644
--- a/core/java/android/app/IActivityClientController.aidl
+++ b/core/java/android/app/IActivityClientController.aidl
@@ -67,6 +67,12 @@
     boolean finishActivityAffinity(in IBinder token);
     /** Finish all activities that were started for result from the specified activity. */
     void finishSubActivity(in IBinder token, in String resultWho, int requestCode);
+    /**
+     * Indicates that when the activity finsihes, the result should be immediately sent to the
+     * originating activity. Must only be invoked during MediaProjection setup.
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)")
+    void setForceSendResultForMediaProjection(in IBinder token);
 
     boolean isTopOfTask(in IBinder token);
     boolean willActivityBeVisible(in IBinder token);
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 2a1883d..d275c83 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -365,8 +365,8 @@
             @NonNull Configuration config) {
         config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
         config.densityDpi = dm.densityDpi;
-        config.screenWidthDp = (int) (dm.widthPixels / dm.density);
-        config.screenHeightDp = (int) (dm.heightPixels / dm.density);
+        config.screenWidthDp = (int) (dm.widthPixels / dm.density + 0.5f);
+        config.screenHeightDp = (int) (dm.heightPixels / dm.density + 0.5f);
         int sl = Configuration.resetScreenLayout(config.screenLayout);
         if (dm.widthPixels > dm.heightPixels) {
             config.orientation = Configuration.ORIENTATION_LANDSCAPE;
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 7910f1a..b09463e 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -140,13 +140,6 @@
     public LocusId mTopActivityLocusId;
 
     /**
-     * True if the task can go in the split-screen primary stack.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public boolean supportsSplitScreenMultiWindow;
-
-    /**
      * Whether this task supports multi windowing modes based on the device settings and the
      * root activity resizability and configuration.
      * @hide
@@ -499,7 +492,6 @@
         lastActiveTime = source.readLong();
 
         taskDescription = source.readTypedObject(ActivityManager.TaskDescription.CREATOR);
-        supportsSplitScreenMultiWindow = source.readBoolean();
         supportsMultiWindow = source.readBoolean();
         resizeMode = source.readInt();
         configuration.readFromParcel(source);
@@ -546,7 +538,6 @@
         dest.writeLong(lastActiveTime);
 
         dest.writeTypedObject(taskDescription, flags);
-        dest.writeBoolean(supportsSplitScreenMultiWindow);
         dest.writeBoolean(supportsMultiWindow);
         dest.writeInt(resizeMode);
         configuration.writeToParcel(dest, flags);
@@ -584,7 +575,6 @@
                 + " realActivity=" + realActivity
                 + " numActivities=" + numActivities
                 + " lastActiveTime=" + lastActiveTime
-                + " supportsSplitScreenMultiWindow=" + supportsSplitScreenMultiWindow
                 + " supportsMultiWindow=" + supportsMultiWindow
                 + " resizeMode=" + resizeMode
                 + " isResizeable=" + isResizeable
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index e96a986..d0ea8d4 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -104,19 +104,6 @@
     public static final int WINDOWING_MODE_FULLSCREEN = 1;
     /** Always on-top (always visible). of other siblings in its parent container. */
     public static final int WINDOWING_MODE_PINNED = 2;
-    /** The primary container driving the screen to be in split-screen mode. */
-    // TODO: Remove once split-screen is migrated to wm-shell.
-    public static final int WINDOWING_MODE_SPLIT_SCREEN_PRIMARY = 3;
-    /**
-     * The containers adjacent to the {@link #WINDOWING_MODE_SPLIT_SCREEN_PRIMARY} container in
-     * split-screen mode.
-     * NOTE: Containers launched with the windowing mode with APIs like
-     * {@link ActivityOptions#setLaunchWindowingMode(int)} will be launched in
-     * {@link #WINDOWING_MODE_FULLSCREEN} if the display isn't currently in split-screen windowing
-     * mode
-     */
-    // TODO: Remove once split-screen is migrated to wm-shell.
-    public static final int WINDOWING_MODE_SPLIT_SCREEN_SECONDARY = 4;
     /** Can be freely resized within its parent container. */
     // TODO: Remove once freeform is migrated to wm-shell.
     public static final int WINDOWING_MODE_FREEFORM = 5;
@@ -129,8 +116,6 @@
             WINDOWING_MODE_FULLSCREEN,
             WINDOWING_MODE_MULTI_WINDOW,
             WINDOWING_MODE_PINNED,
-            WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
-            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
             WINDOWING_MODE_FREEFORM,
     })
     public @interface WindowingMode {}
@@ -890,9 +875,8 @@
     }
 
     /**
-     * Returns true if this container can be put in either
-     * {@link #WINDOWING_MODE_SPLIT_SCREEN_PRIMARY} or
-     * {@link #WINDOWING_MODE_SPLIT_SCREEN_SECONDARY} windowing modes based on its current state.
+     * Returns true if this container can be put in {@link #WINDOWING_MODE_MULTI_WINDOW}
+     * windowing mode based on its current state.
      * @hide
      */
     public boolean supportSplitScreenWindowingMode() {
@@ -911,8 +895,6 @@
             case WINDOWING_MODE_FULLSCREEN: return "fullscreen";
             case WINDOWING_MODE_MULTI_WINDOW: return "multi-window";
             case WINDOWING_MODE_PINNED: return "pinned";
-            case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: return "split-screen-primary";
-            case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY: return "split-screen-secondary";
             case WINDOWING_MODE_FREEFORM: return "freeform";
         }
         return String.valueOf(windowingMode);
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
index d61abc6..e213c93 100644
--- a/core/java/android/app/usage/UsageStats.java
+++ b/core/java/android/app/usage/UsageStats.java
@@ -293,6 +293,17 @@
     }
 
     /**
+     * Returns the last time the package was used - defined by the latest of
+     * mLastTimeUsed, mLastTimeVisible, mLastTimeForegroundServiceUsed, or mLastTimeComponentUsed.
+     * @hide
+     */
+    public long getLastTimePackageUsed() {
+        return Math.max(mLastTimeUsed,
+                        Math.max(mLastTimeVisible,
+                                 Math.max(mLastTimeForegroundServiceUsed, mLastTimeComponentUsed)));
+    }
+
+    /**
      * Returns the number of times the app was launched as an activity from outside of the app.
      * Excludes intra-app activity transitions.
      * @hide
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index c013fcd..1dfc7d4 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -220,6 +220,11 @@
      */
     public static final int REASON_SUB_DEFAULT_APP_UPDATE = 0x0001;
     /**
+     * The app was restored.
+     * @hide
+     */
+    public static final int REASON_SUB_DEFAULT_APP_RESTORED = 0x0002;
+    /**
      * The app was interacted with in some way by the system.
      * @hide
      */
@@ -1209,6 +1214,9 @@
                     case REASON_SUB_DEFAULT_APP_UPDATE:
                         sb.append("-au");
                         break;
+                    case REASON_SUB_DEFAULT_APP_RESTORED:
+                        sb.append("-ar");
+                        break;
                 }
                 break;
             case REASON_MAIN_FORCED_BY_SYSTEM:
diff --git a/core/java/android/companion/AssociationInfo.java b/core/java/android/companion/AssociationInfo.java
index f7f0235..93748f8 100644
--- a/core/java/android/companion/AssociationInfo.java
+++ b/core/java/android/companion/AssociationInfo.java
@@ -55,6 +55,14 @@
 
     private final boolean mSelfManaged;
     private final boolean mNotifyOnDeviceNearby;
+
+    /**
+     * Indicates that the association has been revoked (removed), but we keep the association
+     * record for final clean up (e.g. removing the app from the list of the role holders).
+     *
+     * @see CompanionDeviceManager#disassociate(int)
+     */
+    private final boolean mRevoked;
     private final long mTimeApprovedMs;
     /**
      * A long value indicates the last time connected reported by selfManaged devices
@@ -71,7 +79,7 @@
     public AssociationInfo(int id, @UserIdInt int userId, @NonNull String packageName,
             @Nullable MacAddress macAddress, @Nullable CharSequence displayName,
             @Nullable String deviceProfile, boolean selfManaged, boolean notifyOnDeviceNearby,
-            long timeApprovedMs, long lastTimeConnectedMs) {
+            boolean revoked, long timeApprovedMs, long lastTimeConnectedMs) {
         if (id <= 0) {
             throw new IllegalArgumentException("Association ID should be greater than 0");
         }
@@ -91,6 +99,7 @@
 
         mSelfManaged = selfManaged;
         mNotifyOnDeviceNearby = notifyOnDeviceNearby;
+        mRevoked = revoked;
         mTimeApprovedMs = timeApprovedMs;
         mLastTimeConnectedMs = lastTimeConnectedMs;
     }
@@ -176,6 +185,14 @@
     }
 
     /**
+     * @return if the association has been revoked (removed).
+     * @hide
+     */
+    public boolean isRevoked() {
+        return mRevoked;
+    }
+
+    /**
      * @return the last time self reported disconnected for selfManaged only.
      * @hide
      */
@@ -244,6 +261,7 @@
                 + ", mDeviceProfile='" + mDeviceProfile + '\''
                 + ", mSelfManaged=" + mSelfManaged
                 + ", mNotifyOnDeviceNearby=" + mNotifyOnDeviceNearby
+                + ", mRevoked=" + mRevoked
                 + ", mTimeApprovedMs=" + new Date(mTimeApprovedMs)
                 + ", mLastTimeConnectedMs=" + (
                     mLastTimeConnectedMs == Long.MAX_VALUE
@@ -260,6 +278,7 @@
                 && mUserId == that.mUserId
                 && mSelfManaged == that.mSelfManaged
                 && mNotifyOnDeviceNearby == that.mNotifyOnDeviceNearby
+                && mRevoked == that.mRevoked
                 && mTimeApprovedMs == that.mTimeApprovedMs
                 && mLastTimeConnectedMs == that.mLastTimeConnectedMs
                 && Objects.equals(mPackageName, that.mPackageName)
@@ -271,7 +290,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(mId, mUserId, mPackageName, mDeviceMacAddress, mDisplayName,
-                mDeviceProfile, mSelfManaged, mNotifyOnDeviceNearby, mTimeApprovedMs,
+                mDeviceProfile, mSelfManaged, mNotifyOnDeviceNearby, mRevoked, mTimeApprovedMs,
                 mLastTimeConnectedMs);
     }
 
@@ -293,6 +312,7 @@
 
         dest.writeBoolean(mSelfManaged);
         dest.writeBoolean(mNotifyOnDeviceNearby);
+        dest.writeBoolean(mRevoked);
         dest.writeLong(mTimeApprovedMs);
         dest.writeLong(mLastTimeConnectedMs);
     }
@@ -309,6 +329,7 @@
 
         mSelfManaged = in.readBoolean();
         mNotifyOnDeviceNearby = in.readBoolean();
+        mRevoked = in.readBoolean();
         mTimeApprovedMs = in.readLong();
         mLastTimeConnectedMs = in.readLong();
     }
@@ -352,11 +373,13 @@
         @NonNull
         private final AssociationInfo mOriginalInfo;
         private boolean mNotifyOnDeviceNearby;
+        private boolean mRevoked;
         private long mLastTimeConnectedMs;
 
         private Builder(@NonNull AssociationInfo info) {
             mOriginalInfo = info;
             mNotifyOnDeviceNearby = info.mNotifyOnDeviceNearby;
+            mRevoked = info.mRevoked;
             mLastTimeConnectedMs = info.mLastTimeConnectedMs;
         }
 
@@ -388,6 +411,17 @@
         }
 
         /**
+         * Should only be used by the CompanionDeviceManagerService.
+         * @hide
+         */
+        @Override
+        @NonNull
+        public Builder setRevoked(boolean revoked) {
+            mRevoked = revoked;
+            return this;
+        }
+
+        /**
          * @hide
          */
         @NonNull
@@ -401,6 +435,7 @@
                     mOriginalInfo.mDeviceProfile,
                     mOriginalInfo.mSelfManaged,
                     mNotifyOnDeviceNearby,
+                    mRevoked,
                     mOriginalInfo.mTimeApprovedMs,
                     mLastTimeConnectedMs
             );
@@ -433,5 +468,12 @@
          */
         @NonNull
         Builder setLastTimeConnected(long lastTimeConnectedMs);
+
+        /**
+         * Should only be used by the CompanionDeviceManagerService.
+         * @hide
+         */
+        @NonNull
+        Builder setRevoked(boolean revoked);
     }
 }
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 0673b3a..a3d595ef 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -106,6 +106,24 @@
     public @interface LaunchMode {
     }
 
+    /** @hide */
+    public static String launchModeToString(@LaunchMode int launchMode) {
+        switch(launchMode) {
+            case LAUNCH_MULTIPLE:
+                return "LAUNCH_MULTIPLE";
+            case LAUNCH_SINGLE_TOP:
+                return "LAUNCH_SINGLE_TOP";
+            case LAUNCH_SINGLE_TASK:
+                return "LAUNCH_SINGLE_TASK";
+            case LAUNCH_SINGLE_INSTANCE:
+                return "LAUNCH_SINGLE_INSTANCE";
+            case LAUNCH_SINGLE_INSTANCE_PER_TASK:
+                return "LAUNCH_SINGLE_INSTANCE_PER_TASK";
+            default:
+                return "unknown=" + launchMode;
+        }
+    }
+
     /**
      * The launch mode style requested by the activity.  From the
      * {@link android.R.attr#launchMode} attribute.
@@ -1585,7 +1603,7 @@
                     + " persistableMode=" + persistableModeToString());
         }
         if (launchMode != 0 || flags != 0 || privateFlags != 0 || theme != 0) {
-            pw.println(prefix + "launchMode=" + launchMode
+            pw.println(prefix + "launchMode=" + launchModeToString(launchMode)
                     + " flags=0x" + Integer.toHexString(flags)
                     + " privateFlags=0x" + Integer.toHexString(privateFlags)
                     + " theme=0x" + Integer.toHexString(theme));
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index d6e13ac..9baa6ba 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -143,6 +143,22 @@
     public static final int FLAG_PROFILE = 0x00001000;
 
     /**
+     * Indicates that this user is created in ephemeral mode via
+     * {@link IUserManager} create user.
+     *
+     * When a user is created with {@link #FLAG_EPHEMERAL}, {@link #FLAG_EPHEMERAL_ON_CREATE}
+     * is set internally within the user manager.
+     *
+     * When {@link #FLAG_EPHEMERAL_ON_CREATE} is set {@link IUserManager.setUserEphemeral}
+     * has no effect because a user that was created ephemeral can never be made non-ephemeral.
+     *
+     * {@link #FLAG_EPHEMERAL_ON_CREATE} should NOT be set by client's of user manager
+     *
+     * @hide
+     */
+    public static final int FLAG_EPHEMERAL_ON_CREATE = 0x00002000;
+
+    /**
      * @hide
      */
     @IntDef(flag = true, prefix = "FLAG_", value = {
@@ -158,7 +174,8 @@
             FLAG_DEMO,
             FLAG_FULL,
             FLAG_SYSTEM,
-            FLAG_PROFILE
+            FLAG_PROFILE,
+            FLAG_EPHEMERAL_ON_CREATE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface UserInfoFlag {
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 439c639..608e34b 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -420,7 +420,10 @@
          * Translate a Rect in screen coordinates into the app window's coordinates.
          */
         @UnsupportedAppUsage
-        public void translateRectInScreenToAppWindow(Rect rect) {
+        public void translateRectInScreenToAppWindow(@Nullable Rect rect) {
+            if (rect == null) {
+                return;
+            }
             rect.scale(applicationInvertedScale);
         }
 
diff --git a/core/java/android/hardware/display/AmbientDisplayConfiguration.java b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
index 7d8f2ff..8c71b36 100644
--- a/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+++ b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
@@ -89,7 +89,8 @@
 
     /** @hide */
     public boolean pulseOnNotificationAvailable() {
-        return ambientDisplayAvailable();
+        return mContext.getResources().getBoolean(R.bool.config_pulseOnNotificationsAvailable)
+                && ambientDisplayAvailable();
     }
 
     /** @hide */
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 69c6ba9..8bc11cb 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -559,21 +559,18 @@
      * @see #DISPLAY_CATEGORY_PRESENTATION
      */
     public Display[] getDisplays(String category) {
-        boolean includeDisabledDisplays = (category != null
-                && category.equals(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED));
-        final int[] displayIds = mGlobal.getDisplayIds(includeDisabledDisplays);
+        final int[] displayIds = mGlobal.getDisplayIds();
         synchronized (mLock) {
             try {
-                if (category != null && category.equals(DISPLAY_CATEGORY_PRESENTATION)) {
+                if (category == null
+                        || DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED.equals(category)) {
+                    addAllDisplaysLocked(mTempDisplays, displayIds);
+                } else if (category.equals(DISPLAY_CATEGORY_PRESENTATION)) {
                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI);
                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_EXTERNAL);
                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY);
                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_VIRTUAL);
                     addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_INTERNAL);
-                } else if ((category == null
-                        || DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED.equals(category))) {
-                    // All displays requested.
-                    addAllDisplaysLocked(mTempDisplays, displayIds);
                 }
                 return mTempDisplays.toArray(new Display[mTempDisplays.size()]);
             } finally {
@@ -1451,5 +1448,15 @@
          * @hide
          */
         String KEY_HIGH_REFRESH_RATE_BLACKLIST = "high_refresh_rate_blacklist";
+
+        /**
+         * Key for the brightness throttling data as a String formatted:
+         * <displayId>,<no of throttling levels>,[<severity as string>,<brightness cap>]
+         * Where the latter part is repeated for each throttling level, and the entirety is repeated
+         * for each display, separated by a semicolon.
+         * For example:
+         * 123,1,critical,0.8;456,2,moderate,0.9,critical,0.7
+         */
+        String KEY_BRIGHTNESS_THROTTLING_DATA = "brightness_throttling_data";
     }
 }
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index da3a580..74356dd 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -206,16 +206,6 @@
      */
     @UnsupportedAppUsage
     public int[] getDisplayIds() {
-        return getDisplayIds(/* includeDisabledDisplays= */ false);
-    }
-
-    /**
-     * Gets all valid logical display ids and invalid ones if specified.
-     *
-     * @return An array containing all display ids.
-     */
-    @UnsupportedAppUsage
-    public int[] getDisplayIds(boolean includeDisabledDisplays) {
         try {
             synchronized (mLock) {
                 if (USE_CACHE) {
@@ -224,8 +214,7 @@
                     }
                 }
 
-                int[] displayIds =
-                        mDm.getDisplayIds(includeDisabledDisplays);
+                int[] displayIds = mDm.getDisplayIds();
                 if (USE_CACHE) {
                     mDisplayIdCache = displayIds;
                 }
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index a4115d1..ca3e580 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -36,7 +36,7 @@
 interface IDisplayManager {
     @UnsupportedAppUsage
     DisplayInfo getDisplayInfo(int displayId);
-    int[] getDisplayIds(boolean includeDisabled);
+    int[] getDisplayIds();
 
     boolean isUidPresentOnDisplay(int uid, int displayId);
 
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index e1ccc4f..170df71 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -46,6 +46,5 @@
     int getMaxTransceiveLength(int technology);
     boolean getExtendedLengthApdusSupported();
 
-    void setTagUpToDate(long cookie);
     boolean isTagUpToDate(long cookie);
 }
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 731d1ba..500038f 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -34,7 +34,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
-import android.os.SystemClock;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -119,17 +118,17 @@
     final String[] mTechStringList;
     final Bundle[] mTechExtras;
     final int mServiceHandle;  // for use by NFC service, 0 indicates a mock
+    final long mCookie;        // for accessibility checking
     final INfcTag mTagService; // interface to NFC service, will be null if mock tag
 
     int mConnectedTechnology;
-    long mCookie;
 
     /**
      * Hidden constructor to be used by NFC service and internal classes.
      * @hide
      */
     public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle,
-            INfcTag tagService) {
+            long cookie, INfcTag tagService) {
         if (techList == null) {
             throw new IllegalArgumentException("rawTargets cannot be null");
         }
@@ -139,20 +138,13 @@
         // Ensure mTechExtras is as long as mTechList
         mTechExtras = Arrays.copyOf(techListExtras, techList.length);
         mServiceHandle = serviceHandle;
+        mCookie = cookie;
         mTagService = tagService;
-
         mConnectedTechnology = -1;
-        mCookie = SystemClock.elapsedRealtime();
 
         if (tagService == null) {
             return;
         }
-
-        try {
-            tagService.setTagUpToDate(mCookie);
-        } catch (RemoteException e) {
-            throw e.rethrowAsRuntimeException();
-        }
     }
 
     /**
@@ -165,9 +157,10 @@
      * @return freshly constructed tag
      * @hide
      */
-    public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras) {
+    public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras,
+            long cookie) {
         // set serviceHandle to 0 and tagService to null to indicate mock tag
-        return new Tag(id, techList, techListExtras, 0, null);
+        return new Tag(id, techList, techListExtras, 0, cookie, null);
     }
 
     private String[] generateTechStringList(int[] techList) {
@@ -445,6 +438,7 @@
         dest.writeIntArray(mTechList);
         dest.writeTypedArray(mTechExtras, 0);
         dest.writeInt(mServiceHandle);
+        dest.writeLong(mCookie);
         dest.writeInt(isMock);
         if (isMock == 0) {
             dest.writeStrongBinder(mTagService.asBinder());
@@ -463,6 +457,7 @@
             in.readIntArray(techList);
             Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR);
             int serviceHandle = in.readInt();
+            long cookie = in.readLong();
             int isMock = in.readInt();
             if (isMock == 0) {
                 tagService = INfcTag.Stub.asInterface(in.readStrongBinder());
@@ -471,7 +466,7 @@
                 tagService = null;
             }
 
-            return new Tag(id, techList, techExtras, serviceHandle, tagService);
+            return new Tag(id, techList, techExtras, serviceHandle, cookie, tagService);
         }
 
         @Override
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 3cde031..e5de3e1 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -131,4 +131,5 @@
     String getUserName();
     long getUserStartRealtime();
     long getUserUnlockRealtime();
+    boolean setUserEphemeral(int userId, boolean enableEphemeral);
 }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 0ffdfc6..d656604 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2001,13 +2001,22 @@
      * @return Whether guest user is always ephemeral
      * @hide
      */
-    @TestApi
-    public static boolean isGuestUserEphemeral() {
+    public static boolean isGuestUserAlwaysEphemeral() {
         return Resources.getSystem()
                 .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
     }
 
     /**
+     * @return true, when we want to enable user manager API and UX to allow
+     *           guest user ephemeral state change based on user input
+     * @hide
+     */
+    public static boolean isGuestUserAllowEphemeralStateChange() {
+        return Resources.getSystem()
+                .getBoolean(com.android.internal.R.bool.config_guestUserAllowEphemeralStateChange);
+    }
+
+    /**
      * Checks whether the device is running in a headless system user mode.
      *
      * <p>Headless system user mode means the {@link #isSystemUser() system user} runs system
@@ -3431,6 +3440,20 @@
             if (guest != null) {
                 Settings.Secure.putStringForUser(context.getContentResolver(),
                         Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
+
+                if (UserManager.isGuestUserAllowEphemeralStateChange()) {
+                    // Mark guest as (changeably) ephemeral if REMOVE_GUEST_ON_EXIT is 1
+                    // This is done so that a user via a UI controller can choose to
+                    // make a guest as ephemeral or not.
+                    // Settings.Global.REMOVE_GUEST_ON_EXIT holds the choice on what the guest state
+                    // should be, with default being ephemeral.
+                    boolean resetGuestOnExit = Settings.Global.getInt(context.getContentResolver(),
+                                                 Settings.Global.REMOVE_GUEST_ON_EXIT, 1) == 1;
+
+                    if (resetGuestOnExit && !guest.isEphemeral()) {
+                        setUserEphemeral(guest.id, true);
+                    }
+                }
             }
             return guest;
         } catch (ServiceSpecificException e) {
@@ -4948,6 +4971,31 @@
     }
 
     /**
+     * Set the user as ephemeral or non-ephemeral.
+     *
+     * If the user was initially created as ephemeral then this
+     * method has no effect and false is returned.
+     *
+     * @param userId the user's integer id
+     * @param enableEphemeral true: change user state to ephemeral,
+     *                        false: change user state to non-ephemeral
+     * @return true: user now has the desired ephemeral state,
+     *         false: desired user ephemeral state could not be set
+     *
+     * @hide
+     */
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.CREATE_USERS})
+    public boolean setUserEphemeral(@UserIdInt int userId, boolean enableEphemeral) {
+        try {
+            return mService.setUserEphemeral(userId, enableEphemeral);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Updates the context user's name.
      *
      * @param name the new name for the user
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 805fdc4..7964f7c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9141,6 +9141,57 @@
         public static final String SCREENSAVER_ENABLED_COMPLICATIONS =
                 "screensaver_enabled_complications";
 
+
+        /**
+         * Default, indicates that the user has not yet started the dock setup flow.
+         *
+         * @hide
+         */
+        public static final int DOCK_SETUP_NOT_STARTED = 0;
+
+        /**
+         * Indicates that the user has started but not yet completed dock setup.
+         * One of the possible states for {@link #DOCK_SETUP_STATE}.
+         *
+         * @hide
+         */
+        public static final int DOCK_SETUP_STARTED = 1;
+
+        /**
+         * Indicates that the user has snoozed dock setup and will complete it later.
+         * One of the possible states for {@link #DOCK_SETUP_STATE}.
+         *
+         * @hide
+         */
+        public static final int DOCK_SETUP_PAUSED = 2;
+
+        /**
+         * Indicates that the user has completed dock setup.
+         * One of the possible states for {@link #DOCK_SETUP_STATE}.
+         *
+         * @hide
+         */
+        public static final int DOCK_SETUP_COMPLETED = 10;
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({
+                DOCK_SETUP_NOT_STARTED,
+                DOCK_SETUP_STARTED,
+                DOCK_SETUP_PAUSED,
+                DOCK_SETUP_COMPLETED
+        })
+        public @interface DockSetupState {
+        }
+
+        /**
+         * Defines the user's current state of dock setup.
+         * The possible states are defined in {@link DockSetupState}.
+         *
+         * @hide
+         */
+        public static final String DOCK_SETUP_STATE = "dock_setup_state";
+
         /**
          * The default NFC payment component
          * @hide
@@ -10820,6 +10871,15 @@
                 "launcher_taskbar_education_showing";
 
         /**
+         * Whether or not adaptive charging feature is enabled by user.
+         * Type: int (0 for false, 1 for true)
+         * Default: 1
+         *
+         * @hide
+         */
+        public static final String ADAPTIVE_CHARGING_ENABLED = "adaptive_charging_enabled";
+
+        /**
          * These entries are considered common between the personal and the managed profile,
          * since the managed profile doesn't get to change them.
          */
@@ -10945,6 +11005,14 @@
         public static final String ADD_USERS_WHEN_LOCKED = "add_users_when_locked";
 
         /**
+         * Whether guest user should be removed on exit from guest mode.
+         * <p>
+         * Type: int
+         * @hide
+         */
+        public static final String REMOVE_GUEST_ON_EXIT = "remove_guest_on_exit";
+
+        /**
          * Whether applying ramping ringer on incoming phone call ringtone.
          * <p>1 = apply ramping ringer
          * <p>0 = do not apply ramping ringer
diff --git a/core/java/android/service/dreams/DreamActivity.java b/core/java/android/service/dreams/DreamActivity.java
index bf64d06..f6a7c8e 100644
--- a/core/java/android/service/dreams/DreamActivity.java
+++ b/core/java/android/service/dreams/DreamActivity.java
@@ -21,8 +21,6 @@
 import android.os.Bundle;
 import android.text.TextUtils;
 
-import com.android.internal.R;
-
 /**
  * The Activity used by the {@link DreamService} to draw screensaver content
  * on the screen. This activity runs in dream application's process, but is started by a
@@ -66,17 +64,4 @@
             callback.onActivityCreated(this);
         }
     }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        overridePendingTransition(R.anim.dream_activity_open_enter,
-                                  R.anim.dream_activity_open_exit);
-    }
-
-    @Override
-    public void finishAndRemoveTask() {
-        super.finishAndRemoveTask();
-        overridePendingTransition(0, R.anim.dream_activity_close_exit);
-    }
 }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 1e22856..1df7dbc 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -24,7 +24,6 @@
 import static android.graphics.Matrix.MSKEW_Y;
 import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
 import static android.view.View.SYSTEM_UI_FLAG_VISIBLE;
-import static android.view.ViewRootImpl.LOCAL_LAYOUT;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
 import android.animation.AnimationHandler;
@@ -41,7 +40,6 @@
 import android.app.WallpaperColors;
 import android.app.WallpaperInfo;
 import android.app.WallpaperManager;
-import android.app.WindowConfiguration;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
@@ -260,8 +258,6 @@
         private final Point mLastSurfaceSize = new Point();
         private final Matrix mTmpMatrix = new Matrix();
         private final float[] mTmpValues = new float[9];
-        private final WindowLayout mWindowLayout = new WindowLayout();
-        private final Rect mTempRect = new Rect();
 
         final WindowManager.LayoutParams mLayout
                 = new WindowManager.LayoutParams();
@@ -1100,8 +1096,7 @@
                             | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 
                     final Configuration config = mMergedConfiguration.getMergedConfiguration();
-                    final WindowConfiguration winConfig = config.windowConfiguration;
-                    final Rect maxBounds = winConfig.getMaxBounds();
+                    final Rect maxBounds = config.windowConfiguration.getMaxBounds();
                     if (myWidth == ViewGroup.LayoutParams.MATCH_PARENT
                             && myHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
                         mLayout.width = myWidth;
@@ -1139,7 +1134,7 @@
 
                         if (mSession.addToDisplay(mWindow, mLayout, View.VISIBLE,
                                 mDisplay.getDisplayId(), mRequestedVisibilities, inputChannel,
-                                mInsetsState, mTempControls) < 0) {
+                                mInsetsState, mTempControls, new Rect()) < 0) {
                             Log.w(TAG, "Failed to add window while updating wallpaper surface.");
                             return;
                         }
@@ -1158,29 +1153,9 @@
                     } else {
                         mLayout.surfaceInsets.set(0, 0, 0, 0);
                     }
-
-                    int relayoutResult = 0;
-                    if (LOCAL_LAYOUT) {
-                        if (!mSurfaceControl.isValid()) {
-                            relayoutResult = mSession.updateVisibility(mWindow, mLayout,
-                                    View.VISIBLE, mMergedConfiguration, mSurfaceControl,
-                                    mInsetsState, mTempControls);
-                        }
-
-                        final Rect displayCutoutSafe = mTempRect;
-                        mInsetsState.getDisplayCutoutSafe(displayCutoutSafe);
-                        mWindowLayout.computeFrames(mLayout, mInsetsState, displayCutoutSafe,
-                                winConfig.getBounds(), winConfig.getWindowingMode(), mWidth,
-                                mHeight, mRequestedVisibilities, null /* attachedWindowFrame */,
-                                1f /* compatScale */, mWinFrames);
-
-                        mSession.updateLayout(mWindow, mLayout, 0 /* flags */, mWinFrames, mWidth,
-                                mHeight);
-                    } else {
-                        relayoutResult = mSession.relayout(mWindow, mLayout, mWidth, mHeight,
-                                View.VISIBLE, 0, mWinFrames, mMergedConfiguration,
-                                mSurfaceControl, mInsetsState, mTempControls, mSyncSeqIdBundle);
-                    }
+                    final int relayoutResult = mSession.relayout(mWindow, mLayout, mWidth, mHeight,
+                            View.VISIBLE, 0, mWinFrames, mMergedConfiguration, mSurfaceControl,
+                            mInsetsState, mTempControls, mSyncSeqIdBundle);
 
                     final int transformHint = SurfaceControl.rotationToBufferTransform(
                             (mDisplayInstallOrientation + mDisplay.getRotation()) % 4);
@@ -1229,7 +1204,7 @@
                             null /* ignoringVisibilityState */, config.isScreenRound(),
                             false /* alwaysConsumeSystemBars */, mLayout.softInputMode,
                             mLayout.flags, SYSTEM_UI_FLAG_VISIBLE, mLayout.type,
-                            winConfig.getWindowingMode(), null /* typeSideMap */);
+                            config.windowConfiguration.getWindowingMode(), null /* typeSideMap */);
 
                     if (!fixedSize) {
                         final Rect padding = mIWallpaperEngine.mDisplayPadding;
@@ -1539,8 +1514,9 @@
                         // may have been destroyed so now we need to make
                         // sure it is re-created.
                         doOffsetsChanged(false);
-                        // force relayout to get new surface
-                        updateSurface(true, false, false);
+                        // It will check mSurfaceCreated so no need to force relayout.
+                        updateSurface(false /* forceRelayout */, false /* forceReport */,
+                                false /* redrawNeeded */);
                     }
                     onVisibilityChanged(visible);
                     if (mReportedVisible && mFrozenRequested) {
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 24ded93..6049199 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -83,6 +83,11 @@
     public static final String SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE =
             "settings_hide_second_layer_page_navigate_up_button_in_two_pane";
 
+    /** Flag to enable/disable guest mode UX changes as mentioned in b/214031645
+     *  @hide
+     */
+    public static  final String SETTINGS_GUEST_MODE_UX_CHANGES = "settings_guest_mode_ux_changes";
+
     private static final Map<String, String> DEFAULT_FLAGS;
 
     static {
@@ -110,6 +115,7 @@
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true");
         DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "true");
         DEFAULT_FLAGS.put(SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE, "true");
+        DEFAULT_FLAGS.put(SETTINGS_GUEST_MODE_UX_CHANGES, "true");
     }
 
     private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/view/IDisplayWindowRotationCallback.aidl b/core/java/android/view/IDisplayChangeWindowCallback.aidl
similarity index 77%
rename from core/java/android/view/IDisplayWindowRotationCallback.aidl
rename to core/java/android/view/IDisplayChangeWindowCallback.aidl
index 1ffe2dd..00a5b7b 100644
--- a/core/java/android/view/IDisplayWindowRotationCallback.aidl
+++ b/core/java/android/view/IDisplayChangeWindowCallback.aidl
@@ -17,13 +17,15 @@
 package android.view;
 
 import android.window.WindowContainerTransaction;
+import android.window.DisplayAreaInfo;
 
 /**
- * Interface to be invoked by the controller when it has finished preparing for a display rotation.
+ * Interface to be invoked by the controller when it has finished preparing for a display
+ * size change.
  *
- * @see IDisplayWindowRotationController
+ * @see IDisplayChangeWindowController
  * @hide
  */
-interface IDisplayWindowRotationCallback {
-    void continueRotateDisplay(int targetRotation, in WindowContainerTransaction t);
+interface IDisplayChangeWindowCallback {
+    void continueDisplayChange(in WindowContainerTransaction t);
 }
diff --git a/core/java/android/view/IDisplayWindowRotationController.aidl b/core/java/android/view/IDisplayChangeWindowController.aidl
similarity index 66%
rename from core/java/android/view/IDisplayWindowRotationController.aidl
rename to core/java/android/view/IDisplayChangeWindowController.aidl
index c1c7464..8c0bb6a 100644
--- a/core/java/android/view/IDisplayWindowRotationController.aidl
+++ b/core/java/android/view/IDisplayChangeWindowController.aidl
@@ -16,11 +16,12 @@
 
 package android.view;
 
-import android.view.IDisplayWindowRotationCallback;
+import android.view.IDisplayChangeWindowCallback;
+import android.window.DisplayAreaInfo;
 
 /**
- * Singular controller of a "remote" display rotation. When a display rotation is started, WM
- * freezes the screen. It will then call into this controller and wait for a response via the
+ * Singular controller of a "remote" display change. When a display rotation or change is started,
+ * WM freezes the screen. It will then call into this controller and wait for a response via the
  * callback.
  *
  * This needs to provide configuration changes because those changes need to be applied in sync
@@ -36,17 +37,18 @@
  *
  * @hide
  */
-oneway interface IDisplayWindowRotationController {
+oneway interface IDisplayChangeWindowController {
 
     /**
-     * Called when WM needs to know how to update tasks in response to a display rotation.
-     * If this isn't called, a timeout will continue the rotation in WM.
+     * Called when WM needs to know how to update tasks in response to a display change.
+     * If this isn't called, a timeout will continue the change in WM.
      *
-     * @param displayId the display that is rotating.
-     * @param fromRotation the rotation the display is rotating from.
-     * @param toRotation the rotation the display is rotating to.
+     * @param fromRotation the old rotation
+     * @param newRotation the new rotation
+     * @param newDisplayAreaInfo the new display area info after the change
      * @param callback A callback to be called when this has calculated updated configs.
      */
-    void onRotateDisplay(int displayId, int fromRotation, int toRotation,
-            in IDisplayWindowRotationCallback callback);
+    void onDisplayChange(int displayId, int fromRotation, int toRotation,
+            in DisplayAreaInfo newDisplayAreaInfo, in IDisplayChangeWindowCallback callback);
+
 }
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index fb562d8..acdff4f 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -39,7 +39,7 @@
 import android.view.IDisplayWindowInsetsController;
 import android.view.IDisplayWindowListener;
 import android.view.IDisplayFoldListener;
-import android.view.IDisplayWindowRotationController;
+import android.view.IDisplayChangeWindowController;
 import android.view.IOnKeyguardExitResult;
 import android.view.IPinnedTaskListener;
 import android.view.IScrollCaptureResponseListener;
@@ -145,7 +145,7 @@
      * controller is called after the display has "frozen" for a rotation and display rotation will
      * only continue once the controller has finished calculating associated configurations.
      */
-    void setDisplayWindowRotationController(IDisplayWindowRotationController controller);
+    void setDisplayChangeWindowController(IDisplayChangeWindowController controller);
 
     /**
      * Adds a root container that a client shell can populate with its own windows (usually via
@@ -250,18 +250,6 @@
      */
     void refreshScreenCaptureDisabled();
 
-    // These can only be called with the SET_ORIENTATION permission.
-    /**
-     * Update the current screen rotation based on the current state of
-     * the world.
-     * @param alwaysSendConfiguration Flag to force a new configuration to
-     * be evaluated.  This can be used when there are other parameters in
-     * configuration that are changing.
-     * @param forceRelayout If true, the window manager will always do a relayout
-     * of its windows even if the rotation hasn't changed.
-     */
-    void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout);
-
     /**
      * Retrieve the current orientation of the primary screen.
      * @return Constant as per {@link android.view.Surface.Rotation}.
@@ -442,11 +430,6 @@
     boolean isSafeModeEnabled();
 
     /**
-     * Enables the screen if all conditions are met.
-     */
-    void enableScreenIfNeeded();
-
-    /**
      * Clears the frame statistics for a given window.
      *
      * @param token The window token.
@@ -560,6 +543,21 @@
     boolean isWindowTraceEnabled();
 
     /**
+     * Starts a transition trace.
+     */
+    void startTransitionTrace();
+
+    /**
+     * Stops a transition trace.
+     */
+    void stopTransitionTrace();
+
+    /**
+     * Returns true if transition trace is enabled.
+     */
+    boolean isTransitionTraceEnabled();
+
+    /**
      * Gets the windowing mode of the display.
      *
      * @param displayId The id of the display.
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 649accd..ef57b1d 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -50,13 +50,15 @@
     int addToDisplay(IWindow window, in WindowManager.LayoutParams attrs,
             in int viewVisibility, in int layerStackId, in InsetsVisibilities requestedVisibilities,
             out InputChannel outInputChannel, out InsetsState insetsState,
-            out InsetsSourceControl[] activeControls);
+            out InsetsSourceControl[] activeControls, out Rect attachedFrame);
     int addToDisplayAsUser(IWindow window, in WindowManager.LayoutParams attrs,
             in int viewVisibility, in int layerStackId, in int userId,
             in InsetsVisibilities requestedVisibilities, out InputChannel outInputChannel,
-            out InsetsState insetsState, out InsetsSourceControl[] activeControls);
+            out InsetsState insetsState, out InsetsSourceControl[] activeControls,
+            out Rect attachedFrame);
     int addToDisplayWithoutInputChannel(IWindow window, in WindowManager.LayoutParams attrs,
-            in int viewVisibility, in int layerStackId, out InsetsState insetsState);
+            in int viewVisibility, in int layerStackId, out InsetsState insetsState,
+            out Rect attachedFrame);
     @UnsupportedAppUsage
     void remove(IWindow window);
 
@@ -107,41 +109,6 @@
             out InsetsState insetsState, out InsetsSourceControl[] activeControls,
             out Bundle bundle);
 
-    /**
-     * Changes the view visibility and the attributes of a window. This should only be called when
-     * the visibility of the root view is changed. This returns a valid surface if the root view is
-     * visible. This also returns the latest information for the caller to compute its window frame.
-     *
-     * @param window The window being updated.
-     * @param attrs If non-null, new attributes to apply to the window.
-     * @param viewVisibility Window root view's visibility.
-     * @param outMergedConfiguration New config container that holds global, override and merged
-     * config for window, if it is now becoming visible and the merged configuration has changed
-     * since it was last displayed.
-     * @param outSurfaceControl Object in which is placed the new display surface.
-     * @param outInsetsState The current insets state in the system.
-     * @param outActiveControls The insets source controls for the caller to override the insets
-     * state in the system.
-     *
-     * @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_FIRST_TIME}.
-     */
-    int updateVisibility(IWindow window, in WindowManager.LayoutParams attrs, int viewVisibility,
-            out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl,
-            out InsetsState outInsetsState, out InsetsSourceControl[] outActiveControls);
-
-    /**
-     * Reports the layout results and the attributes of a window to the server.
-     *
-     * @param window The window being reported.
-     * @param attrs If non-null, new attributes to apply to the window.
-     * @param flags Request flags: {@link WindowManagerGlobal#RELAYOUT_INSETS_PENDING}.
-     * @param clientFrames the window frames computed by the client.
-     * @param requestedWidth The width the window wants to be.
-     * @param requestedHeight The height the window wants to be.
-     */
-    oneway void updateLayout(IWindow window, in WindowManager.LayoutParams attrs, int flags,
-            in ClientWindowFrames clientFrames, int requestedWidth, int requestedHeight);
-
     /*
      * Notify the window manager that an application is relaunching and
      * windows should be prepared for replacement.
@@ -384,4 +351,9 @@
      * Clears a touchable region set by {@link #setInsets}.
      */
     void clearTouchableRegion(IWindow window);
+
+    /**
+     * Returns whether this window needs to cancel draw and retry later.
+     */
+    boolean cancelDraw(IWindow window);
 }
diff --git a/core/java/android/view/InsetsFrameProvider.java b/core/java/android/view/InsetsFrameProvider.java
new file mode 100644
index 0000000..9e66f54
--- /dev/null
+++ b/core/java/android/view/InsetsFrameProvider.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.graphics.Insets;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Insets provided by a window.
+ *
+ * The insets frame will by default as the window frame size. If the providers are set, the
+ * calculation result based on the source size will be used as the insets frame.
+ * @hide
+ */
+public class InsetsFrameProvider implements Parcelable {
+
+    /**
+     * If specified in source field, the insets calculation will be based on the display frame.
+     */
+    public static final int SOURCE_DISPLAY = 0;
+
+    /**
+     * If specified in source field, the insets calculation will be based on the window bounds. The
+     * container bounds can sometimes be different from the window frame. For example, when a task
+     * bar needs the entire screen to be prepared to showing the apps, the window container can take
+     * the entire display, or display area, but the window frame, as a result of the layout, will
+     * stay small until it actually taking the entire display to draw their view.
+     */
+    public static final int SOURCE_CONTAINER_BOUNDS = 1;
+
+    /**
+     * If specified in source field, the insets calculation will be based on the window frame. This
+     * is also the default value of the source.
+     */
+    public static final int SOURCE_FRAME = 2;
+
+    private static final int HAS_INSETS_SIZE = 1;
+    private static final int HAS_IME_INSETS_SIZE = 2;
+
+    /**
+     * The type of insets to provide.
+     */
+    public @InsetsState.InternalInsetsType int type;
+
+    /**
+     * The source of frame. By default, all adjustment will be based on the window frame, it
+     * can be set to window bounds or display bounds instead.
+     */
+    public int source = SOURCE_FRAME;
+
+    /**
+     * The provided insets size based on the source frame. The result will be used as the insets
+     * size to windows other than IME. Only one side should be set.
+     *
+     * For example, when the given source frame is (0, 0) - (100, 200), and the insetsSize is null,
+     * the source frame will be directly used as the final insets frame. If the insetsSize is set to
+     * (0, 0, 0, 50) instead, the insets frame will be a frame starting from the bottom side of the
+     * source frame with height of 50, i.e., (0, 150) - (100, 200).
+     */
+    public Insets insetsSize = null;
+
+    /**
+     * The provided frame based on the source frame. The result will be used as the insets
+     * size to IME window. Only one side should be set.
+     */
+    public Insets imeInsetsSize = null;
+
+    public InsetsFrameProvider(int type) {
+        this(type, SOURCE_FRAME, null, null);
+    }
+
+    public InsetsFrameProvider(int type, Insets insetsSize) {
+        this(type, SOURCE_FRAME, insetsSize, insetsSize);
+    }
+
+    public InsetsFrameProvider(int type, Insets insetsSize, Insets imeInsetsSize) {
+        this(type, SOURCE_FRAME, insetsSize, imeInsetsSize);
+    }
+
+    public InsetsFrameProvider(int type, int source, Insets insetsSize,
+            Insets imeInsetsSize) {
+        this.type = type;
+        this.source = source;
+        this.insetsSize = insetsSize;
+        this.imeInsetsSize = imeInsetsSize;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(32);
+        sb.append("InsetsFrameProvider: {");
+        sb.append("type=").append(InsetsState.typeToString(type));
+        sb.append(", source=");
+        switch (source) {
+            case SOURCE_DISPLAY:
+                sb.append("SOURCE_DISPLAY");
+                break;
+            case SOURCE_CONTAINER_BOUNDS:
+                sb.append("SOURCE_CONTAINER_BOUNDS Bounds");
+                break;
+            case SOURCE_FRAME:
+                sb.append("SOURCE_FRAME");
+                break;
+        }
+        if (insetsSize != null) {
+            sb.append(", insetsSize=").append(insetsSize);
+        }
+        if (imeInsetsSize != null) {
+            sb.append(", imeInsetsSize=").append(imeInsetsSize);
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
+    public InsetsFrameProvider(Parcel in) {
+        int insetsSizeModified = in.readInt();
+        type = in.readInt();
+        source = in.readInt();
+        if ((insetsSizeModified & HAS_INSETS_SIZE) != 0) {
+            insetsSize = Insets.CREATOR.createFromParcel(in);
+        }
+        if ((insetsSizeModified & HAS_IME_INSETS_SIZE) != 0) {
+            imeInsetsSize = Insets.CREATOR.createFromParcel(in);
+        }
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        int insetsSizeModified = 0;
+        if (insetsSize != null) {
+            insetsSizeModified |= HAS_INSETS_SIZE;
+        }
+        if (imeInsetsSize != null) {
+            insetsSizeModified |= HAS_IME_INSETS_SIZE;
+        }
+        out.writeInt(insetsSizeModified);
+        out.writeInt(type);
+        out.writeInt(source);
+        if (insetsSize != null) {
+            insetsSize.writeToParcel(out, flags);
+        }
+        if (imeInsetsSize != null) {
+            imeInsetsSize.writeToParcel(out, flags);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        InsetsFrameProvider other = (InsetsFrameProvider) o;
+        return type == other.type && source == other.source
+                && Objects.equals(insetsSize, other.insetsSize)
+                && Objects.equals(imeInsetsSize, other.imeInsetsSize);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = type;
+        result = 31 * result + source;
+        result = 31 * result + (insetsSize != null ? insetsSize.hashCode() : 0);
+        result = 31 * result + (imeInsetsSize != null ? imeInsetsSize.hashCode() : 0);
+        return result;
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<InsetsFrameProvider>
+            CREATOR = new Parcelable.Creator<InsetsFrameProvider>() {
+                @Override
+                public InsetsFrameProvider createFromParcel(Parcel in) {
+                    return new InsetsFrameProvider(in);
+                }
+
+                @Override
+                public InsetsFrameProvider[] newArray(int size) {
+                    return new InsetsFrameProvider[size];
+                }
+            };
+}
+
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index f6e4f6e..11e02e0 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -404,27 +404,20 @@
             if (source == null) {
                 continue;
             }
-            if (!canControlSide(frame, getInsetSide(
-                    source.calculateInsets(frame, true /* ignoreVisibility */)))) {
+            if (!canControlSource(frame, source)) {
                 blocked |= toPublicType(type);
             }
         }
         return blocked;
     }
 
-    private boolean canControlSide(Rect frame, int side) {
-        switch (side) {
-            case ISIDE_LEFT:
-            case ISIDE_RIGHT:
-                return frame.left == mDisplayFrame.left && frame.right == mDisplayFrame.right;
-            case ISIDE_TOP:
-            case ISIDE_BOTTOM:
-                return frame.top == mDisplayFrame.top && frame.bottom == mDisplayFrame.bottom;
-            case ISIDE_FLOATING:
-                return true;
-            default:
-                return false;
-        }
+    private static boolean canControlSource(Rect frame, InsetsSource source) {
+        final Insets insets = source.calculateInsets(frame, true /* ignoreVisibility */);
+        final Rect sourceFrame = source.getFrame();
+        final int sourceWidth = sourceFrame.width();
+        final int sourceHeight = sourceFrame.height();
+        return insets.left == sourceWidth || insets.right == sourceWidth
+                || insets.top == sourceHeight || insets.bottom == sourceHeight;
     }
 
     private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility,
diff --git a/core/java/android/view/RemoteAnimationTarget.java b/core/java/android/view/RemoteAnimationTarget.java
index e98d046..a468951 100644
--- a/core/java/android/view/RemoteAnimationTarget.java
+++ b/core/java/android/view/RemoteAnimationTarget.java
@@ -223,6 +223,12 @@
     public boolean hasAnimatingParent;
 
     /**
+     * Whether an activity has enabled {@link android.R.styleable#Animation_showBackdrop} for
+     * transition.
+     */
+    public boolean showBackdrop;
+
+    /**
      * The background color of animation in case the task info is not available if the transition
      * is activity level.
      */
@@ -287,6 +293,11 @@
         windowType = in.readInt();
         hasAnimatingParent = in.readBoolean();
         backgroundColor = in.readInt();
+        showBackdrop = in.readBoolean();
+    }
+
+    public void setShowBackdrop(boolean shouldShowBackdrop) {
+        showBackdrop = shouldShowBackdrop;
     }
 
     @Override
@@ -316,6 +327,7 @@
         dest.writeInt(windowType);
         dest.writeBoolean(hasAnimatingParent);
         dest.writeInt(backgroundColor);
+        dest.writeBoolean(showBackdrop);
     }
 
     public void dump(PrintWriter pw, String prefix) {
@@ -337,6 +349,7 @@
         pw.print(prefix); pw.print("windowType="); pw.print(windowType);
         pw.print(prefix); pw.print("hasAnimatingParent="); pw.print(hasAnimatingParent);
         pw.print(prefix); pw.print("backgroundColor="); pw.print(backgroundColor);
+        pw.print(prefix); pw.print("showBackdrop="); pw.print(showBackdrop);
     }
 
     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index a1ce39e..92bdfdd 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -121,6 +121,7 @@
     private static native void nativeSetAnimationTransaction(long transactionObj);
     private static native void nativeSetEarlyWakeupStart(long transactionObj);
     private static native void nativeSetEarlyWakeupEnd(long transactionObj);
+    private static native long nativeGetTransactionId(long transactionObj);
 
     private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder);
     private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject,
@@ -3537,6 +3538,15 @@
         }
 
         /**
+         * @hide
+         * @return The transaction's current id.
+         *         The id changed every time the transaction is applied.
+         */
+        public long getId() {
+            return nativeGetTransactionId(mNativeObject);
+        }
+
+        /**
          * Sets an arbitrary piece of metadata on the surface. This is a helper for int data.
          * @hide
          */
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index f7bca5b..d75ff2f 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -29,8 +29,6 @@
 import android.os.RemoteException;
 import android.util.Log;
 import android.window.WindowTokenClient;
-import android.view.InsetsState;
-import android.view.WindowManagerGlobal;
 import android.view.accessibility.IAccessibilityEmbeddedConnection;
 
 import java.util.Objects;
@@ -280,7 +278,7 @@
     public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d,
             @NonNull WindowlessWindowManager wwm, boolean useSfChoreographer) {
         mWm = wwm;
-        mViewRoot = new ViewRootImpl(c, d, mWm, useSfChoreographer);
+        mViewRoot = new ViewRootImpl(c, d, mWm, new WindowlessWindowLayout(), useSfChoreographer);
         addConfigCallback(c, d);
 
         WindowManagerGlobal.getInstance().addWindowlessRoot(mViewRoot);
@@ -310,7 +308,7 @@
         mWm = new WindowlessWindowManager(context.getResources().getConfiguration(),
                 mSurfaceControl, hostToken);
 
-        mViewRoot = new ViewRootImpl(context, display, mWm);
+        mViewRoot = new ViewRootImpl(context, display, mWm, new WindowlessWindowLayout());
         addConfigCallback(context, display);
 
         WindowManagerGlobal.getInstance().addWindowlessRoot(mViewRoot);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e46e44b..64151d9 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -60,13 +60,11 @@
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowLayout.UNSPECIFIED_LENGTH;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED;
@@ -77,13 +75,12 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
 import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER;
@@ -564,9 +561,7 @@
     private final Rect mVisRect = new Rect(); // used to retrieve visible rect of focused view.
     private final Rect mTempRect = new Rect();
 
-    private final WindowLayout mWindowLayout = new WindowLayout();
-
-    private ViewRootImpl mParentViewRoot;
+    private final WindowLayout mWindowLayout;
 
     // This is used to reduce the race between window focus changes being dispatched from
     // the window manager and input events coming through the input system.
@@ -601,9 +596,18 @@
      */
     private boolean mSyncBuffer = false;
 
+    /**
+     * Flag to determine whether the client needs to check with WMS if it can draw. WMS will notify
+     * the client that it can't draw if we're still in the middle of a sync set that includes this
+     * window. Once the sync is complete, the window can resume drawing. This is to ensure we don't
+     * deadlock the client by trying to request draws when there may not be any buffers available.
+     */
+    private boolean mCheckIfCanDraw = false;
+
     int mSyncSeqId = 0;
     int mLastSyncSeqId = 0;
 
+    private boolean mUpdateSurfaceNeeded;
     boolean mFullRedrawNeeded;
     boolean mNewSurfaceNeeded;
     boolean mForceNextWindowRelayout;
@@ -881,18 +885,20 @@
     private String mTag = TAG;
 
     public ViewRootImpl(Context context, Display display) {
-        this(context, display, WindowManagerGlobal.getWindowSession(),
+        this(context, display, WindowManagerGlobal.getWindowSession(), new WindowLayout(),
                 false /* useSfChoreographer */);
     }
 
-    public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session) {
-        this(context, display, session, false /* useSfChoreographer */);
+    public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
+            WindowLayout windowLayout) {
+        this(context, display, session, windowLayout, false /* useSfChoreographer */);
     }
 
     public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
-            boolean useSfChoreographer) {
+            WindowLayout windowLayout, boolean useSfChoreographer) {
         mContext = context;
         mWindowSession = session;
+        mWindowLayout = windowLayout;
         mDisplay = display;
         mBasePackageName = context.getBasePackageName();
         mThread = Thread.currentThread();
@@ -1184,7 +1190,6 @@
                 if (panelParentView != null) {
                     mAttachInfo.mPanelParentWindowToken
                             = panelParentView.getApplicationWindowToken();
-                    mParentViewRoot = panelParentView.getViewRootImpl();
                 }
                 mAdded = true;
                 int res; /* = WindowManagerImpl.ADD_OKAY; */
@@ -1215,14 +1220,21 @@
                     collectViewAttributes();
                     adjustLayoutParamsForCompatibility(mWindowAttributes);
                     controlInsetsForCompatibility(mWindowAttributes);
+
+                    Rect attachedFrame = new Rect();
                     res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
                             getHostVisibility(), mDisplay.getDisplayId(), userId,
                             mInsetsController.getRequestedVisibilities(), inputChannel, mTempInsets,
-                            mTempControls);
+                            mTempControls, attachedFrame);
+                    if (!attachedFrame.isValid()) {
+                        attachedFrame = null;
+                    }
                     if (mTranslator != null) {
                         mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
                         mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
+                        mTranslator.translateRectInScreenToAppWindow(attachedFrame);
                     }
+                    mTmpFrames.attachedFrame = attachedFrame;
                 } catch (RemoteException e) {
                     mAdded = false;
                     mView = null;
@@ -1249,8 +1261,8 @@
                 mWindowLayout.computeFrames(mWindowAttributes, state,
                         displayCutoutSafe, winConfig.getBounds(), winConfig.getWindowingMode(),
                         UNSPECIFIED_LENGTH, UNSPECIFIED_LENGTH,
-                        mInsetsController.getRequestedVisibilities(),
-                        getAttachedWindowFrame(), 1f /* compactScale */, mTmpFrames);
+                        mInsetsController.getRequestedVisibilities(), 1f /* compactScale */,
+                        mTmpFrames);
                 setFrame(mTmpFrames.frame);
                 registerBackCallbackOnWindow();
                 if (!WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
@@ -1372,14 +1384,6 @@
         }
     }
 
-    private Rect getAttachedWindowFrame() {
-        final int type = mWindowAttributes.type;
-        final boolean layoutAttached = (mParentViewRoot != null
-                && type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW
-                && type != TYPE_APPLICATION_ATTACHED_DIALOG);
-        return layoutAttached ? mParentViewRoot.mWinFrame : null;
-    }
-
     /**
      * Register any kind of listeners if setView was success.
      */
@@ -1737,16 +1741,20 @@
 
         final Rect frame = frames.frame;
         final Rect displayFrame = frames.displayFrame;
+        final Rect attachedFrame = frames.attachedFrame;
         if (mTranslator != null) {
             mTranslator.translateRectInScreenToAppWindow(frame);
             mTranslator.translateRectInScreenToAppWindow(displayFrame);
+            mTranslator.translateRectInScreenToAppWindow(attachedFrame);
         }
         final boolean frameChanged = !mWinFrame.equals(frame);
         final boolean configChanged = !mLastReportedMergedConfiguration.equals(mergedConfiguration);
+        final boolean attachedFrameChanged = LOCAL_LAYOUT
+                && !Objects.equals(mTmpFrames.attachedFrame, attachedFrame);
         final boolean displayChanged = mDisplay.getDisplayId() != displayId;
         final boolean resizeModeChanged = mResizeMode != resizeMode;
-        if (msg == MSG_RESIZED && !frameChanged && !configChanged && !displayChanged
-                && !resizeModeChanged && !forceNextWindowRelayout) {
+        if (msg == MSG_RESIZED && !frameChanged && !configChanged && !attachedFrameChanged
+                && !displayChanged && !resizeModeChanged && !forceNextWindowRelayout) {
             return;
         }
 
@@ -1764,6 +1772,9 @@
 
         setFrame(frame);
         mTmpFrames.displayFrame.set(displayFrame);
+        if (mTmpFrames.attachedFrame != null && attachedFrame != null) {
+            mTmpFrames.attachedFrame.set(attachedFrame);
+        }
 
         if (mDragResizing && mUseMTRenderer) {
             boolean fullscreen = frame.equals(mPendingBackDropFrame);
@@ -1773,7 +1784,7 @@
             }
         }
 
-        mForceNextWindowRelayout = forceNextWindowRelayout;
+        mForceNextWindowRelayout |= forceNextWindowRelayout;
         mPendingAlwaysConsumeSystemBars = args.argi2 != 0;
         mSyncSeqId = args.argi4 > mSyncSeqId ? args.argi4 : mSyncSeqId;
 
@@ -2697,6 +2708,9 @@
 
         mIsInTraversal = true;
         mWillDrawSoon = true;
+        boolean cancelDraw = false;
+        boolean isSyncRequest = false;
+
         boolean windowSizeMayChange = false;
         WindowManager.LayoutParams lp = mWindowAttributes;
 
@@ -2903,7 +2917,6 @@
         final int surfaceGenerationId = mSurface.getGenerationId();
 
         final boolean isViewVisible = viewVisibility == View.VISIBLE;
-        final boolean windowRelayoutWasForced = mForceNextWindowRelayout;
         boolean surfaceSizeChanged = false;
         boolean surfaceCreated = false;
         boolean surfaceDestroyed = false;
@@ -2967,6 +2980,8 @@
                     mViewFrameInfo.flags |= FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED;
                 }
                 relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
+                cancelDraw = (relayoutResult & RELAYOUT_RES_CANCEL_AND_REDRAW)
+                        == RELAYOUT_RES_CANCEL_AND_REDRAW;
                 final boolean dragResizing = mPendingDragResizing;
                 if (mSyncSeqId > mLastSyncSeqId) {
                     mLastSyncSeqId = mSyncSeqId;
@@ -2975,6 +2990,7 @@
                     }
                     reportNextDraw();
                     mSyncBuffer = true;
+                    isSyncRequest = true;
                 }
 
                 final boolean surfaceControlChanged =
@@ -3007,6 +3023,8 @@
                             !mFirst, INVALID_DISPLAY /* same display */);
                     updatedConfiguration = true;
                 }
+                final boolean updateSurfaceNeeded = mUpdateSurfaceNeeded;
+                mUpdateSurfaceNeeded = false;
 
                 surfaceSizeChanged = false;
                 if (!mLastSurfaceSize.equals(mSurfaceSize)) {
@@ -3085,8 +3103,7 @@
                     if (isHardwareEnabled()) {
                         mAttachInfo.mThreadedRenderer.destroy();
                     }
-                } else if ((surfaceReplaced
-                        || surfaceSizeChanged || windowRelayoutWasForced)
+                } else if ((surfaceReplaced || surfaceSizeChanged || updateSurfaceNeeded)
                         && mSurfaceHolder == null
                         && mAttachInfo.mThreadedRenderer != null
                         && mSurface.isValid()) {
@@ -3262,6 +3279,19 @@
                 }
             }
         } else {
+            // If a relayout isn't going to happen, we still need to check if this window can draw
+            // when mCheckIfCanDraw is set. This is because it means we had a sync in the past, but
+            // have not been told by WMS that the sync is complete and that we can continue to draw
+            if (mCheckIfCanDraw) {
+                try {
+                    cancelDraw = mWindowSession.cancelDraw(mWindow);
+                    if (DEBUG_BLAST) {
+                        Log.d(mTag, "cancelDraw returned " + cancelDraw);
+                    }
+                } catch (RemoteException e) {
+                }
+            }
+
             // Not the first pass and no window/insets/visibility change but the window
             // may have moved and we need check that and if so to update the left and right
             // in the attach info. We translate only the window frame since on window move
@@ -3480,7 +3510,9 @@
             reportNextDraw();
         }
 
-        boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw();
+        mCheckIfCanDraw = isSyncRequest || cancelDraw;
+
+        boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || cancelDraw;
         if (!cancelAndRedraw) {
             createSyncIfNeeded();
         }
@@ -5218,6 +5250,21 @@
             throw new IllegalArgumentException("No merged config provided.");
         }
 
+        final int lastRotation = mLastReportedMergedConfiguration.getMergedConfiguration()
+                .windowConfiguration.getRotation();
+        final int newRotation = mergedConfiguration.getMergedConfiguration()
+                .windowConfiguration.getRotation();
+        if (lastRotation != newRotation) {
+            // Trigger ThreadedRenderer#updateSurface() if the surface control doesn't change.
+            // Because even if the actual surface size is not changed, e.g. flip 180 degrees,
+            // the buffers may still have content in previous rotation. And the next draw may
+            // not update all regions, that causes some afterimages to flicker.
+            mUpdateSurfaceNeeded = true;
+            if (!mIsInTraversal) {
+                mForceNextWindowRelayout = true;
+            }
+        }
+
         Configuration globalConfig = mergedConfiguration.getGlobalConfiguration();
         final Configuration overrideConfig = mergedConfiguration.getOverrideConfiguration();
         if (DEBUG_CONFIGURATION) Log.v(mTag,
@@ -7990,69 +8037,20 @@
         final int requestedWidth = (int) (mView.getMeasuredWidth() * appScale + 0.5f);
         final int requestedHeight = (int) (mView.getMeasuredHeight() * appScale + 0.5f);
 
-        int relayoutResult = 0;
-        WindowConfiguration winConfig = getConfiguration().windowConfiguration;
-        if (LOCAL_LAYOUT) {
-            if (mFirst || viewVisibility != mViewVisibility) {
-                relayoutResult = mWindowSession.updateVisibility(mWindow, params, viewVisibility,
-                        mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTempControls);
-                if (mTranslator != null) {
-                    mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
-                    mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
-                }
-                mInsetsController.onStateChanged(mTempInsets);
-                mInsetsController.onControlsChanged(mTempControls);
-
-                mPendingAlwaysConsumeSystemBars =
-                        (relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
-            }
-            final InsetsState state = mInsetsController.getState();
-            final Rect displayCutoutSafe = mTempRect;
-            state.getDisplayCutoutSafe(displayCutoutSafe);
-            if (mWindowAttributes.type == TYPE_APPLICATION_STARTING) {
-                // TODO(b/210378379): Remove the special logic.
-                // Letting starting window use the window bounds from the pending config is for the
-                // fixed rotation, because the config is not overridden before the starting window
-                // is created.
-                winConfig = mPendingMergedConfiguration.getMergedConfiguration()
-                        .windowConfiguration;
-            }
-            mWindowLayout.computeFrames(mWindowAttributes, state, displayCutoutSafe,
-                    winConfig.getBounds(), winConfig.getWindowingMode(), requestedWidth,
-                    requestedHeight, mInsetsController.getRequestedVisibilities(),
-                    getAttachedWindowFrame(), 1f /* compatScale */, mTmpFrames);
-
-            mWindowSession.updateLayout(mWindow, params,
-                    insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mTmpFrames,
-                    requestedWidth, requestedHeight);
-
-        } else {
-            relayoutResult = mWindowSession.relayout(mWindow, params,
-                    requestedWidth, requestedHeight, viewVisibility,
-                    insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
-                    mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
-                    mTempControls, mRelayoutBundle);
-            final int maybeSyncSeqId = mRelayoutBundle.getInt("seqid");
-            if (maybeSyncSeqId > 0) {
-                mSyncSeqId = maybeSyncSeqId;
-            }
-
-            if (mTranslator != null) {
-                mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
-                mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame);
-                mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
-                mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
-            }
-            mInsetsController.onStateChanged(mTempInsets);
-            mInsetsController.onControlsChanged(mTempControls);
-
-            mPendingAlwaysConsumeSystemBars =
-                    (relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
+        int relayoutResult = mWindowSession.relayout(mWindow, params,
+                requestedWidth, requestedHeight, viewVisibility,
+                insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
+                mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
+                mTempControls, mRelayoutBundle);
+        final int maybeSyncSeqId = mRelayoutBundle.getInt("seqid");
+        if (maybeSyncSeqId > 0) {
+            mSyncSeqId = maybeSyncSeqId;
         }
 
         final int transformHint = SurfaceControl.rotationToBufferTransform(
                 (mDisplayInstallOrientation + mDisplay.getRotation()) % 4);
 
+        final WindowConfiguration winConfig = getConfiguration().windowConfiguration;
         WindowLayout.computeSurfaceSize(mWindowAttributes, winConfig.getMaxBounds(), requestedWidth,
                 requestedHeight, mTmpFrames.frame, mPendingDragResizing, mSurfaceSize);
 
@@ -8101,10 +8099,23 @@
             destroySurface();
         }
 
+        mPendingAlwaysConsumeSystemBars =
+                (relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
+
         if (restore) {
             params.restore();
         }
+
+        if (mTranslator != null) {
+            mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
+            mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame);
+            mTranslator.translateRectInScreenToAppWindow(mTmpFrames.attachedFrame);
+            mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
+            mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
+        }
         setFrame(mTmpFrames.frame);
+        mInsetsController.onStateChanged(mTempInsets);
+        mInsetsController.onControlsChanged(mTempControls);
         return relayoutResult;
     }
 
diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java
index c320b26..9b6b2b9 100644
--- a/core/java/android/view/WindowLayout.java
+++ b/core/java/android/view/WindowLayout.java
@@ -66,14 +66,15 @@
     public void computeFrames(WindowManager.LayoutParams attrs, InsetsState state,
             Rect displayCutoutSafe, Rect windowBounds, @WindowingMode int windowingMode,
             int requestedWidth, int requestedHeight, InsetsVisibilities requestedVisibilities,
-            Rect attachedWindowFrame, float compatScale, ClientWindowFrames outFrames) {
+            float compatScale, ClientWindowFrames frames) {
         final int type = attrs.type;
         final int fl = attrs.flags;
         final int pfl = attrs.privateFlags;
         final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) == FLAG_LAYOUT_IN_SCREEN;
-        final Rect outDisplayFrame = outFrames.displayFrame;
-        final Rect outParentFrame = outFrames.parentFrame;
-        final Rect outFrame = outFrames.frame;
+        final Rect attachedWindowFrame = frames.attachedFrame;
+        final Rect outDisplayFrame = frames.displayFrame;
+        final Rect outParentFrame = frames.parentFrame;
+        final Rect outFrame = frames.frame;
 
         // Compute bounds restricted by insets
         final Insets insets = state.calculateInsets(windowBounds, attrs.getFitInsetsTypes(),
@@ -104,7 +105,7 @@
         final DisplayCutout cutout = state.getDisplayCutout();
         final Rect displayCutoutSafeExceptMaybeBars = mTempDisplayCutoutSafeExceptMaybeBarsRect;
         displayCutoutSafeExceptMaybeBars.set(displayCutoutSafe);
-        outFrames.isParentFrameClippedByDisplayCutout = false;
+        frames.isParentFrameClippedByDisplayCutout = false;
         if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS && !cutout.isEmpty()) {
             // Ensure that windows with a non-ALWAYS display cutout mode are laid out in
             // the cutout safe zone.
@@ -167,7 +168,7 @@
             if (!attachedInParent && !floatingInScreenWindow) {
                 mTempRect.set(outParentFrame);
                 outParentFrame.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
-                outFrames.isParentFrameClippedByDisplayCutout = !mTempRect.equals(outParentFrame);
+                frames.isParentFrameClippedByDisplayCutout = !mTempRect.equals(outParentFrame);
             }
             outDisplayFrame.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
         }
@@ -287,12 +288,9 @@
             }
         }
 
-        if (DEBUG) Log.d(TAG, "computeWindowFrames " + attrs.getTitle()
-                + " outFrames=" + outFrames
+        if (DEBUG) Log.d(TAG, "computeFrames " + attrs.getTitle()
+                + " frames=" + frames
                 + " windowBounds=" + windowBounds.toShortString()
-                + " attachedWindowFrame=" + (attachedWindowFrame != null
-                        ? attachedWindowFrame.toShortString()
-                        : "null")
                 + " requestedWidth=" + requestedWidth
                 + " requestedHeight=" + requestedHeight
                 + " compatScale=" + compatScale
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 00052f6..dd990e7 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -98,7 +98,6 @@
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
-import android.graphics.Insets;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -341,6 +340,18 @@
     int TRANSIT_OLD_TASK_FRAGMENT_CHANGE = 30;
 
     /**
+     * A dream activity is being opened.
+     * @hide
+     */
+    int TRANSIT_OLD_DREAM_ACTIVITY_OPEN = 31;
+
+    /**
+     * A dream activity is being closed.
+     * @hide
+     */
+    int TRANSIT_OLD_DREAM_ACTIVITY_CLOSE = 32;
+
+    /**
      * @hide
      */
     @IntDef(prefix = { "TRANSIT_OLD_" }, value = {
@@ -368,7 +379,9 @@
             TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE,
             TRANSIT_OLD_TASK_FRAGMENT_OPEN,
             TRANSIT_OLD_TASK_FRAGMENT_CLOSE,
-            TRANSIT_OLD_TASK_FRAGMENT_CHANGE
+            TRANSIT_OLD_TASK_FRAGMENT_CHANGE,
+            TRANSIT_OLD_DREAM_ACTIVITY_OPEN,
+            TRANSIT_OLD_DREAM_ACTIVITY_CLOSE
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface TransitionOldType {}
@@ -2578,6 +2591,7 @@
                 PRIVATE_FLAG_SYSTEM_ERROR,
                 PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
                 PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR,
+                PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
                 PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY,
                 PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH,
                 PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME,
@@ -2639,6 +2653,10 @@
                         equals = PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR,
                         name = "FORCE_STATUS_BAR_VISIBLE"),
                 @ViewDebug.FlagToString(
+                        mask = PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
+                        equals = PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
+                        name = "LAYOUT_SIZE_EXTENDED_BY_CUTOUT"),
+                @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY,
                         equals = PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY,
                         name = "FORCE_DECOR_VIEW_VISIBILITY"),
@@ -3589,34 +3607,17 @@
         private boolean mFitInsetsIgnoringVisibility = false;
 
         /**
-         * {@link InsetsState.InternalInsetsType}s to be applied to the window
-         * If {@link #type} has the predefined insets (like {@link #TYPE_STATUS_BAR} or
-         * {@link #TYPE_NAVIGATION_BAR}), this field will be ignored.
-         *
-         * <p>Note: provide only one inset corresponding to the window type (like
-         * {@link InsetsState.InternalInsetsType#ITYPE_STATUS_BAR} or
-         * {@link InsetsState.InternalInsetsType#ITYPE_NAVIGATION_BAR})</p>
-         * @hide
-         */
-        public @InsetsState.InternalInsetsType int[] providesInsetsTypes;
-
-        /**
-         * If specified, the insets provided by this window will be our window frame minus the
-         * insets specified by providedInternalInsets for each type. This should not be used
-         * together with {@link WindowState#mGivenContentInsets}. If both of them are set, both will
-         * be applied.
+         * If set, the specified insets types will be provided by the window and the insets frame
+         * will be calculated based on the provider's parameters. The insets types and the array
+         * should not be modified after the window is added. If multiple layout parameters are
+         * provided for different rotations in {@link LayoutParams#paramsForRotation}, the types in
+         * the providedInsets array should be the same in all rotations, including the base one.
+         * All other params can be adjusted at runtime.
+         * See {@link InsetsFrameProvider}.
          *
          * @hide
          */
-        public Insets[] providedInternalInsets;
-
-        /**
-         * If specified, the insets provided by this window for the IME will be our window frame
-         * minus the insets specified by providedInternalImeInsets.
-         *
-         * @hide
-         */
-        public Insets[] providedInternalImeInsets;
+        public InsetsFrameProvider[] providedInsets;
 
         /**
          * If specified, the frame that used to calculate relative {@link RoundedCorner} will be
@@ -3748,6 +3749,18 @@
             }
         }
 
+        /**
+         * @see #paramsForRotation
+         * @hide
+         */
+        public LayoutParams forRotation(int rotation) {
+            if (paramsForRotation == null || paramsForRotation.length <= rotation
+                    || paramsForRotation[rotation] == null) {
+                return this;
+            }
+            return paramsForRotation[rotation];
+        }
+
         public LayoutParams() {
             super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
             type = TYPE_APPLICATION;
@@ -3996,32 +4009,10 @@
             out.writeBoolean(mFitInsetsIgnoringVisibility);
             out.writeBoolean(preferMinimalPostProcessing);
             out.writeInt(mBlurBehindRadius);
-            if (providesInsetsTypes != null) {
-                out.writeInt(providesInsetsTypes.length);
-                out.writeIntArray(providesInsetsTypes);
-            } else {
-                out.writeInt(0);
-            }
-            if (providedInternalInsets != null) {
-                out.writeInt(providedInternalInsets.length);
-                out.writeTypedArray(providedInternalInsets, 0 /* parcelableFlags */);
-            } else {
-                out.writeInt(0);
-            }
-            if (providedInternalImeInsets != null) {
-                out.writeInt(providedInternalImeInsets.length);
-                out.writeTypedArray(providedInternalImeInsets, 0 /* parcelableFlags */);
-            } else {
-                out.writeInt(0);
-            }
             out.writeBoolean(insetsRoundedCornerFrame);
-            if (paramsForRotation != null) {
-                checkNonRecursiveParams();
-                out.writeInt(paramsForRotation.length);
-                out.writeTypedArray(paramsForRotation, 0 /* parcelableFlags */);
-            } else {
-                out.writeInt(0);
-            }
+            out.writeTypedArray(providedInsets, 0 /* parcelableFlags */);
+            checkNonRecursiveParams();
+            out.writeTypedArray(paramsForRotation, 0 /* parcelableFlags */);
         }
 
         public static final @android.annotation.NonNull Parcelable.Creator<LayoutParams> CREATOR
@@ -4088,27 +4079,9 @@
             mFitInsetsIgnoringVisibility = in.readBoolean();
             preferMinimalPostProcessing = in.readBoolean();
             mBlurBehindRadius = in.readInt();
-            int insetsTypesLength = in.readInt();
-            if (insetsTypesLength > 0) {
-                providesInsetsTypes = new int[insetsTypesLength];
-                in.readIntArray(providesInsetsTypes);
-            }
-            int providedInternalInsetsLength = in.readInt();
-            if (providedInternalInsetsLength > 0) {
-                providedInternalInsets = new Insets[providedInternalInsetsLength];
-                in.readTypedArray(providedInternalInsets, Insets.CREATOR);
-            }
-            int providedInternalImeInsetsLength = in.readInt();
-            if (providedInternalImeInsetsLength > 0) {
-                providedInternalImeInsets = new Insets[providedInternalImeInsetsLength];
-                in.readTypedArray(providedInternalImeInsets, Insets.CREATOR);
-            }
             insetsRoundedCornerFrame = in.readBoolean();
-            int paramsForRotationLength = in.readInt();
-            if (paramsForRotationLength > 0) {
-                paramsForRotation = new LayoutParams[paramsForRotationLength];
-                in.readTypedArray(paramsForRotation, LayoutParams.CREATOR);
-            }
+            providedInsets = in.createTypedArray(InsetsFrameProvider.CREATOR);
+            paramsForRotation = in.createTypedArray(LayoutParams.CREATOR);
         }
 
         @SuppressWarnings({"PointlessBitwiseExpression"})
@@ -4400,18 +4373,8 @@
                 changes |= LAYOUT_CHANGED;
             }
 
-            if (!Arrays.equals(providesInsetsTypes, o.providesInsetsTypes)) {
-                providesInsetsTypes = o.providesInsetsTypes;
-                changes |= LAYOUT_CHANGED;
-            }
-
-            if (!Arrays.equals(providedInternalInsets, o.providedInternalInsets)) {
-                providedInternalInsets = o.providedInternalInsets;
-                changes |= LAYOUT_CHANGED;
-            }
-
-            if (!Arrays.equals(providedInternalImeInsets, o.providedInternalImeInsets)) {
-                providedInternalImeInsets = o.providedInternalImeInsets;
+            if (!Arrays.equals(providedInsets, o.providedInsets)) {
+                providedInsets = o.providedInsets;
                 changes |= LAYOUT_CHANGED;
             }
 
@@ -4613,28 +4576,12 @@
                 sb.append(System.lineSeparator());
                 sb.append(prefix).append("  fitIgnoreVis");
             }
-            if (providesInsetsTypes != null) {
+            if (providedInsets != null) {
                 sb.append(System.lineSeparator());
-                sb.append(prefix).append("  insetsTypes=");
-                for (int i = 0; i < providesInsetsTypes.length; ++i) {
+                sb.append(" providedInsets=");
+                for (int i = 0; i < providedInsets.length; ++i) {
                     if (i > 0) sb.append(' ');
-                    sb.append(InsetsState.typeToString(providesInsetsTypes[i]));
-                }
-            }
-            if (providedInternalInsets != null) {
-                sb.append(System.lineSeparator());
-                sb.append(" providedInternalInsets=");
-                for (int i = 0; i < providedInternalInsets.length; ++i) {
-                    if (i > 0) sb.append(' ');
-                    sb.append((providedInternalInsets[i]));
-                }
-            }
-            if (providedInternalImeInsets != null) {
-                sb.append(System.lineSeparator());
-                sb.append(" providedInternalImeInsets=");
-                for (int i = 0; i < providedInternalImeInsets.length; ++i) {
-                    if (i > 0) sb.append(' ');
-                    sb.append((providedInternalImeInsets[i]));
+                    sb.append((providedInsets[i]));
                 }
             }
             if (insetsRoundedCornerFrame) {
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index aae930e..25445ab 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -83,6 +83,11 @@
     public static final int RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS = 1 << 3;
 
     /**
+     * The window manager has told the window it cannot draw this frame and should retry again.
+     */
+    public static final int RELAYOUT_RES_CANCEL_AND_REDRAW = 1 << 4;
+
+    /**
      * Flag for relayout: the client will be later giving
      * internal insets; as a result, the window will not impact other window
      * layouts until the insets are given.
@@ -386,7 +391,7 @@
                 root = new ViewRootImpl(view.getContext(), display);
             } else {
                 root = new ViewRootImpl(view.getContext(), display,
-                        windowlessSession);
+                        windowlessSession, new WindowlessWindowLayout());
             }
 
             view.setLayoutParams(wparams);
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 4d07171..43d427d 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -237,10 +237,6 @@
      */
     int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER - 1;
 
-    // TODO(b/207185041): Remove this divider workaround after we full remove leagacy split and
-    //                    make app pair split only have single root then we can just attach the
-    //                    divider to the single root task in shell.
-    int SPLIT_DIVIDER_LAYER = TYPE_LAYER_MULTIPLIER * 3;
     int WATERMARK_LAYER = TYPE_LAYER_MULTIPLIER * 100;
     int STRICT_MODE_LAYER = TYPE_LAYER_MULTIPLIER * 101;
     int WINDOW_FREEZE_LAYER = TYPE_LAYER_MULTIPLIER * 200;
diff --git a/core/java/android/view/WindowlessWindowLayout.java b/core/java/android/view/WindowlessWindowLayout.java
new file mode 100644
index 0000000..5bec5b6
--- /dev/null
+++ b/core/java/android/view/WindowlessWindowLayout.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.app.WindowConfiguration.WindowingMode;
+import android.graphics.Rect;
+import android.window.ClientWindowFrames;
+
+/**
+ * Computes window frames for the windowless window.
+ * @hide
+ */
+public class WindowlessWindowLayout extends WindowLayout {
+
+    @Override
+    public void computeFrames(WindowManager.LayoutParams attrs, InsetsState state,
+            Rect displayCutoutSafe, Rect windowBounds, @WindowingMode int windowingMode,
+            int requestedWidth, int requestedHeight, InsetsVisibilities requestedVisibilities,
+            float compatScale, ClientWindowFrames frames) {
+        frames.frame.set(0, 0, attrs.width, attrs.height);
+        frames.displayFrame.set(frames.frame);
+        frames.parentFrame.set(frames.frame);
+    }
+}
+
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index a212348..94da274 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -149,7 +149,7 @@
     public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs,
             int viewVisibility, int displayId, InsetsVisibilities requestedVisibilities,
             InputChannel outInputChannel, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
+            InsetsSourceControl[] outActiveControls, Rect outAttachedFrame) {
         final SurfaceControl.Builder b = new SurfaceControl.Builder(mSurfaceSession)
                 .setFormat(attrs.format)
                 .setBLASTLayer()
@@ -181,6 +181,7 @@
         synchronized (this) {
             mStateForWindow.put(window.asBinder(), state);
         }
+        outAttachedFrame.set(0, 0, -1, -1);
 
         final int res = WindowManagerGlobal.ADD_OKAY | WindowManagerGlobal.ADD_FLAG_APP_VISIBLE |
                         WindowManagerGlobal.ADD_FLAG_USE_BLAST;
@@ -196,15 +197,15 @@
     public int addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs,
             int viewVisibility, int displayId, int userId, InsetsVisibilities requestedVisibilities,
             InputChannel outInputChannel, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
+            InsetsSourceControl[] outActiveControls, Rect outAttachedFrame) {
         return addToDisplay(window, attrs, viewVisibility, displayId, requestedVisibilities,
-                outInputChannel, outInsetsState, outActiveControls);
+                outInputChannel, outInsetsState, outActiveControls, outAttachedFrame);
     }
 
     @Override
     public int addToDisplayWithoutInputChannel(android.view.IWindow window,
             android.view.WindowManager.LayoutParams attrs, int viewVisibility, int layerStackId,
-            android.view.InsetsState insetsState) {
+            android.view.InsetsState insetsState, Rect outAttachedFrame) {
         return 0;
     }
 
@@ -337,21 +338,6 @@
     }
 
     @Override
-    public int updateVisibility(IWindow window, WindowManager.LayoutParams inAttrs,
-            int viewVisibility, MergedConfiguration outMergedConfiguration,
-            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
-        // TODO(b/161810301): Finish the implementation.
-        return 0;
-    }
-
-    @Override
-    public void updateLayout(IWindow window, WindowManager.LayoutParams inAttrs, int flags,
-            ClientWindowFrames clientWindowFrames, int requestedWidth, int requestedHeight) {
-        // TODO(b/161810301): Finish the implementation.
-    }
-
-    @Override
     public void prepareToReplaceWindows(android.os.IBinder appToken, boolean childrenOnly) {
     }
 
@@ -552,4 +538,9 @@
             }
         }
     }
+
+    @Override
+    public boolean cancelDraw(IWindow window) {
+        return false;
+    }
 }
diff --git a/core/java/android/window/ClientWindowFrames.java b/core/java/android/window/ClientWindowFrames.java
index 51f3fe2..929e81ed 100644
--- a/core/java/android/window/ClientWindowFrames.java
+++ b/core/java/android/window/ClientWindowFrames.java
@@ -17,6 +17,7 @@
 package android.window;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -40,6 +41,12 @@
      */
     public final @NonNull Rect parentFrame = new Rect();
 
+    /**
+     * The frame this window attaches to. If this is not null, this is the frame of the parent
+     * window.
+     */
+    public @Nullable Rect attachedFrame;
+
     public boolean isParentFrameClippedByDisplayCutout;
 
     public ClientWindowFrames() {
@@ -49,6 +56,9 @@
         frame.set(other.frame);
         displayFrame.set(other.displayFrame);
         parentFrame.set(other.parentFrame);
+        if (other.attachedFrame != null) {
+            attachedFrame = new Rect(other.attachedFrame);
+        }
         isParentFrameClippedByDisplayCutout = other.isParentFrameClippedByDisplayCutout;
     }
 
@@ -61,6 +71,7 @@
         frame.readFromParcel(in);
         displayFrame.readFromParcel(in);
         parentFrame.readFromParcel(in);
+        attachedFrame = in.readTypedObject(Rect.CREATOR);
         isParentFrameClippedByDisplayCutout = in.readBoolean();
     }
 
@@ -69,6 +80,7 @@
         frame.writeToParcel(dest, flags);
         displayFrame.writeToParcel(dest, flags);
         parentFrame.writeToParcel(dest, flags);
+        dest.writeTypedObject(attachedFrame, flags);
         dest.writeBoolean(isParentFrameClippedByDisplayCutout);
     }
 
@@ -78,6 +90,7 @@
         return "ClientWindowFrames{frame=" + frame.toShortString(sb)
                 + " display=" + displayFrame.toShortString(sb)
                 + " parentFrame=" + parentFrame.toShortString(sb)
+                + (attachedFrame != null ? " attachedFrame=" + attachedFrame.toShortString() : "")
                 + " parentClippedByDisplayCutout=" + isParentFrameClippedByDisplayCutout + "}";
     }
 
diff --git a/core/java/android/window/PictureInPictureSurfaceTransaction.java b/core/java/android/window/PictureInPictureSurfaceTransaction.java
index 0a751c3..3b1fdf5 100644
--- a/core/java/android/window/PictureInPictureSurfaceTransaction.java
+++ b/core/java/android/window/PictureInPictureSurfaceTransaction.java
@@ -51,6 +51,8 @@
 
     private final Rect mWindowCrop;
 
+    private boolean mShouldDisableCanAffectSystemUiFlags;
+
     private PictureInPictureSurfaceTransaction(Parcel in) {
         mAlpha = in.readFloat();
         mPosition = in.readTypedObject(PointF.CREATOR);
@@ -60,6 +62,7 @@
         mCornerRadius = in.readFloat();
         mShadowRadius = in.readFloat();
         mWindowCrop = in.readTypedObject(Rect.CREATOR);
+        mShouldDisableCanAffectSystemUiFlags = in.readBoolean();
     }
 
     private PictureInPictureSurfaceTransaction(float alpha, @Nullable PointF position,
@@ -84,6 +87,7 @@
         this(other.mAlpha, other.mPosition,
                 other.mFloat9, other.mRotation, other.mCornerRadius, other.mShadowRadius,
                 other.mWindowCrop);
+        mShouldDisableCanAffectSystemUiFlags = other.mShouldDisableCanAffectSystemUiFlags;
     }
 
     /** @return {@link Matrix} from {@link #mFloat9} */
@@ -103,6 +107,16 @@
         return mShadowRadius > 0;
     }
 
+    /** Sets the internal {@link #mShouldDisableCanAffectSystemUiFlags}. */
+    public void setShouldDisableCanAffectSystemUiFlags(boolean shouldDisable) {
+        mShouldDisableCanAffectSystemUiFlags = shouldDisable;
+    }
+
+    /** @return {@code true} if we should disable Task#setCanAffectSystemUiFlags. */
+    public boolean getShouldDisableCanAffectSystemUiFlags() {
+        return mShouldDisableCanAffectSystemUiFlags;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
@@ -114,13 +128,16 @@
                 && Objects.equals(mRotation, that.mRotation)
                 && Objects.equals(mCornerRadius, that.mCornerRadius)
                 && Objects.equals(mShadowRadius, that.mShadowRadius)
-                && Objects.equals(mWindowCrop, that.mWindowCrop);
+                && Objects.equals(mWindowCrop, that.mWindowCrop)
+                && mShouldDisableCanAffectSystemUiFlags
+                == that.mShouldDisableCanAffectSystemUiFlags;
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mAlpha, mPosition, Arrays.hashCode(mFloat9),
-                mRotation, mCornerRadius, mShadowRadius, mWindowCrop);
+                mRotation, mCornerRadius, mShadowRadius, mWindowCrop,
+                mShouldDisableCanAffectSystemUiFlags);
     }
 
     @Override
@@ -137,6 +154,7 @@
         out.writeFloat(mCornerRadius);
         out.writeFloat(mShadowRadius);
         out.writeTypedObject(mWindowCrop, 0 /* flags */);
+        out.writeBoolean(mShouldDisableCanAffectSystemUiFlags);
     }
 
     @Override
@@ -150,6 +168,7 @@
                 + " cornerRadius=" + mCornerRadius
                 + " shadowRadius=" + mShadowRadius
                 + " crop=" + mWindowCrop
+                + " shouldDisableCanAffectSystemUiFlags" + mShouldDisableCanAffectSystemUiFlags
                 + ")";
     }
 
diff --git a/core/java/android/window/SizeConfigurationBuckets.java b/core/java/android/window/SizeConfigurationBuckets.java
index f474f0a..998bec0 100644
--- a/core/java/android/window/SizeConfigurationBuckets.java
+++ b/core/java/android/window/SizeConfigurationBuckets.java
@@ -104,24 +104,15 @@
     /**
      * Get the changes between two configurations but don't count changes in sizes if they don't
      * cross boundaries that are important to the app.
-     *
-     * This is a static helper to deal with null `buckets`. When no buckets have been specified,
-     * this actually filters out all 3 size-configs. This is legacy behavior.
      */
     public static int filterDiff(int diff, @NonNull Configuration oldConfig,
             @NonNull Configuration newConfig, @Nullable SizeConfigurationBuckets buckets) {
+        if (buckets == null) {
+            return diff;
+        }
+
         final boolean nonSizeLayoutFieldsUnchanged =
                 areNonSizeLayoutFieldsUnchanged(oldConfig.screenLayout, newConfig.screenLayout);
-        if (buckets == null) {
-            // Only unflip CONFIG_SCREEN_LAYOUT if non-size-related  attributes of screen layout do
-            // not change.
-            if (nonSizeLayoutFieldsUnchanged) {
-                return diff & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE
-                        | CONFIG_SCREEN_LAYOUT);
-            } else {
-                return diff & ~(CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE);
-            }
-        }
         if ((diff & CONFIG_SCREEN_SIZE) != 0) {
             final boolean crosses = buckets.crossesHorizontalSizeThreshold(oldConfig.screenWidthDp,
                     newConfig.screenWidthDp)
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 51da61f..c81184f 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -107,8 +107,11 @@
      */
     public static final int FLAG_DISPLAY_HAS_ALERT_WINDOWS = 1 << 7;
 
+    /** The container is an input-method window. */
+    public static final int FLAG_IS_INPUT_METHOD = 1 << 8;
+
     /** The first unused bit. This can be used by remotes to attach custom flags to this change. */
-    public static final int FLAG_FIRST_CUSTOM = 1 << 8;
+    public static final int FLAG_FIRST_CUSTOM = 1 << 9;
 
     /** @hide */
     @IntDef(prefix = { "FLAG_" }, value = {
@@ -121,6 +124,7 @@
             FLAG_IS_DISPLAY,
             FLAG_OCCLUDES_KEYGUARD,
             FLAG_DISPLAY_HAS_ALERT_WINDOWS,
+            FLAG_IS_INPUT_METHOD,
             FLAG_FIRST_CUSTOM
     })
     public @interface ChangeFlags {}
@@ -300,6 +304,9 @@
         if ((flags & FLAG_IS_WALLPAPER) != 0) {
             sb.append("IS_WALLPAPER");
         }
+        if ((flags & FLAG_IS_INPUT_METHOD) != 0) {
+            sb.append("IS_INPUT_METHOD");
+        }
         if ((flags & FLAG_TRANSLUCENT) != 0) {
             sb.append((sb.length() == 0 ? "" : "|") + "TRANSLUCENT");
         }
diff --git a/core/java/android/window/TransitionRequestInfo.java b/core/java/android/window/TransitionRequestInfo.java
index 48211a8..1404694 100644
--- a/core/java/android/window/TransitionRequestInfo.java
+++ b/core/java/android/window/TransitionRequestInfo.java
@@ -16,6 +16,8 @@
 
 package android.window;
 
+import static android.view.WindowManager.transitTypeToString;
+
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.WindowConfiguration;
@@ -366,7 +368,7 @@
         // String fieldNameToString() { ... }
 
         return "TransitionRequestInfo { " +
-                "type = " + mType + ", " +
+                "type = " + transitTypeToString(mType) + ", " +
                 "triggerTask = " + mTriggerTask + ", " +
                 "remoteTransition = " + mRemoteTransition + ", " +
                 "displayChange = " + mDisplayChange +
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 7dc039d..a87b91d 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -384,16 +384,27 @@
      */
     @NonNull
     public WindowContainerTransaction setAdjacentRoots(
-            @NonNull WindowContainerToken root1, @NonNull WindowContainerToken root2,
-            boolean moveTogether) {
+            @NonNull WindowContainerToken root1, @NonNull WindowContainerToken root2) {
         mHierarchyOps.add(HierarchyOp.createForAdjacentRoots(
                 root1.asBinder(),
-                root2.asBinder(),
-                moveTogether));
+                root2.asBinder()));
         return this;
     }
 
     /**
+     * This is temp function for compatible with old cts tests suite and it equal to
+     * {@link #setAdjacentRoots(WindowContainerToken, WindowContainerToken).
+     * @deprecated should use {@link #setAdjacentRoots(WindowContainerToken, WindowContainerToken)}
+     */
+    @Deprecated
+    @NonNull
+    public WindowContainerTransaction setAdjacentRoots(
+            @NonNull WindowContainerToken root1, @NonNull WindowContainerToken root2,
+            boolean moveTogether) {
+        return setAdjacentRoots(root1, root2);
+    }
+
+    /**
      * Sets the container as launch adjacent flag root. Task starting with
      * {@link FLAG_ACTIVITY_LAUNCH_ADJACENT} will be launching to.
      */
@@ -1106,9 +1117,6 @@
 
         private boolean mReparentTopOnly;
 
-        // TODO(b/207185041): Remove this once having a single-top root for split screen.
-        private boolean mMoveAdjacentTogether;
-
         @Nullable
         private int[]  mWindowingModes;
 
@@ -1171,12 +1179,10 @@
         }
 
         /** Create a hierarchy op for setting adjacent root tasks. */
-        public static HierarchyOp createForAdjacentRoots(IBinder root1, IBinder root2,
-                boolean moveTogether) {
+        public static HierarchyOp createForAdjacentRoots(IBinder root1, IBinder root2) {
             return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS)
                     .setContainer(root1)
                     .setReparentContainer(root2)
-                    .setMoveAdjacentTogether(moveTogether)
                     .build();
         }
 
@@ -1223,7 +1229,6 @@
             mInsetsProviderFrame = copy.mInsetsProviderFrame;
             mToTop = copy.mToTop;
             mReparentTopOnly = copy.mReparentTopOnly;
-            mMoveAdjacentTogether = copy.mMoveAdjacentTogether;
             mWindowingModes = copy.mWindowingModes;
             mActivityTypes = copy.mActivityTypes;
             mLaunchOptions = copy.mLaunchOptions;
@@ -1245,7 +1250,6 @@
             }
             mToTop = in.readBoolean();
             mReparentTopOnly = in.readBoolean();
-            mMoveAdjacentTogether = in.readBoolean();
             mWindowingModes = in.createIntArray();
             mActivityTypes = in.createIntArray();
             mLaunchOptions = in.readBundle();
@@ -1300,10 +1304,6 @@
             return mReparentTopOnly;
         }
 
-        public boolean getMoveAdjacentTogether() {
-            return mMoveAdjacentTogether;
-        }
-
         public int[] getWindowingModes() {
             return mWindowingModes;
         }
@@ -1356,8 +1356,7 @@
                     return "{reorder: " + mContainer + " to " + (mToTop ? "top" : "bottom") + "}";
                 case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS:
                     return "{SetAdjacentRoot: container=" + mContainer
-                            + " adjacentRoot=" + mReparent + " mMoveAdjacentTogether="
-                            + mMoveAdjacentTogether + "}";
+                            + " adjacentRoot=" + mReparent + "}";
                 case HIERARCHY_OP_TYPE_LAUNCH_TASK:
                     return "{LaunchTask: " + mLaunchOptions + "}";
                 case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT:
@@ -1413,7 +1412,6 @@
             }
             dest.writeBoolean(mToTop);
             dest.writeBoolean(mReparentTopOnly);
-            dest.writeBoolean(mMoveAdjacentTogether);
             dest.writeIntArray(mWindowingModes);
             dest.writeIntArray(mActivityTypes);
             dest.writeBundle(mLaunchOptions);
@@ -1458,8 +1456,6 @@
 
             private boolean mReparentTopOnly;
 
-            private boolean mMoveAdjacentTogether;
-
             @Nullable
             private int[]  mWindowingModes;
 
@@ -1515,11 +1511,6 @@
                 return this;
             }
 
-            Builder setMoveAdjacentTogether(boolean moveAdjacentTogether) {
-                mMoveAdjacentTogether = moveAdjacentTogether;
-                return this;
-            }
-
             Builder setWindowingModes(@Nullable int[] windowingModes) {
                 mWindowingModes = windowingModes;
                 return this;
@@ -1570,7 +1561,6 @@
                 hierarchyOp.mInsetsProviderFrame = mInsetsProviderFrame;
                 hierarchyOp.mToTop = mToTop;
                 hierarchyOp.mReparentTopOnly = mReparentTopOnly;
-                hierarchyOp.mMoveAdjacentTogether = mMoveAdjacentTogether;
                 hierarchyOp.mLaunchOptions = mLaunchOptions;
                 hierarchyOp.mActivityIntent = mActivityIntent;
                 hierarchyOp.mPendingIntent = mPendingIntent;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 66abe30..1dedec3 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1002,6 +1002,7 @@
 
         mShouldDisplayLandscape = shouldDisplayLandscape(newConfig.orientation);
         mMaxTargetsPerRow = getResources().getInteger(R.integer.config_chooser_max_targets_per_row);
+        mChooserMultiProfilePagerAdapter.setMaxTargetsPerRow(mMaxTargetsPerRow);
         adjustPreviewWidth(newConfig.orientation, null);
         updateStickyContentPreview();
         updateTabPadding();
diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
index e6cc624..df1130b 100644
--- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
@@ -93,6 +93,10 @@
         return profileDescriptor;
     }
 
+    public void setMaxTargetsPerRow(int maxTargetsPerRow) {
+        mMaxTargetsPerRow = maxTargetsPerRow;
+    }
+
     RecyclerView getListViewForIndex(int index) {
         return getItem(index).recyclerView;
     }
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 65e7abf..22340c6 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -53,6 +53,7 @@
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_QS_TILE;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_DIALOG_OPEN;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_EXPAND_COLLAPSE_LOCK;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_DISAPPEAR;
@@ -74,7 +75,10 @@
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TAKE_SCREENSHOT;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_COLLAPSE;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_EXPAND;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__UNFOLD_ANIM;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_DIALOG_OPEN;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_SWITCH;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__VOLUME_CONTROL;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__WALLPAPER_TRANSITION;
@@ -202,6 +206,10 @@
     public static final int CUJ_VOLUME_CONTROL = 55;
     public static final int CUJ_BIOMETRIC_PROMPT_TRANSITION = 56;
     public static final int CUJ_SETTINGS_TOGGLE = 57;
+    public static final int CUJ_SHADE_DIALOG_OPEN = 58;
+    public static final int CUJ_USER_DIALOG_OPEN = 59;
+    public static final int CUJ_TASKBAR_EXPAND = 60;
+    public static final int CUJ_TASKBAR_COLLAPSE = 61;
 
     private static final int NO_STATSD_LOGGING = -1;
 
@@ -268,6 +276,10 @@
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__VOLUME_CONTROL,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__BIOMETRIC_PROMPT_TRANSITION,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_TOGGLE,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_DIALOG_OPEN,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_DIALOG_OPEN,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_EXPAND,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_COLLAPSE,
     };
 
     private static volatile InteractionJankMonitor sInstance;
@@ -346,6 +358,10 @@
             CUJ_VOLUME_CONTROL,
             CUJ_BIOMETRIC_PROMPT_TRANSITION,
             CUJ_SETTINGS_TOGGLE,
+            CUJ_SHADE_DIALOG_OPEN,
+            CUJ_USER_DIALOG_OPEN,
+            CUJ_TASKBAR_EXPAND,
+            CUJ_TASKBAR_COLLAPSE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CujType {
@@ -780,6 +796,14 @@
                 return "BIOMETRIC_PROMPT_TRANSITION";
             case CUJ_SETTINGS_TOGGLE:
                 return "SETTINGS_TOGGLE";
+            case CUJ_SHADE_DIALOG_OPEN:
+                return "SHADE_DIALOG_OPEN";
+            case CUJ_USER_DIALOG_OPEN:
+                return "USER_DIALOG_OPEN";
+            case CUJ_TASKBAR_EXPAND:
+                return "TASKBAR_EXPAND";
+            case CUJ_TASKBAR_COLLAPSE:
+                return "TASKBAR_COLLAPSE";
         }
         return "UNKNOWN";
     }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index ea5797d..13bf643 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -42,6 +42,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 
 import static com.android.internal.policy.PhoneWindow.FEATURE_OPTIONS_PANEL;
 
@@ -309,6 +310,7 @@
                 R.integer.dock_enter_exit_duration);
         mForceWindowDrawsBarBackgrounds = context.getResources().getBoolean(
                 R.bool.config_forceWindowDrawsStatusBarBackground)
+                && params.type != TYPE_INPUT_METHOD
                 && context.getApplicationInfo().targetSdkVersion >= N;
         mSemiTransparentBarColor = context.getResources().getColor(
                 R.color.system_bar_background_semi_transparent, null /* theme */);
@@ -1164,8 +1166,8 @@
                     0 /* sideInset */, animate && !disallowAnimate,
                     mForceWindowDrawsBarBackgrounds, controller);
             boolean oldDrawLegacy = mDrawLegacyNavigationBarBackground;
-            mDrawLegacyNavigationBarBackground = mNavigationColorViewState.visible
-                    && (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
+            mDrawLegacyNavigationBarBackground =
+                    (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
             if (oldDrawLegacy != mDrawLegacyNavigationBarBackground) {
                 mDrawLegacyNavigationBarBackgroundHandled =
                         mWindow.onDrawLegacyNavigationBarBackgroundChanged(
@@ -1206,7 +1208,8 @@
         boolean hideNavigation = (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
                 || !(controller == null || controller.isRequestedVisible(ITYPE_NAVIGATION_BAR));
         boolean decorFitsSystemWindows = mWindow.mDecorFitsSystemWindows;
-        boolean forceConsumingNavBar = (mForceWindowDrawsBarBackgrounds
+        boolean forceConsumingNavBar =
+                ((mForceWindowDrawsBarBackgrounds || mDrawLegacyNavigationBarBackgroundHandled)
                         && (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
                         && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
                         && decorFitsSystemWindows
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 9c0fad9..fb38bba 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -915,6 +915,12 @@
             }
         }
 
+        if (!st.hasPanelItems()) {
+            // Ensure that |st.decorView| has its actual content. Otherwise, an empty window can be
+            // created and cause ANR.
+            return;
+        }
+
         st.isHandled = false;
 
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
index 377dfd0..295dc54 100644
--- a/core/java/com/android/internal/policy/TransitionAnimation.java
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -25,6 +25,7 @@
 import static android.view.WindowManager.TRANSIT_OLD_NONE;
 import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN;
+import static android.view.WindowManager.TRANSIT_OLD_UNSET;
 import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_CLOSE;
 import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_OPEN;
 import static android.view.WindowManager.TRANSIT_OPEN;
@@ -258,11 +259,17 @@
         }
         return null;
     }
-
-    /** Load animation by attribute Id from a specific AnimationStyle resource. */
+    /**
+     * Load animation by attribute Id from a specific AnimationStyle resource.
+     *
+     * @param translucent {@code true} if we're sure that the animation is applied on a translucent
+     *                    window container, {@code false} otherwise.
+     * @param transit {@link TransitionOldType} for the app transition of this animation, or
+     *                {@link TransitionOldType#TRANSIT_OLD_UNSET} if app transition type is unknown.
+     */
     @Nullable
-    public Animation loadAnimationAttr(String packageName, int animStyleResId, int animAttr,
-            boolean translucent) {
+    private Animation loadAnimationAttr(String packageName, int animStyleResId, int animAttr,
+            boolean translucent, @TransitionOldType int transit) {
         if (animStyleResId == 0) {
             return null;
         }
@@ -278,6 +285,8 @@
         }
         if (translucent) {
             resId = updateToTranslucentAnimIfNeeded(resId);
+        } else if (transit != TRANSIT_OLD_UNSET) {
+            resId = updateToTranslucentAnimIfNeeded(resId, transit);
         }
         if (ResourceId.isValid(resId)) {
             return loadAnimationSafely(context, resId, mTag);
@@ -285,6 +294,15 @@
         return null;
     }
 
+
+    /** Load animation by attribute Id from a specific AnimationStyle resource. */
+    @Nullable
+    public Animation loadAnimationAttr(String packageName, int animStyleResId, int animAttr,
+            boolean translucent) {
+        return loadAnimationAttr(packageName, animStyleResId, animAttr, translucent,
+                TRANSIT_OLD_UNSET);
+    }
+
     /** Load animation by attribute Id from android package. */
     @Nullable
     public Animation loadDefaultAnimationAttr(int animAttr, boolean translucent) {
@@ -292,6 +310,13 @@
                 translucent);
     }
 
+    /** Load animation by attribute Id from android package. */
+    @Nullable
+    public Animation loadDefaultAnimationAttr(int animAttr, @TransitionOldType int transit) {
+        return loadAnimationAttr(DEFAULT_PACKAGE, mDefaultWindowAnimationStyleResId, animAttr,
+                false /* translucent */, transit);
+    }
+
     @Nullable
     private AttributeCache.Entry getCachedAnimations(LayoutParams lp) {
         if (mDebug) {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index f388fec..b1610d7 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -580,6 +580,11 @@
     transaction->setEarlyWakeupEnd();
 }
 
+static jlong nativeGetTransactionId(JNIEnv* env, jclass clazz, jlong transactionObj) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    return transaction->getId();
+}
+
 static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
         jlong nativeObject, jint zorder) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -2103,6 +2108,8 @@
             (void*)nativeSetEarlyWakeupStart },
     {"nativeSetEarlyWakeupEnd", "(J)V",
             (void*)nativeSetEarlyWakeupEnd },
+    {"nativeGetTransactionId", "(J)J",
+                (void*)nativeGetTransactionId },
     {"nativeSetLayer", "(JJI)V",
             (void*)nativeSetLayer },
     {"nativeSetRelativeLayer", "(JJJI)V",
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 152d729..92ac389 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -116,6 +116,7 @@
     repeated KeyguardOccludedProto keyguard_occluded_states = 2 [deprecated=true];
     optional bool aod_showing = 3;
     repeated KeyguardPerDisplayProto keyguard_per_display = 4;
+    optional bool keyguard_going_away = 5;
 }
 
 message KeyguardOccludedProto {
@@ -132,6 +133,7 @@
     optional bool keyguard_showing = 2;
     optional bool aod_showing = 3;
     optional bool keyguard_occluded = 4;
+    optional bool keyguard_going_away = 5;
 }
 
 /* represents PhoneWindowManager */
diff --git a/core/proto/android/server/windowmanagertransitiontrace.proto b/core/proto/android/server/windowmanagertransitiontrace.proto
new file mode 100644
index 0000000..4161f65
--- /dev/null
+++ b/core/proto/android/server/windowmanagertransitiontrace.proto
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package com.android.server.wm.shell;
+
+import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
+
+option java_multiple_files = true;
+
+/* Represents a file full of transition entries.
+   Encoded, it should start with 0x9 0x57 0x49 0x4e 0x54 0x52 0x41 0x43 0x45 (.TRNTRACE), such
+   that it can be easily identified. */
+message TransitionTraceProto {
+
+  /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L
+     (this is needed because enums have to be 32 bits and there's no nice way to put 64bit
+      constants into .proto files. */
+  enum MagicNumber {
+    INVALID = 0;
+    MAGIC_NUMBER_L = 0x544e5254;  /* TRNT (little-endian ASCII) */
+    MAGIC_NUMBER_H = 0x45434152;  /* RACE (little-endian ASCII) */
+  }
+
+  fixed64 magic_number = 1;  /* Must be the first field, set to value in MagicNumber */
+  int64 timestamp = 2; /* The timestamp of when the trace was started. */
+  repeated Transition transition = 3;
+}
+
+message Transition {
+
+  enum State {
+    COLLECTING = 0;
+    PENDING = -1;
+    STARTED = 1;
+    PLAYING = 2;
+    ABORT = 3;
+    FINISHED = 4;
+  }
+
+  int32 id = 1;
+  int32 transition_type = 2;
+  int64 timestamp = 3;
+  State state = 5;
+  int32 flags = 6;
+  repeated ChangeInfo change = 7;
+  uint64 start_transaction_id = 8;
+  uint64 finish_transaction_id = 9;
+}
+
+message ChangeInfo {
+  com.android.server.wm.IdentifierProto window_identifier = 1;
+  int32 transit_mode = 2;
+  bool has_changed = 3;
+  int32 change_flags = 4;
+}
diff --git a/core/res/res/anim-ldrtl/task_fragment_clear_top_close_enter.xml b/core/res/res/anim-ldrtl/task_fragment_clear_top_close_enter.xml
new file mode 100644
index 0000000..6c44bdc0
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_fragment_clear_top_close_enter.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false"
+     android:showBackdrop="true">
+    <alpha
+        android:fromAlpha="0.0"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="100"
+        android:duration="350" />
+
+    <translate
+        android:fromXDelta="5%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_fragment_clear_top_close_exit.xml b/core/res/res/anim-ldrtl/task_fragment_clear_top_close_exit.xml
new file mode 100644
index 0000000..65cf2c2c
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_fragment_clear_top_close_exit.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false">
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="0.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="0"
+        android:duration="100" />
+
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="-25%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_fragment_clear_top_open_enter.xml b/core/res/res/anim-ldrtl/task_fragment_clear_top_open_enter.xml
new file mode 100644
index 0000000..022bc22
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_fragment_clear_top_open_enter.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false"
+     android:showBackdrop="true">
+    <alpha
+        android:fromAlpha="0.0"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="100"
+        android:duration="350" />
+
+    <translate
+        android:fromXDelta="-5%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="450" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_fragment_clear_top_open_exit.xml b/core/res/res/anim-ldrtl/task_fragment_clear_top_open_exit.xml
new file mode 100644
index 0000000..3644dea
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_fragment_clear_top_open_exit.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false">
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="0.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/standard_accelerate"
+        android:startOffset="0"
+        android:duration="100" />
+
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="25%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="450" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_fragment_open_enter.xml b/core/res/res/anim-ldrtl/task_fragment_open_enter.xml
index b6f1af3..9e3780a 100644
--- a/core/res/res/anim-ldrtl/task_fragment_open_enter.xml
+++ b/core/res/res/anim-ldrtl/task_fragment_open_enter.xml
@@ -17,7 +17,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-     android:shareInterpolator="false">
+    android:shareInterpolator="false">
 
     <alpha
         android:fromAlpha="0"
diff --git a/core/res/res/anim/task_fragment_clear_top_close_enter.xml b/core/res/res/anim/task_fragment_clear_top_close_enter.xml
new file mode 100644
index 0000000..e33f718
--- /dev/null
+++ b/core/res/res/anim/task_fragment_clear_top_close_enter.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false"
+     android:showBackdrop="true">
+    <alpha
+        android:fromAlpha="0.0"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/standard_decelerate"
+        android:startOffset="100"
+        android:duration="350" />
+
+    <translate
+        android:fromXDelta="-5%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_fragment_clear_top_close_exit.xml b/core/res/res/anim/task_fragment_clear_top_close_exit.xml
new file mode 100644
index 0000000..3d274ba9
--- /dev/null
+++ b/core/res/res/anim/task_fragment_clear_top_close_exit.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false">
+
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="0.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/standard_accelerate"
+        android:startOffset="0"
+        android:duration="100" />
+
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="25%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_fragment_clear_top_open_enter.xml b/core/res/res/anim/task_fragment_clear_top_open_enter.xml
new file mode 100644
index 0000000..b963661
--- /dev/null
+++ b/core/res/res/anim/task_fragment_clear_top_open_enter.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false"
+     android:showBackdrop="true">
+
+    <alpha
+        android:fromAlpha="0.0"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/standard_decelerate"
+        android:startOffset="100"
+        android:duration="350" />
+
+    <translate
+        android:fromXDelta="5%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:startOffset="0"
+        android:duration="450" />
+
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_fragment_clear_top_open_exit.xml b/core/res/res/anim/task_fragment_clear_top_open_exit.xml
new file mode 100644
index 0000000..22be7d1
--- /dev/null
+++ b/core/res/res/anim/task_fragment_clear_top_open_exit.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false">
+
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="0.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/standard_accelerate"
+        android:startOffset="0"
+        android:duration="100" />
+
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="-25%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="450" />
+
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_fragment_open_enter.xml b/core/res/res/anim/task_fragment_open_enter.xml
index aa61e6f..87ee179 100644
--- a/core/res/res/anim/task_fragment_open_enter.xml
+++ b/core/res/res/anim/task_fragment_open_enter.xml
@@ -16,7 +16,7 @@
    -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shareInterpolator="false">
+     android:shareInterpolator="false">
     <alpha
         android:fromAlpha="0"
         android:toAlpha="1.0"
diff --git a/core/res/res/anim/task_fragment_open_exit.xml b/core/res/res/anim/task_fragment_open_exit.xml
index b4914d2..55a472d 100644
--- a/core/res/res/anim/task_fragment_open_exit.xml
+++ b/core/res/res/anim/task_fragment_open_exit.xml
@@ -32,5 +32,5 @@
         android:fillBefore="true"
         android:fillAfter="true"
         android:interpolator="@interpolator/fast_out_extra_slow_in"
-        android:duration="400" />
-</set>
\ No newline at end of file
+        android:duration="400"/>
+</set>
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index 0756d68..fd787f6 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -138,7 +138,7 @@
 
         </LinearLayout>
 
-        <ImageView
+        <com.android.internal.widget.CachingIconView
             android:id="@+id/right_icon"
             android:layout_width="@dimen/notification_right_icon_size"
             android:layout_height="@dimen/notification_right_icon_size"
@@ -150,6 +150,8 @@
             android:clipToOutline="true"
             android:importantForAccessibility="no"
             android:scaleType="centerCrop"
+            android:maxDrawableWidth="@dimen/notification_right_icon_size"
+            android:maxDrawableHeight="@dimen/notification_right_icon_size"
             />
 
         <FrameLayout
diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml
index f163ed5..8b3b795 100644
--- a/core/res/res/layout/notification_template_right_icon.xml
+++ b/core/res/res/layout/notification_template_right_icon.xml
@@ -13,7 +13,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-<ImageView
+<com.android.internal.widget.CachingIconView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/right_icon"
     android:layout_width="@dimen/notification_right_icon_size"
@@ -25,4 +25,6 @@
     android:clipToOutline="true"
     android:importantForAccessibility="no"
     android:scaleType="centerCrop"
+    android:maxDrawableWidth="@dimen/notification_right_icon_size"
+    android:maxDrawableHeight="@dimen/notification_right_icon_size"
     />
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 83c30bb..f63dfef 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1041,9 +1041,9 @@
     <string name="permlab_readHistoryBookmarks" msgid="9102293913842539697">"lese nettbokmerkene og nettloggen din"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="2323799501008967852">"Lar appen lese loggen for alle nettadressene nettleseren har besøkt, og alle bokmerkene i nettleseren. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="6090259925187986937">"skrive nettbokmerker og nettlogg"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Lar appen endre nettleserens logg eller bokmerker lagret på nettbrettet ditt. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Lar appen endre nettleserens logg eller bokmerker som er lagret på Android TV-enheten din. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettlesingsdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="573341025292489065">"Lar appen endre nettleserens logg eller bokmerker lagret på nettbrettet ditt. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="88642768580408561">"Lar appen endre nettleserens logg eller bokmerker som er lagret på Android TV-enheten din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="2245203087160913652">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
     <string name="permlab_setAlarm" msgid="1158001610254173567">"stille alarm"</string>
     <string name="permdesc_setAlarm" msgid="2185033720060109640">"Lar appen stille inn alarmen for en installert alarmklokke-app. Enkelte alarmklokke-apper implementerer kanskje ikke denne funksjonen."</string>
     <string name="permlab_addVoicemail" msgid="4770245808840814471">"legge til talepost"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d2f31b0..515ea50 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2422,6 +2422,15 @@
         <!--  When closing the current activity, this is the animation that is
               run on the current activity (which is exiting the screen). -->
         <attr name="activityCloseExitAnimation" format="reference" />
+        <!--  When closing a dream activity, this is the animation that is
+              run on the dream activity (which is exiting the screen). -->
+        <attr name="dreamActivityCloseExitAnimation" format="reference" />
+        <!--  When opening a dream activity, this is the animation that is
+              run on the dream activity (which is entering the screen). -->
+        <attr name="dreamActivityOpenEnterAnimation" format="reference" />
+        <!--  When opening a dream activity, this is the animation that is
+              run on the old activity (which is exiting the screen). -->
+        <attr name="dreamActivityOpenExitAnimation" format="reference" />
         <!--  When opening an activity in a new task, this is the animation that is
               run on the activity of the new task (which is entering the screen). -->
         <attr name="taskOpenEnterAnimation" format="reference" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 31229e9..a8c7bf2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2030,6 +2030,10 @@
          STREAM_MUSIC as if it's on TV platform. -->
     <bool name="config_single_volume">false</bool>
 
+    <!-- Flag indicating whether notification and ringtone volumes
+         are controlled together (aliasing is true) or not. -->
+    <bool name="config_alias_ring_notif_stream_types">true</bool>
+
     <!-- Flag indicating whether platform level volume adjustments are enabled for remote sessions
          on grouped devices. -->
     <bool name="config_volumeAdjustmentForRemoteGroupSessions">true</bool>
@@ -3755,6 +3759,9 @@
          "Guest" and "Reset guest". -->
     <bool name="config_guestUserAutoCreated">false</bool>
 
+    <!-- If true, owner can change guest user ephemeral state via UI option -->
+    <bool name="config_guestUserAllowEphemeralStateChange">true</bool>
+
     <!-- Enforce strong auth on boot. Setting this to false represents a security risk and should
          not be ordinarily done. The only case in which this might be permissible is in a car head
          unit where there are hardware mechanisms to protect the device (physical keys) and not
@@ -5133,16 +5140,24 @@
      -->
     <color name="config_letterboxBackgroundColor">@android:color/system_neutral2_900</color>
 
-    <!-- Horizonal position of a center of the letterboxed app window.
+    <!-- Horizontal position of a center of the letterboxed app window.
         0 corresponds to the left side of the screen and 1 to the right side. If given value < 0
-        or > 1, it is ignored and central positionis used (0.5). -->
+        or > 1, it is ignored and central position is used (0.5). -->
     <item name="config_letterboxHorizontalPositionMultiplier" format="float" type="dimen">0.5</item>
 
-    <!-- Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape
-        device orientation. -->
-    <bool name="config_letterboxIsReachabilityEnabled">false</bool>
+    <!-- Vertical position of a center of the letterboxed app window.
+        0 corresponds to the upper side of the screen and 1 to the lower side. If given value < 0
+        or > 1, it is ignored and central position is used (0.5). -->
+    <item name="config_letterboxVerticalPositionMultiplier" format="float" type="dimen">0.5</item>
 
-    <!-- Default horizonal position of the letterboxed app window when reachability is
+    <!-- Whether horizontal reachability repositioning is allowed for letterboxed fullscreen apps.
+    -->
+    <bool name="config_letterboxIsHorizontalReachabilityEnabled">false</bool>
+
+    <!-- Whether vertical reachability repositioning is allowed for letterboxed fullscreen apps. -->
+    <bool name="config_letterboxIsVerticalReachabilityEnabled">false</bool>
+
+    <!-- Default horizontal position of the letterboxed app window when reachability is
         enabled and an app is fullscreen in landscape device orientation. When reachability is
         enabled, the position can change between left, center and right. This config defines the
         default one:
@@ -5150,11 +5165,30 @@
             - Option 1 - Center.
             - Option 2 - Right.
         If given value is outside of this range, the option 1 (center) is assummed. -->
-    <integer name="config_letterboxDefaultPositionForReachability">1</integer>
+    <integer name="config_letterboxDefaultPositionForHorizontalReachability">1</integer>
+
+    <!-- Default vertical position of the letterboxed app window when reachability is
+        enabled and an app is fullscreen in portrait device orientation. When reachability is
+        enabled, the position can change between top, center and bottom. This config defines the
+        default one:
+            - Option 0 - Top.
+            - Option 1 - Center.
+            - Option 2 - Bottom.
+        If given value is outside of this range, the option 1 (center) is assummed. -->
+    <integer name="config_letterboxDefaultPositionForVerticalReachability">1</integer>
 
     <!-- Whether displaying letterbox education is enabled for letterboxed fullscreen apps. -->
     <bool name="config_letterboxIsEducationEnabled">false</bool>
 
+    <!-- Default min aspect ratio for unresizable apps which are eligible for size compat mode.
+         Values <= 1.0 will be ignored. Activity min/max aspect ratio restrictions will still be
+         espected so this override can control the maximum screen area that can be occupied by
+         the app in the letterbox mode. -->
+    <item name="config_letterboxDefaultMinAspectRatioForUnresizableApps" format="float" type="dimen">0.0</item>
+
+    <!-- Whether using split screen aspect ratio as a default aspect ratio for unresizable apps. -->
+    <bool name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled">false</bool>
+
     <!-- Whether a camera compat controller is enabled to allow the user to apply or revert
          treatment for stretched issues in camera viewfinder. -->
     <bool name="config_isCameraCompatControlForStretchedIssuesEnabled">false</bool>
@@ -5816,4 +5850,7 @@
     <string-array name="config_serviceStateLocationAllowedPackages">
         <item>"com.android.phone"</item>
     </string-array>
+
+    <!-- Whether the wake screen on notifications feature is available. -->
+    <bool name="config_pulseOnNotificationsAvailable">true</bool>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 5d17047..bad05e0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -85,6 +85,9 @@
         <item name="activityOpenExitAnimation">@anim/activity_open_exit</item>
         <item name="activityCloseEnterAnimation">@anim/activity_close_enter</item>
         <item name="activityCloseExitAnimation">@anim/activity_close_exit</item>
+        <item name="dreamActivityCloseExitAnimation">@anim/dream_activity_close_exit</item>
+        <item name="dreamActivityOpenEnterAnimation">@anim/dream_activity_open_enter</item>
+        <item name="dreamActivityOpenExitAnimation">@anim/dream_activity_open_exit</item>
         <item name="taskOpenEnterAnimation">@anim/task_open_enter</item>
         <item name="taskOpenExitAnimation">@anim/task_open_exit</item>
         <item name="launchTaskBehindTargetAnimation">@anim/launch_task_behind_target</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a8258118..1438e7f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -273,6 +273,7 @@
   <java-symbol type="attr" name="autofillSaveCustomSubtitleMaxHeight"/>
   <java-symbol type="bool" name="action_bar_embed_tabs" />
   <java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" />
+  <java-symbol type="bool" name="config_alias_ring_notif_stream_types" />
   <java-symbol type="bool" name="config_avoidGfxAccel" />
   <java-symbol type="bool" name="config_bluetooth_address_validation" />
   <java-symbol type="integer" name="config_chooser_max_targets_per_row" />
@@ -394,6 +395,7 @@
   <java-symbol type="bool" name="config_supportsInsecureLockScreen" />
   <java-symbol type="bool" name="config_guestUserEphemeral" />
   <java-symbol type="bool" name="config_guestUserAutoCreated" />
+  <java-symbol type="bool" name="config_guestUserAllowEphemeralStateChange" />
   <java-symbol type="bool" name="config_localDisplaysMirrorContent" />
   <java-symbol type="array" name="config_localPrivateDisplayPorts" />
   <java-symbol type="integer" name="config_defaultDisplayDefaultColorMode" />
@@ -1704,6 +1706,10 @@
   <java-symbol type="anim" name="task_fragment_close_exit" />
   <java-symbol type="anim" name="task_fragment_open_enter" />
   <java-symbol type="anim" name="task_fragment_open_exit" />
+  <java-symbol type="anim" name="task_fragment_clear_top_close_enter" />
+  <java-symbol type="anim" name="task_fragment_clear_top_close_exit" />
+  <java-symbol type="anim" name="task_fragment_clear_top_open_enter" />
+  <java-symbol type="anim" name="task_fragment_clear_top_open_exit" />
 
   <java-symbol type="array" name="config_autoRotationTiltTolerance" />
   <java-symbol type="array" name="config_longPressVibePattern" />
@@ -3336,6 +3342,7 @@
   <java-symbol type="string" name="config_dozeTapSensorType" />
   <java-symbol type="array" name="config_dozeTapSensorPostureMapping" />
   <java-symbol type="bool" name="config_dozePulsePickup" />
+  <java-symbol type="bool" name="config_pulseOnNotificationsAvailable" />
 
   <!-- Used for MimeIconUtils. -->
   <java-symbol type="drawable" name="ic_doc_apk" />
@@ -4387,9 +4394,14 @@
   <java-symbol type="integer" name="config_letterboxBackgroundType" />
   <java-symbol type="color" name="config_letterboxBackgroundColor" />
   <java-symbol type="dimen" name="config_letterboxHorizontalPositionMultiplier" />
-  <java-symbol type="bool" name="config_letterboxIsReachabilityEnabled" />
-  <java-symbol type="integer" name="config_letterboxDefaultPositionForReachability" />
+  <java-symbol type="dimen" name="config_letterboxVerticalPositionMultiplier" />
+  <java-symbol type="bool" name="config_letterboxIsHorizontalReachabilityEnabled" />
+  <java-symbol type="bool" name="config_letterboxIsVerticalReachabilityEnabled" />
+  <java-symbol type="integer" name="config_letterboxDefaultPositionForHorizontalReachability" />
+  <java-symbol type="integer" name="config_letterboxDefaultPositionForVerticalReachability" />
   <java-symbol type="bool" name="config_letterboxIsEducationEnabled" />
+  <java-symbol type="dimen" name="config_letterboxDefaultMinAspectRatioForUnresizableApps" />
+  <java-symbol type="bool" name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled" />
   <java-symbol type="bool" name="config_isCameraCompatControlForStretchedIssuesEnabled" />
 
   <java-symbol type="bool" name="config_hideDisplayCutoutWithDisplayArea" />
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index bfb2fd5..a2d4baf 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -31,7 +31,6 @@
 
 import android.annotation.Nullable;
 import android.app.Activity;
-import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.ActivityThread.ActivityClientRecord;
 import android.app.IApplicationThread;
@@ -571,53 +570,6 @@
     }
 
     @Test
-    public void testHandleProcessConfigurationChanged_DependOnProcessState() {
-        final ActivityThread activityThread = ActivityThread.currentActivityThread();
-        final Configuration origConfig = activityThread.getConfiguration();
-        final int newDpi = origConfig.densityDpi + 10;
-        final Configuration newConfig = new Configuration(origConfig);
-        newConfig.seq++;
-        newConfig.densityDpi = newDpi;
-
-        activityThread.updateProcessState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
-                false /* fromIPC */);
-
-        applyProcessConfiguration(activityThread, newConfig);
-        try {
-            // In the cached state, the configuration is only set as pending and not applied.
-            assertEquals(origConfig.densityDpi, activityThread.getConfiguration().densityDpi);
-            assertTrue(activityThread.isCachedProcessState());
-        } finally {
-            // The foreground state is the default state of instrumentation.
-            activityThread.updateProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
-                    false /* fromIPC */);
-        }
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-
-        try {
-            // The state becomes non-cached, the pending configuration should be applied.
-            assertEquals(newConfig.densityDpi, activityThread.getConfiguration().densityDpi);
-            assertFalse(activityThread.isCachedProcessState());
-        } finally {
-            // Restore to the original configuration.
-            activityThread.getConfiguration().seq = origConfig.seq - 1;
-            applyProcessConfiguration(activityThread, origConfig);
-        }
-    }
-
-    private static void applyProcessConfiguration(ActivityThread thread, Configuration config) {
-        final ClientTransaction clientTransaction = newTransaction(thread,
-                null /* activityToken */);
-        clientTransaction.addCallback(ConfigurationChangeItem.obtain(config));
-        final IApplicationThread appThread = thread.getApplicationThread();
-        try {
-            appThread.scheduleTransaction(clientTransaction);
-        } catch (Exception ignored) {
-        }
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-    }
-
-    @Test
     public void testResumeAfterNewIntent() {
         final Activity activity = mActivityTestRule.launchActivity(new Intent());
         final ActivityThread activityThread = activity.getActivityThread();
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index c504f0c..dcb1835 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -214,19 +214,23 @@
     }
 
     @Test
-    public void testFrameDoesntMatchDisplay() {
-        mController.onFrameChanged(new Rect(0, 0, 100, 100));
-        mController.getState().setDisplayFrame(new Rect(0, 0, 200, 200));
-        InsetsSourceControl control =
-                new InsetsSourceControl(
-                        ITYPE_STATUS_BAR, mLeash, new Point(), Insets.of(0, 10, 0, 0));
-        mController.onControlsChanged(new InsetsSourceControl[] { control });
+    public void testFrameDoesntOverlapWithInsets() {
         WindowInsetsAnimationControlListener controlListener =
                 mock(WindowInsetsAnimationControlListener.class);
-        mController.controlWindowInsetsAnimation(0, 0 /* durationMs */, new LinearInterpolator(),
-                new CancellationSignal(), controlListener);
-        mController.addOnControllableInsetsChangedListener(
-                (controller, typeMask) -> assertEquals(0, typeMask));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            //  The frame doesn't overlap with status bar.
+            mController.onFrameChanged(new Rect(0, 10, 100, 100));
+
+            InsetsSourceControl control =
+                    new InsetsSourceControl(
+                            ITYPE_STATUS_BAR, mLeash, new Point(), Insets.of(0, 10, 0, 0));
+            mController.onControlsChanged(new InsetsSourceControl[]{control});
+            mController.controlWindowInsetsAnimation(0, 0 /* durationMs */,
+                    new LinearInterpolator(),
+                    new CancellationSignal(), controlListener);
+            mController.addOnControllableInsetsChangedListener(
+                    (controller, typeMask) -> assertEquals(0, typeMask));
+        });
         verify(controlListener).onCancelled(null);
         verify(controlListener, never()).onReady(any(), anyInt());
     }
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index b38e1c2..8214842 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -84,17 +84,23 @@
 import android.view.View;
 
 import androidx.annotation.CallSuper;
+import androidx.test.espresso.matcher.BoundedDiagnosingMatcher;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.rule.ActivityTestRule;
 
+import com.android.internal.R;
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
 import com.android.internal.app.chooser.DisplayResolveInfo;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.FrameworkStatsLog;
+import com.android.internal.widget.GridLayoutManager;
+import com.android.internal.widget.RecyclerView;
 
+import org.hamcrest.Description;
 import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Rule;
@@ -1680,6 +1686,25 @@
                 wrapper.getAdapter().getItem(1).getDisplayLabel(), is("testTitle1"));
     }
 
+    @Test
+    public void testUpdateMaxTargetsPerRow_columnCountIsUpdated() throws InterruptedException {
+        updateMaxTargetsPerRowResource(/* targetsPerRow= */ 4);
+        givenAppTargets(/* appCount= */ 16);
+        Intent sendIntent = createSendTextIntent();
+        final ChooserActivity activity =
+                mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+
+        updateMaxTargetsPerRowResource(/* targetsPerRow= */ 6);
+        InstrumentationRegistry.getInstrumentation()
+                .runOnMainSync(() -> activity.onConfigurationChanged(
+                        InstrumentationRegistry.getInstrumentation()
+                                .getContext().getResources().getConfiguration()));
+
+        waitForIdle();
+        onView(withIdFromRuntimeResource("resolver_list"))
+                .check(matches(withGridColumnCount(6)));
+    }
+
     // This test is too long and too slow and should not be taken as an example for future tests.
     @Test @Ignore
     public void testDirectTargetLoggingWithAppTargetNotRankedPortrait()
@@ -3063,6 +3088,64 @@
         return withText(getRuntimeResourceId(id, "string"));
     }
 
+    private static GridRecyclerSpanCountMatcher withGridColumnCount(int columnCount) {
+        return new GridRecyclerSpanCountMatcher(Matchers.is(columnCount));
+    }
+
+    private static class GridRecyclerSpanCountMatcher extends
+            BoundedDiagnosingMatcher<View, RecyclerView> {
+
+        private final Matcher<Integer> mIntegerMatcher;
+
+        private GridRecyclerSpanCountMatcher(Matcher<Integer> integerMatcher) {
+            super(RecyclerView.class);
+            this.mIntegerMatcher = integerMatcher;
+        }
+
+        @Override
+        protected void describeMoreTo(Description description) {
+            description.appendText("RecyclerView grid layout span count to match: ");
+            this.mIntegerMatcher.describeTo(description);
+        }
+
+        @Override
+        protected boolean matchesSafely(RecyclerView view, Description mismatchDescription) {
+            int spanCount = ((GridLayoutManager) view.getLayoutManager()).getSpanCount();
+            if (this.mIntegerMatcher.matches(spanCount)) {
+                return true;
+            } else {
+                mismatchDescription.appendText("RecyclerView grid layout span count was ")
+                        .appendValue(spanCount);
+                return false;
+            }
+        }
+    }
+
+    private void givenAppTargets(int appCount) {
+        List<ResolvedComponentInfo> resolvedComponentInfos =
+                createResolvedComponentsForTest(appCount);
+        when(
+                ChooserActivityOverrideData
+                        .getInstance()
+                        .resolverListController
+                        .getResolversForIntent(
+                                Mockito.anyBoolean(),
+                                Mockito.anyBoolean(),
+                                Mockito.isA(List.class)))
+                .thenReturn(resolvedComponentInfos);
+    }
+
+    private void updateMaxTargetsPerRowResource(int targetsPerRow) {
+        ChooserActivityOverrideData.getInstance().resources = Mockito.spy(
+                InstrumentationRegistry.getInstrumentation().getContext().getResources());
+        when(
+                ChooserActivityOverrideData
+                        .getInstance()
+                        .resources
+                        .getInteger(R.integer.config_chooser_max_targets_per_row))
+                .thenReturn(targetsPerRow);
+    }
+
     // ChooserWrapperActivity inherits from the framework ChooserActivity, so if the framework
     // resources have been updated since the framework was last built/pushed, the inherited behavior
     // (which is the focus of our testing) will still be implemented in terms of the old resource
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 8d3751e..47f70dd 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -207,8 +207,8 @@
         final Configuration currentConfig = new Configuration();
 
         assertFalse("Must not report change if no public diff",
-                shouldReportChange(0 /* publicDiff */, currentConfig, newConfig,
-                null /* sizeBuckets */, 0 /* handledConfigChanges */));
+                shouldReportChange(currentConfig, newConfig, null /* sizeBuckets */,
+                        0 /* handledConfigChanges */));
 
         final int[] verticalThresholds = {100, 400};
         final SizeConfigurationBuckets buckets = new SizeConfigurationBuckets(
@@ -221,25 +221,25 @@
         newConfig.screenHeightDp = 300;
 
         assertFalse("Must not report changes if the diff is small and not handled",
-                shouldReportChange(CONFIG_SCREEN_SIZE /* publicDiff */, currentConfig,
-                newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */));
+                shouldReportChange(currentConfig, newConfig, buckets,
+                        CONFIG_FONT_SCALE /* handledConfigChanges */));
 
         assertTrue("Must report changes if the small diff is handled",
-                shouldReportChange(CONFIG_SCREEN_SIZE /* publicDiff */, currentConfig, newConfig,
-                buckets, CONFIG_SCREEN_SIZE /* handledConfigChanges */));
+                shouldReportChange(currentConfig, newConfig, buckets,
+                        CONFIG_SCREEN_SIZE /* handledConfigChanges */));
 
         currentConfig.fontScale = 0.8f;
         newConfig.fontScale = 1.2f;
 
         assertTrue("Must report handled changes regardless of small unhandled change",
-                shouldReportChange(CONFIG_SCREEN_SIZE | CONFIG_FONT_SCALE /* publicDiff */,
-                currentConfig, newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */));
+                shouldReportChange(currentConfig, newConfig, buckets,
+                        CONFIG_FONT_SCALE /* handledConfigChanges */));
 
         newConfig.screenHeightDp = 500;
 
         assertFalse("Must not report changes if there's unhandled big changes",
-                shouldReportChange(CONFIG_SCREEN_SIZE | CONFIG_FONT_SCALE /* publicDiff */,
-                currentConfig, newConfig, buckets, CONFIG_FONT_SCALE /* handledConfigChanges */));
+                shouldReportChange(currentConfig, newConfig, buckets,
+                        CONFIG_FONT_SCALE /* handledConfigChanges */));
     }
 
     private void recreateAndVerifyNoRelaunch(ActivityThread activityThread, TestActivity activity) {
diff --git a/core/tests/mockingcoretests/src/android/window/SizeConfigurationBucketsTest.java b/core/tests/mockingcoretests/src/android/window/SizeConfigurationBucketsTest.java
index fa4aa80..ed857e8 100644
--- a/core/tests/mockingcoretests/src/android/window/SizeConfigurationBucketsTest.java
+++ b/core/tests/mockingcoretests/src/android/window/SizeConfigurationBucketsTest.java
@@ -88,26 +88,15 @@
     }
 
     /**
-     * Tests that null size configuration buckets unflips the correct configuration flags.
+     * Tests that {@code null} size configuration buckets do not unflip the configuration flags.
      */
     @Test
     public void testNullSizeConfigurationBuckets() {
-        // Check that all 3 size configurations are filtered out of the diff if the buckets are null
-        // and non-size attributes of screen layout are unchanged. Add a non-size related config
-        // change (i.e. CONFIG_LOCALE) to test that the diff is not set to zero.
         final int diff = CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_SCREEN_LAYOUT
                 | CONFIG_LOCALE;
         final int filteredDiffNonSizeLayoutUnchanged = SizeConfigurationBuckets.filterDiff(diff,
                 Configuration.EMPTY, Configuration.EMPTY, null);
-        assertEquals(CONFIG_LOCALE, filteredDiffNonSizeLayoutUnchanged);
-
-        // Check that only screen size and smallest screen size are filtered out of the diff if the
-        // buckets are null and non-size attributes of screen layout are changed.
-        final Configuration newConfig = new Configuration();
-        newConfig.screenLayout |= SCREENLAYOUT_ROUND_YES;
-        final int filteredDiffNonSizeLayoutChanged = SizeConfigurationBuckets.filterDiff(diff,
-                Configuration.EMPTY, newConfig, null);
-        assertEquals(CONFIG_SCREEN_LAYOUT | CONFIG_LOCALE, filteredDiffNonSizeLayoutChanged);
+        assertEquals(diff, filteredDiffNonSizeLayoutUnchanged);
     }
 
     /**
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index f7c2b73..6706e4e 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -163,6 +163,12 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-1941440781": {
+      "message": "Creating Pending Move-to-back: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/Task.java"
+    },
     "-1939861963": {
       "message": "Create root task displayId=%d winMode=%d",
       "level": "VERBOSE",
@@ -757,6 +763,12 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-1383884640": {
+      "message": " allReady query: used=%b override=%b defer=%d states=[%s]",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/Transition.java"
+    },
     "-1376035390": {
       "message": "No task found",
       "level": "DEBUG",
@@ -1693,6 +1705,12 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/RootWindowContainer.java"
     },
+    "-417730399": {
+      "message": "Preparing to sync a window that was already in the sync, so try dropping buffer. win=%s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_SYNC_ENGINE",
+      "at": "com\/android\/server\/wm\/WindowState.java"
+    },
     "-415865166": {
       "message": "findFocusedWindow: Found new focus @ %s",
       "level": "VERBOSE",
@@ -2071,6 +2089,12 @@
       "group": "WM_DEBUG_IME",
       "at": "com\/android\/server\/wm\/DisplayContent.java"
     },
+    "-57572004": {
+      "message": "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b  canCustomizeAppTransition=%b Callers=%s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+      "at": "com\/android\/server\/wm\/AppTransition.java"
+    },
     "-55185509": {
       "message": "setFocusedTask: taskId=%d touchedActivity=%s",
       "level": "DEBUG",
@@ -2113,6 +2137,12 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimation.java"
     },
+    "-4263657": {
+      "message": "Got a buffer for request id=%d but latest request is id=%d. Since the buffer is out-of-date, drop it. win=%s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_SYNC_ENGINE",
+      "at": "com\/android\/server\/wm\/WindowState.java"
+    },
     "3593205": {
       "message": "commitVisibility: %s: visible=%b mVisibleRequested=%b",
       "level": "VERBOSE",
@@ -2143,6 +2173,12 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
     },
+    "25888308": {
+      "message": "Resize reasons for w=%s:  %s configChanged=%b dragResizingChanged=%b",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_RESIZE",
+      "at": "com\/android\/server\/wm\/WindowState.java"
+    },
     "35398067": {
       "message": "goodToGo(): onAnimationStart, transit=%s, apps=%d, wallpapers=%d, nonApps=%d",
       "level": "DEBUG",
@@ -2527,12 +2563,6 @@
       "group": "WM_DEBUG_ADD_REMOVE",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
-    "352982444": {
-      "message": " allReady query: used=%b override=%b states=[%s]",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
     "355720268": {
       "message": "stopFreezingDisplayLocked: Unfreezing now",
       "level": "DEBUG",
@@ -2575,6 +2605,12 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/TaskFragment.java"
     },
+    "385237117": {
+      "message": "moveFocusableActivityToTop: already on top and focused, activity=%s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_FOCUS",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
+    },
     "385595355": {
       "message": "Starting animation on %s: type=%d, anim=%s",
       "level": "VERBOSE",
@@ -2797,12 +2833,6 @@
       "group": "WM_DEBUG_FOCUS_LIGHT",
       "at": "com\/android\/server\/wm\/DisplayContent.java"
     },
-    "625447638": {
-      "message": "Resize reasons for w=%s:  %s configChanged=%b dragResizingChanged=%b reportOrientationChanged=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_RESIZE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
     "628276090": {
       "message": "Delaying app transition for screen rotation animation to finish",
       "level": "VERBOSE",
@@ -3049,6 +3079,12 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/RootWindowContainer.java"
     },
+    "898260097": {
+      "message": "Creating Pending Pip-Enter: %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
+    },
     "898863925": {
       "message": "Attempted to add QS dialog window with unknown token %s.  Aborting.",
       "level": "WARN",
@@ -3379,11 +3415,11 @@
       "group": "WM_DEBUG_BOOT",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "1246035185": {
-      "message": "stopFreezingDisplayLocked: Returning waitingForConfig=%b, waitingForRemoteRotation=%b, mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, mClientFreezingScreen=%b, mOpeningApps.size()=%d",
+    "1239439010": {
+      "message": "moveFocusableActivityToTop: set focused, activity=%s",
       "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
+      "group": "WM_DEBUG_FOCUS",
+      "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
     "1252594551": {
       "message": "Window types in WindowContext and LayoutParams.type should match! Type from LayoutParams is %d, but type from WindowContext is %d",
@@ -3481,6 +3517,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
     },
+    "1360176455": {
+      "message": "stopFreezingDisplayLocked: Returning waitingForConfig=%b, waitingForRemoteDisplayChange=%b, mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, mClientFreezingScreen=%b, mOpeningApps.size()=%d",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_ORIENTATION",
+      "at": "com\/android\/server\/wm\/WindowManagerService.java"
+    },
     "1364126018": {
       "message": "Resumed activity; dropping state of: %s",
       "level": "INFO",
@@ -3505,6 +3547,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
     },
+    "1393721079": {
+      "message": "Starting remote display change: from [rot = %d], to [%dx%d, rot = %d]",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONFIGURATION",
+      "at": "com\/android\/server\/wm\/RemoteDisplayChangeController.java"
+    },
     "1396893178": {
       "message": "createRootTask unknown displayId=%d",
       "level": "ERROR",
@@ -3955,12 +4003,6 @@
       "group": "WM_DEBUG_STARTING_WINDOW",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
-    "1856211951": {
-      "message": "moveFocusableActivityToTop: already on top, activity=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
     "1856783490": {
       "message": "resumeTopActivity: Restarting %s",
       "level": "DEBUG",
@@ -4171,6 +4213,12 @@
       "group": "WM_DEBUG_ANIM",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "2079410261": {
+      "message": "applyAnimation:  override requested, but it is prohibited by policy.",
+      "level": "ERROR",
+      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+      "at": "com\/android\/server\/wm\/AppTransition.java"
+    },
     "2083556954": {
       "message": "Set mOrientationChanging of %s",
       "level": "VERBOSE",
@@ -4224,12 +4272,6 @@
       "level": "VERBOSE",
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "2137411379": {
-      "message": "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
     }
   },
   "groups": {
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 1629b6a..239621e 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -40,6 +40,7 @@
 import android.graphics.drawable.NinePatchDrawable;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Trace;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.DisplayMetrics;
@@ -223,13 +224,21 @@
         public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
             return nCreate(mData, mOffset, mLength, preferAnimation, this);
         }
+
+        @Override
+        public String toString() {
+            return "ByteArraySource{len=" + mLength + "}";
+        }
     }
 
     private static class ByteBufferSource extends Source {
         ByteBufferSource(@NonNull ByteBuffer buffer) {
             mBuffer = buffer;
+            mLength = mBuffer.limit() - mBuffer.position();
         }
+
         private final ByteBuffer mBuffer;
+        private final int mLength;
 
         @Override
         public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
@@ -241,6 +250,11 @@
             ByteBuffer buffer = mBuffer.slice();
             return nCreate(buffer, buffer.position(), buffer.limit(), preferAnimation, this);
         }
+
+        @Override
+        public String toString() {
+            return "ByteBufferSource{len=" + mLength + "}";
+        }
     }
 
     private static class ContentResolverSource extends Source {
@@ -285,6 +299,16 @@
 
             return createFromAssetFileDescriptor(assetFd, preferAnimation, this);
         }
+
+        @Override
+        public String toString() {
+            String uri = mUri.toString();
+            if (uri.length() > 90) {
+                // We want to keep the Uri usable - usually the authority and the end is important.
+                uri = uri.substring(0, 80) + ".." + uri.substring(uri.length() - 10);
+            }
+            return "ContentResolverSource{uri=" + uri + "}";
+        }
     }
 
     @NonNull
@@ -399,6 +423,11 @@
                 return createFromStream(is, false, preferAnimation, this);
             }
         }
+
+        @Override
+        public String toString() {
+            return "InputStream{s=" + mInputStream + "}";
+        }
     }
 
     /**
@@ -444,6 +473,11 @@
                 return createFromAsset(ais, preferAnimation, this);
             }
         }
+
+        @Override
+        public String toString() {
+            return "AssetInputStream{s=" + mAssetInputStream + "}";
+        }
     }
 
     private static class ResourceSource extends Source {
@@ -485,6 +519,17 @@
 
             return createFromAsset((AssetInputStream) is, preferAnimation, this);
         }
+
+        @Override
+        public String toString() {
+            // Try to return a human-readable name for debugging purposes.
+            try {
+                return "Resource{name=" + mResources.getResourceName(mResId) + "}";
+            } catch (Resources.NotFoundException e) {
+                // It's ok if we don't find it, fall back to ID.
+            }
+            return "Resource{id=" + mResId + "}";
+        }
     }
 
     /**
@@ -521,6 +566,11 @@
             InputStream is = mAssets.open(mFileName);
             return createFromAsset((AssetInputStream) is, preferAnimation, this);
         }
+
+        @Override
+        public String toString() {
+            return "AssetSource{file=" + mFileName + "}";
+        }
     }
 
     private static class FileSource extends Source {
@@ -534,6 +584,11 @@
         public ImageDecoder createImageDecoder(boolean preferAnimation) throws IOException {
             return createFromFile(mFile, preferAnimation, this);
         }
+
+        @Override
+        public String toString() {
+            return "FileSource{file=" + mFile + "}";
+        }
     }
 
     private static class CallableSource extends Source {
@@ -557,6 +612,11 @@
             }
             return createFromAssetFileDescriptor(assetFd, preferAnimation, this);
         }
+
+        @Override
+        public String toString() {
+            return "CallableSource{obj=" + mCallable.toString() + "}";
+        }
     }
 
     /**
@@ -1763,61 +1823,65 @@
     @NonNull
     private static Drawable decodeDrawableImpl(@NonNull Source src,
             @Nullable OnHeaderDecodedListener listener) throws IOException {
+        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ImageDecoder#decodeDrawable");
         try (ImageDecoder decoder = src.createImageDecoder(true /*preferAnimation*/)) {
             decoder.mSource = src;
             decoder.callHeaderDecoded(listener, src);
 
-            if (decoder.mUnpremultipliedRequired) {
-                // Though this could be supported (ignored) for opaque images,
-                // it seems better to always report this error.
-                throw new IllegalStateException("Cannot decode a Drawable " +
-                                                "with unpremultiplied pixels!");
-            }
-
-            if (decoder.mMutable) {
-                throw new IllegalStateException("Cannot decode a mutable " +
-                                                "Drawable!");
-            }
-
-            // this call potentially manipulates the decoder so it must be performed prior to
-            // decoding the bitmap and after decode set the density on the resulting bitmap
-            final int srcDensity = decoder.computeDensity(src);
-            if (decoder.mAnimated) {
-                // AnimatedImageDrawable calls postProcessAndRelease only if
-                // mPostProcessor exists.
-                ImageDecoder postProcessPtr = decoder.mPostProcessor == null ?
-                        null : decoder;
-                decoder.checkState(true);
-                Drawable d = new AnimatedImageDrawable(decoder.mNativePtr,
-                        postProcessPtr, decoder.mDesiredWidth,
-                        decoder.mDesiredHeight, decoder.getColorSpacePtr(),
-                        decoder.checkForExtended(), srcDensity,
-                        src.computeDstDensity(), decoder.mCropRect,
-                        decoder.mInputStream, decoder.mAssetFd);
-                // d has taken ownership of these objects.
-                decoder.mInputStream = null;
-                decoder.mAssetFd = null;
-                return d;
-            }
-
-            Bitmap bm = decoder.decodeBitmapInternal();
-            bm.setDensity(srcDensity);
-
-            Resources res = src.getResources();
-            byte[] np = bm.getNinePatchChunk();
-            if (np != null && NinePatch.isNinePatchChunk(np)) {
-                Rect opticalInsets = new Rect();
-                bm.getOpticalInsets(opticalInsets);
-                Rect padding = decoder.mOutPaddingRect;
-                if (padding == null) {
-                    padding = new Rect();
+            try (ImageDecoderSourceTrace unused = new ImageDecoderSourceTrace(decoder)) {
+                if (decoder.mUnpremultipliedRequired) {
+                    // Though this could be supported (ignored) for opaque images,
+                    // it seems better to always report this error.
+                    throw new IllegalStateException(
+                            "Cannot decode a Drawable with unpremultiplied pixels!");
                 }
-                nGetPadding(decoder.mNativePtr, padding);
-                return new NinePatchDrawable(res, bm, np, padding,
-                        opticalInsets, null);
-            }
 
-            return new BitmapDrawable(res, bm);
+                if (decoder.mMutable) {
+                    throw new IllegalStateException("Cannot decode a mutable Drawable!");
+                }
+
+                // this call potentially manipulates the decoder so it must be performed prior to
+                // decoding the bitmap and after decode set the density on the resulting bitmap
+                final int srcDensity = decoder.computeDensity(src);
+                if (decoder.mAnimated) {
+                    // AnimatedImageDrawable calls postProcessAndRelease only if
+                    // mPostProcessor exists.
+                    ImageDecoder postProcessPtr = decoder.mPostProcessor == null ? null : decoder;
+                    decoder.checkState(true);
+                    Drawable d = new AnimatedImageDrawable(decoder.mNativePtr,
+                            postProcessPtr, decoder.mDesiredWidth,
+                            decoder.mDesiredHeight, decoder.getColorSpacePtr(),
+                            decoder.checkForExtended(), srcDensity,
+                            src.computeDstDensity(), decoder.mCropRect,
+                            decoder.mInputStream, decoder.mAssetFd);
+                    // d has taken ownership of these objects.
+                    decoder.mInputStream = null;
+                    decoder.mAssetFd = null;
+                    return d;
+                }
+
+                Bitmap bm = decoder.decodeBitmapInternal();
+                bm.setDensity(srcDensity);
+
+                Resources res = src.getResources();
+                byte[] np = bm.getNinePatchChunk();
+                if (np != null && NinePatch.isNinePatchChunk(np)) {
+                    Rect opticalInsets = new Rect();
+                    bm.getOpticalInsets(opticalInsets);
+                    Rect padding = decoder.mOutPaddingRect;
+                    if (padding == null) {
+                        padding = new Rect();
+                    }
+                    nGetPadding(decoder.mNativePtr, padding);
+                    return new NinePatchDrawable(res, bm, np, padding,
+                            opticalInsets, null);
+                }
+
+                return new BitmapDrawable(res, bm);
+            }
+        } finally {
+            // Close the ImageDecoder#decode trace.
+            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
         }
     }
 
@@ -1867,26 +1931,51 @@
     @NonNull
     private static Bitmap decodeBitmapImpl(@NonNull Source src,
             @Nullable OnHeaderDecodedListener listener) throws IOException {
+        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ImageDecoder#decodeBitmap");
         try (ImageDecoder decoder = src.createImageDecoder(false /*preferAnimation*/)) {
             decoder.mSource = src;
             decoder.callHeaderDecoded(listener, src);
+            try (ImageDecoderSourceTrace unused = new ImageDecoderSourceTrace(decoder)) {
+                // this call potentially manipulates the decoder so it must be performed prior to
+                // decoding the bitmap
+                final int srcDensity = decoder.computeDensity(src);
+                Bitmap bm = decoder.decodeBitmapInternal();
+                bm.setDensity(srcDensity);
 
-            // this call potentially manipulates the decoder so it must be performed prior to
-            // decoding the bitmap
-            final int srcDensity = decoder.computeDensity(src);
-            Bitmap bm = decoder.decodeBitmapInternal();
-            bm.setDensity(srcDensity);
+                Rect padding = decoder.mOutPaddingRect;
+                if (padding != null) {
+                    byte[] np = bm.getNinePatchChunk();
+                    if (np != null && NinePatch.isNinePatchChunk(np)) {
+                        nGetPadding(decoder.mNativePtr, padding);
+                    }
+                }
+                return bm;
+            }
+        } finally {
+            // Close the ImageDecoder#decode trace.
+            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
+        }
+    }
 
-            Rect padding = decoder.mOutPaddingRect;
-            if (padding != null) {
-                byte[] np = bm.getNinePatchChunk();
-                if (np != null && NinePatch.isNinePatchChunk(np)) {
-                    nGetPadding(decoder.mNativePtr, padding);
+    /**
+     * This describes the decoder in traces to ease debugging. It has to be called after
+     * header has been decoded and width/height have been populated. It should be used
+     * inside a try-with-resources call to automatically complete the trace.
+     */
+    private static AutoCloseable traceDecoderSource(ImageDecoder decoder) {
+        final boolean resourceTracingEnabled = Trace.isTagEnabled(Trace.TRACE_TAG_RESOURCES);
+        if (resourceTracingEnabled) {
+            Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, describeDecoderForTrace(decoder));
+        }
+
+        return new AutoCloseable() {
+            @Override
+            public void close() throws Exception {
+                if (resourceTracingEnabled) {
+                    Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
                 }
             }
-
-            return bm;
-        }
+        };
     }
 
     // This method may modify the decoder so it must be called prior to performing the decode
@@ -1994,6 +2083,66 @@
         }
     }
 
+    /**
+     * Returns a short string describing what passed ImageDecoder is loading -
+     * it reports image dimensions, desired dimensions (if any) and source resource.
+     *
+     * The string appears in perf traces to simplify search for slow or memory intensive
+     * image loads.
+     *
+     * Example: ID#w=300;h=250;dw=150;dh=150;src=Resource{name=@resource}
+     *
+     * @hide
+     */
+    private static String describeDecoderForTrace(@NonNull ImageDecoder decoder) {
+        StringBuilder builder = new StringBuilder();
+        // Source dimensions
+        builder.append("ID#w=");
+        builder.append(decoder.mWidth);
+        builder.append(";h=");
+        builder.append(decoder.mHeight);
+        // Desired dimensions (if present)
+        if (decoder.mDesiredWidth != decoder.mWidth
+                || decoder.mDesiredHeight != decoder.mHeight) {
+            builder.append(";dw=");
+            builder.append(decoder.mDesiredWidth);
+            builder.append(";dh=");
+            builder.append(decoder.mDesiredHeight);
+        }
+        // Source description
+        builder.append(";src=");
+        builder.append(decoder.mSource);
+        return builder.toString();
+    }
+
+    /**
+     * Records a trace with information about the source being decoded - dimensions,
+     * desired dimensions and source information.
+     *
+     * It significantly eases debugging of slow resource loads on main thread and
+     * possible large memory consumers.
+     *
+     * @hide
+     */
+    private static final class ImageDecoderSourceTrace implements AutoCloseable {
+
+        private final boolean mResourceTracingEnabled;
+
+        ImageDecoderSourceTrace(ImageDecoder decoder) {
+            mResourceTracingEnabled = Trace.isTagEnabled(Trace.TRACE_TAG_RESOURCES);
+            if (mResourceTracingEnabled) {
+                Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, describeDecoderForTrace(decoder));
+            }
+        }
+
+        @Override
+        public void close() {
+            if (mResourceTracingEnabled) {
+                Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
+            }
+        }
+    }
+
     private static native ImageDecoder nCreate(long asset,
             boolean preferAnimation, Source src) throws IOException;
     private static native ImageDecoder nCreate(ByteBuffer buffer, int position, int limit,
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 74cad1a..417a27d 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -321,6 +321,7 @@
         boolean pressed = false;
         boolean focused = false;
         boolean hovered = false;
+        boolean windowFocused = false;
 
         for (int state : stateSet) {
             if (state == R.attr.state_enabled) {
@@ -331,10 +332,12 @@
                 pressed = true;
             } else if (state == R.attr.state_hovered) {
                 hovered = true;
+            } else if (state == R.attr.state_window_focused) {
+                windowFocused = true;
             }
         }
         setRippleActive(enabled && pressed);
-        setBackgroundActive(hovered, focused, pressed);
+        setBackgroundActive(hovered, focused, pressed, windowFocused);
 
         return changed;
     }
@@ -358,7 +361,8 @@
         }
     }
 
-    private void setBackgroundActive(boolean hovered, boolean focused, boolean pressed) {
+    private void setBackgroundActive(boolean hovered, boolean focused, boolean pressed,
+            boolean windowFocused) {
         if (mState.mRippleStyle == STYLE_SOLID) {
             if (mBackground == null && (hovered || focused)) {
                 mBackground = new RippleBackground(this, mHotspotBounds, isBounded());
@@ -370,7 +374,7 @@
         } else {
             if (focused || hovered) {
                 if (!pressed) {
-                    enterPatternedBackgroundAnimation(focused, hovered);
+                    enterPatternedBackgroundAnimation(focused, hovered, windowFocused);
                 }
             } else {
                 exitPatternedBackgroundAnimation();
@@ -840,9 +844,14 @@
         invalidateSelf(false);
     }
 
-    private void enterPatternedBackgroundAnimation(boolean focused, boolean hovered) {
+    private void enterPatternedBackgroundAnimation(boolean focused, boolean hovered,
+            boolean windowFocused) {
         mBackgroundOpacity = 0;
-        mTargetBackgroundOpacity = focused ? .6f : hovered ? .2f : 0f;
+        if (focused) {
+            mTargetBackgroundOpacity = windowFocused ? .6f : .2f;
+        } else {
+            mTargetBackgroundOpacity = hovered ? .2f : 0f;
+        }
         if (mBackgroundAnimation != null) mBackgroundAnimation.cancel();
         // after cancel
         mRunBackgroundAnimation = true;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
index 921552b..68ff806 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
@@ -199,7 +199,7 @@
             throw new IllegalArgumentException(
                     "Display feature rectangle cannot have zero width and height simultaneously.");
         }
-        this.mRect = rect;
+        this.mRect = new Rect(rect);
     }
 
     /** Returns the type of the feature. */
@@ -217,7 +217,7 @@
     /** Returns the bounds of the feature. */
     @NonNull
     public Rect getRect() {
-        return mRect;
+        return new Rect(mRect);
     }
 
     @Override
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index fdcb7be..cc2bb63 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -22,7 +22,6 @@
 import static androidx.window.common.CommonFoldingFeature.parseListFromString;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.devicestate.DeviceStateManager.DeviceStateCallback;
@@ -30,22 +29,25 @@
 import android.util.Log;
 import android.util.SparseIntArray;
 
+import androidx.window.util.AcceptOnceConsumer;
 import androidx.window.util.BaseDataProducer;
-import androidx.window.util.DataProducer;
 
 import com.android.internal.R;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import java.util.function.Consumer;
 
 /**
- * An implementation of {@link androidx.window.util.DataProducer} that returns the device's posture
- * by mapping the state returned from {@link DeviceStateManager} to values provided in the resources
- * config at {@link R.array#config_device_state_postures}.
+ * An implementation of {@link androidx.window.util.BaseDataProducer} that returns
+ * the device's posture by mapping the state returned from {@link DeviceStateManager} to
+ * values provided in the resources' config at {@link R.array#config_device_state_postures}.
  */
-public final class DeviceStateManagerFoldingFeatureProducer extends
-        BaseDataProducer<List<CommonFoldingFeature>> {
+public final class DeviceStateManagerFoldingFeatureProducer
+        extends BaseDataProducer<List<CommonFoldingFeature>> {
     private static final String TAG =
             DeviceStateManagerFoldingFeatureProducer.class.getSimpleName();
     private static final boolean DEBUG = false;
@@ -54,15 +56,11 @@
 
     private int mCurrentDeviceState = INVALID_DEVICE_STATE;
 
-    private final DeviceStateCallback mDeviceStateCallback = (state) -> {
-        mCurrentDeviceState = state;
-        notifyDataChanged();
-    };
     @NonNull
-    private final DataProducer<String> mRawFoldSupplier;
+    private final BaseDataProducer<String> mRawFoldSupplier;
 
     public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context,
-            @NonNull DataProducer<String> rawFoldSupplier) {
+            @NonNull BaseDataProducer<String> rawFoldSupplier) {
         mRawFoldSupplier = rawFoldSupplier;
         String[] deviceStatePosturePairs = context.getResources()
                 .getStringArray(R.array.config_device_state_postures);
@@ -70,7 +68,8 @@
             String[] deviceStatePostureMapping = deviceStatePosturePair.split(":");
             if (deviceStatePostureMapping.length != 2) {
                 if (DEBUG) {
-                    Log.e(TAG, "Malformed device state posture pair: " + deviceStatePosturePair);
+                    Log.e(TAG, "Malformed device state posture pair: "
+                            + deviceStatePosturePair);
                 }
                 continue;
             }
@@ -82,7 +81,8 @@
                 posture = Integer.parseInt(deviceStatePostureMapping[1]);
             } catch (NumberFormatException e) {
                 if (DEBUG) {
-                    Log.e(TAG, "Failed to parse device state or posture: " + deviceStatePosturePair,
+                    Log.e(TAG, "Failed to parse device state or posture: "
+                                    + deviceStatePosturePair,
                             e);
                 }
                 continue;
@@ -92,32 +92,95 @@
         }
 
         if (mDeviceStateToPostureMap.size() > 0) {
-            context.getSystemService(DeviceStateManager.class)
-                    .registerCallback(context.getMainExecutor(), mDeviceStateCallback);
+            DeviceStateCallback deviceStateCallback = (state) -> {
+                mCurrentDeviceState = state;
+                mRawFoldSupplier.getData(this::notifyFoldingFeatureChange);
+            };
+            Objects.requireNonNull(context.getSystemService(DeviceStateManager.class))
+                    .registerCallback(context.getMainExecutor(), deviceStateCallback);
         }
     }
 
-    @Override
-    @Nullable
-    public Optional<List<CommonFoldingFeature>> getData() {
-        final int globalHingeState = globalHingeState();
-        Optional<String> displayFeaturesString = mRawFoldSupplier.getData();
-        if (displayFeaturesString.isEmpty() || TextUtils.isEmpty(displayFeaturesString.get())) {
-            return Optional.empty();
+    /**
+     * Add a callback to mCallbacks if there is no device state. This callback will be run
+     * once a device state is set. Otherwise,run the callback immediately.
+     */
+    private void runCallbackWhenValidState(@NonNull Consumer<List<CommonFoldingFeature>> callback,
+            String displayFeaturesString) {
+        if (isCurrentStateValid()) {
+            callback.accept(calculateFoldingFeature(displayFeaturesString));
+        } else {
+            // This callback will be added to mCallbacks and removed once it runs once.
+            AcceptOnceConsumer<List<CommonFoldingFeature>> singleRunCallback =
+                    new AcceptOnceConsumer<>(this, callback);
+            addDataChangedCallback(singleRunCallback);
         }
-        return Optional.of(parseListFromString(displayFeaturesString.get(), globalHingeState));
+    }
+
+    /**
+     * Checks to find {@link DeviceStateManagerFoldingFeatureProducer#mCurrentDeviceState} in the
+     * {@link DeviceStateManagerFoldingFeatureProducer#mDeviceStateToPostureMap} which was
+     * initialized in the constructor of {@link DeviceStateManagerFoldingFeatureProducer}.
+     * Returns a boolean value of whether the device state is valid.
+     */
+    private boolean isCurrentStateValid() {
+        // If the device state is not found in the map, indexOfKey returns a negative number.
+        return mDeviceStateToPostureMap.indexOfKey(mCurrentDeviceState) >= 0;
     }
 
     @Override
-    protected void onListenersChanged(Set<Runnable> callbacks) {
+    protected void onListenersChanged(
+            @NonNull Set<Consumer<List<CommonFoldingFeature>>> callbacks) {
         super.onListenersChanged(callbacks);
         if (callbacks.isEmpty()) {
-            mRawFoldSupplier.removeDataChangedCallback(this::notifyDataChanged);
+            mCurrentDeviceState = INVALID_DEVICE_STATE;
+            mRawFoldSupplier.removeDataChangedCallback(this::notifyFoldingFeatureChange);
         } else {
-            mRawFoldSupplier.addDataChangedCallback(this::notifyDataChanged);
+            mRawFoldSupplier.addDataChangedCallback(this::notifyFoldingFeatureChange);
         }
     }
 
+    @NonNull
+    @Override
+    public Optional<List<CommonFoldingFeature>> getCurrentData() {
+        Optional<String> displayFeaturesString = mRawFoldSupplier.getCurrentData();
+        if (!isCurrentStateValid()) {
+            return Optional.empty();
+        } else {
+            return displayFeaturesString.map(this::calculateFoldingFeature);
+        }
+    }
+
+    /**
+     * Adds the data to the storeFeaturesConsumer when the data is ready.
+     * @param storeFeaturesConsumer a consumer to collect the data when it is first available.
+     */
+    public void getData(Consumer<List<CommonFoldingFeature>> storeFeaturesConsumer) {
+        mRawFoldSupplier.getData((String displayFeaturesString) -> {
+            if (TextUtils.isEmpty(displayFeaturesString)) {
+                storeFeaturesConsumer.accept(new ArrayList<>());
+            } else {
+                runCallbackWhenValidState(storeFeaturesConsumer, displayFeaturesString);
+            }
+        });
+    }
+
+    private void notifyFoldingFeatureChange(String displayFeaturesString) {
+        if (!isCurrentStateValid()) {
+            return;
+        }
+        if (TextUtils.isEmpty(displayFeaturesString)) {
+            notifyDataChanged(new ArrayList<>());
+        } else {
+            notifyDataChanged(calculateFoldingFeature(displayFeaturesString));
+        }
+    }
+
+    private List<CommonFoldingFeature> calculateFoldingFeature(String displayFeaturesString) {
+        final int globalHingeState = globalHingeState();
+        return parseListFromString(displayFeaturesString, globalHingeState);
+    }
+
     private int globalHingeState() {
         return mDeviceStateToPostureMap.get(mCurrentDeviceState, COMMON_STATE_UNKNOWN);
     }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
index 69ad1ba..7906342 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/RawFoldingFeatureProducer.java
@@ -32,6 +32,7 @@
 
 import java.util.Optional;
 import java.util.Set;
+import java.util.function.Consumer;
 
 /**
  * Implementation of {@link androidx.window.util.DataProducer} that produces a
@@ -40,7 +41,7 @@
  * settings where the {@link String} property is saved with the key
  * {@link RawFoldingFeatureProducer#DISPLAY_FEATURES}. If this value is null or empty then the
  * value in {@link android.content.res.Resources} is used. If both are empty then
- * {@link RawFoldingFeatureProducer#getData()} returns an empty object.
+ * {@link RawFoldingFeatureProducer#getData} returns an empty object.
  * {@link RawFoldingFeatureProducer} listens to changes in the setting so that it can override
  * the system {@link CommonFoldingFeature} data.
  */
@@ -63,12 +64,13 @@
 
     @Override
     @NonNull
-    public Optional<String> getData() {
+    public void getData(Consumer<String> dataConsumer) {
         String displayFeaturesString = getFeatureString();
         if (displayFeaturesString == null) {
-            return Optional.empty();
+            dataConsumer.accept("");
+        } else {
+            dataConsumer.accept(displayFeaturesString);
         }
-        return Optional.of(displayFeaturesString);
     }
 
     /**
@@ -84,7 +86,7 @@
     }
 
     @Override
-    protected void onListenersChanged(Set<Runnable> callbacks) {
+    protected void onListenersChanged(Set<Consumer<String>> callbacks) {
         if (callbacks.isEmpty()) {
             unregisterObserversIfNeeded();
         } else {
@@ -92,6 +94,12 @@
         }
     }
 
+    @NonNull
+    @Override
+    public Optional<String> getCurrentData() {
+        return Optional.of(getFeatureString());
+    }
+
     /**
      * Registers settings observers, if needed. When settings observers are registered for this
      * producer callbacks for changes in data will be triggered.
@@ -125,8 +133,8 @@
         @Override
         public void onChange(boolean selfChange, Uri uri) {
             if (mDisplayFeaturesUri.equals(uri)) {
-                notifyDataChanged();
+                notifyDataChanged(getFeatureString());
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index c9a0d7d9..41791af 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -381,6 +381,7 @@
      *         in a state that the caller shouldn't handle.
      */
     @VisibleForTesting
+    @GuardedBy("mLock")
     boolean resolveActivityToContainer(@NonNull Activity activity, boolean isOnReparent) {
         if (isInPictureInPicture(activity) || activity.isFinishing()) {
             // We don't embed activity when it is in PIP, or finishing. Return true since we don't
@@ -607,6 +608,7 @@
      * Checks if there is a rule to split the two activities. If there is one, puts them into split
      * and returns {@code true}. Otherwise, returns {@code false}.
      */
+    @GuardedBy("mLock")
     private boolean putActivitiesIntoSplitIfNecessary(@NonNull Activity primaryActivity,
             @NonNull Activity secondaryActivity) {
         final SplitPairRule splitRule = getSplitRule(primaryActivity, secondaryActivity);
@@ -793,6 +795,7 @@
      * Returns a container for the new activity intent to launch into as splitting with the primary
      * activity.
      */
+    @GuardedBy("mLock")
     @Nullable
     private TaskFragmentContainer getSecondaryContainerForSplitIfAny(
             @NonNull WindowContainerTransaction wct, @NonNull Activity primaryActivity,
@@ -865,6 +868,7 @@
      *                                  if needed.
      * @param taskId                    parent Task of the new TaskFragment.
      */
+    @GuardedBy("mLock")
     TaskFragmentContainer newContainer(@Nullable Activity pendingAppearedActivity,
             @Nullable Intent pendingAppearedIntent, @NonNull Activity activityInTask, int taskId) {
         if (activityInTask == null) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java
index 586ac1f..5cc496a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java
@@ -180,9 +180,18 @@
     Animation loadOpenAnimation(@NonNull RemoteAnimationTarget target,
             @NonNull Rect wholeAnimationBounds) {
         final boolean isEnter = target.mode != MODE_CLOSING;
-        final Animation animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
-                ? com.android.internal.R.anim.task_fragment_open_enter
-                : com.android.internal.R.anim.task_fragment_open_exit);
+        final Animation animation;
+        // Background color on TaskDisplayArea has already been set earlier in
+        // WindowContainer#getAnimationAdapter.
+        if (target.showBackdrop) {
+            animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
+                    ? com.android.internal.R.anim.task_fragment_clear_top_open_enter
+                    : com.android.internal.R.anim.task_fragment_clear_top_open_exit);
+        } else {
+            animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
+                    ? com.android.internal.R.anim.task_fragment_open_enter
+                    : com.android.internal.R.anim.task_fragment_open_exit);
+        }
         animation.initialize(target.localBounds.width(), target.localBounds.height(),
                 wholeAnimationBounds.width(), wholeAnimationBounds.height());
         animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
@@ -192,9 +201,16 @@
     Animation loadCloseAnimation(@NonNull RemoteAnimationTarget target,
             @NonNull Rect wholeAnimationBounds) {
         final boolean isEnter = target.mode != MODE_CLOSING;
-        final Animation animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
-                ? com.android.internal.R.anim.task_fragment_close_enter
-                : com.android.internal.R.anim.task_fragment_close_exit);
+        final Animation animation;
+        if (target.showBackdrop) {
+            animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
+                    ? com.android.internal.R.anim.task_fragment_clear_top_close_enter
+                    : com.android.internal.R.anim.task_fragment_clear_top_close_exit);
+        } else {
+            animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
+                    ? com.android.internal.R.anim.task_fragment_close_enter
+                    : com.android.internal.R.anim.task_fragment_close_exit);
+        }
         animation.initialize(target.localBounds.width(), target.localBounds.height(),
                 wholeAnimationBounds.width(), wholeAnimationBounds.height());
         animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index c1d1c8e..18086f5 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -46,7 +46,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
 import java.util.function.Consumer;
 
@@ -66,7 +65,7 @@
 
     private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
 
-    public WindowLayoutComponentImpl(Context context) {
+    public WindowLayoutComponentImpl(@NonNull Context context) {
         ((Application) context.getApplicationContext())
                 .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
         RawFoldingFeatureProducer foldingFeatureProducer = new RawFoldingFeatureProducer(context);
@@ -83,8 +82,12 @@
      */
     public void addWindowLayoutInfoListener(@NonNull Activity activity,
             @NonNull Consumer<WindowLayoutInfo> consumer) {
+        mFoldingFeatureProducer.getData((features) -> {
+            // Get the WindowLayoutInfo from the activity and pass the value to the layoutConsumer.
+            WindowLayoutInfo newWindowLayout = getWindowLayoutInfo(activity, features);
+            consumer.accept(newWindowLayout);
+        });
         mWindowLayoutChangeListeners.put(activity, consumer);
-        onDisplayFeaturesChanged();
     }
 
     /**
@@ -92,18 +95,8 @@
      *
      * @param consumer no longer interested in receiving updates to {@link WindowLayoutInfo}
      */
-    public void removeWindowLayoutInfoListener(
-            @NonNull Consumer<WindowLayoutInfo> consumer) {
+    public void removeWindowLayoutInfoListener(@NonNull Consumer<WindowLayoutInfo> consumer) {
         mWindowLayoutChangeListeners.values().remove(consumer);
-        onDisplayFeaturesChanged();
-    }
-
-    void updateWindowLayout(@NonNull Activity activity,
-            @NonNull WindowLayoutInfo newLayout) {
-        Consumer<WindowLayoutInfo> consumer = mWindowLayoutChangeListeners.get(activity);
-        if (consumer != null) {
-            consumer.accept(newLayout);
-        }
     }
 
     @NonNull
@@ -111,7 +104,6 @@
         return mWindowLayoutChangeListeners.keySet();
     }
 
-    @NonNull
     private boolean isListeningForLayoutChanges(IBinder token) {
         for (Activity activity: getActivitiesListeningForLayoutChanges()) {
             if (token.equals(activity.getWindow().getAttributes().token)) {
@@ -128,12 +120,12 @@
     /**
      * A convenience method to translate from the common feature state to the extensions feature
      * state.  More specifically, translates from {@link CommonFoldingFeature.State} to
-     * {@link FoldingFeature.STATE_FLAT} or {@link FoldingFeature.STATE_HALF_OPENED}. If it is not
+     * {@link FoldingFeature#STATE_FLAT} or {@link FoldingFeature#STATE_HALF_OPENED}. If it is not
      * possible to translate, then we will return a {@code null} value.
      *
      * @param state if it matches a value in {@link CommonFoldingFeature.State}, {@code null}
-     *              otherwise. @return a {@link FoldingFeature.STATE_FLAT} or
-     *              {@link FoldingFeature.STATE_HALF_OPENED} if the given state matches a value in
+     *              otherwise. @return a {@link FoldingFeature#STATE_FLAT} or
+     *              {@link FoldingFeature#STATE_HALF_OPENED} if the given state matches a value in
      *              {@link CommonFoldingFeature.State} and {@code null} otherwise.
      */
     @Nullable
@@ -147,17 +139,24 @@
         }
     }
 
-    private void onDisplayFeaturesChanged() {
+    private void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) {
         for (Activity activity : getActivitiesListeningForLayoutChanges()) {
-            WindowLayoutInfo newLayout = getWindowLayoutInfo(activity);
-            updateWindowLayout(activity, newLayout);
+            // Get the WindowLayoutInfo from the activity and pass the value to the layoutConsumer.
+            Consumer<WindowLayoutInfo> layoutConsumer = mWindowLayoutChangeListeners.get(activity);
+            WindowLayoutInfo newWindowLayout = getWindowLayoutInfo(activity, storedFeatures);
+            layoutConsumer.accept(newWindowLayout);
         }
     }
 
-    @NonNull
-    private WindowLayoutInfo getWindowLayoutInfo(@NonNull Activity activity) {
-        List<DisplayFeature> displayFeatures = getDisplayFeatures(activity);
-        return new WindowLayoutInfo(displayFeatures);
+    /**
+     * Translates the {@link DisplayFeature} into a {@link WindowLayoutInfo} when a
+     * valid state is found.
+     * @param activity a proxy for the {@link android.view.Window} that contains the
+     */
+    private WindowLayoutInfo getWindowLayoutInfo(
+            @NonNull Activity activity, List<CommonFoldingFeature> storedFeatures) {
+        List<DisplayFeature> displayFeatureList = getDisplayFeatures(activity, storedFeatures);
+        return new WindowLayoutInfo(displayFeatureList);
     }
 
     /**
@@ -175,26 +174,21 @@
      *
      * @param activity a proxy for the {@link android.view.Window} that contains the
      * {@link DisplayFeature}.
-     * @return a {@link List} of valid {@link DisplayFeature} that
      * are within the {@link android.view.Window} of the {@link Activity}
      */
-    private List<DisplayFeature> getDisplayFeatures(@NonNull Activity activity) {
+    private List<DisplayFeature> getDisplayFeatures(
+            @NonNull Activity activity, List<CommonFoldingFeature> storedFeatures) {
         List<DisplayFeature> features = new ArrayList<>();
         int displayId = activity.getDisplay().getDisplayId();
         if (displayId != DEFAULT_DISPLAY) {
             Log.w(TAG, "This sample doesn't support display features on secondary displays");
             return features;
-        }
-
-        if (isTaskInMultiWindowMode(activity)) {
+        } else if (isTaskInMultiWindowMode(activity)) {
             // It is recommended not to report any display features in multi-window mode, since it
             // won't be possible to synchronize the display feature positions with window movement.
             return features;
-        }
-
-        Optional<List<CommonFoldingFeature>> storedFeatures = mFoldingFeatureProducer.getData();
-        if (storedFeatures.isPresent()) {
-            for (CommonFoldingFeature baseFeature : storedFeatures.get()) {
+        } else {
+            for (CommonFoldingFeature baseFeature : storedFeatures) {
                 Integer state = convertToExtensionState(baseFeature.getState());
                 if (state == null) {
                     continue;
@@ -208,8 +202,8 @@
                     features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
                 }
             }
+            return features;
         }
-        return features;
     }
 
     /**
@@ -262,7 +256,8 @@
         private void onDisplayFeaturesChangedIfListening(Activity activity) {
             IBinder token = activity.getWindow().getAttributes().token;
             if (token == null || isListeningForLayoutChanges(token)) {
-                onDisplayFeaturesChanged();
+                mFoldingFeatureProducer.getData(
+                        WindowLayoutComponentImpl.this::onDisplayFeaturesChanged);
             }
         }
     }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index 970f0a2..5bfb0eb 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -28,41 +28,42 @@
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.window.common.CommonFoldingFeature;
 import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
 import androidx.window.common.EmptyLifecycleCallbacksAdapter;
 import androidx.window.common.RawFoldingFeatureProducer;
-import androidx.window.util.DataProducer;
+import androidx.window.util.BaseDataProducer;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Optional;
 
 /**
  * Reference implementation of androidx.window.sidecar OEM interface for use with
  * WindowManager Jetpack.
  */
 class SampleSidecarImpl extends StubSidecar {
-    private static final String TAG = "SampleSidecar";
-
-    private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
-
+    private List<CommonFoldingFeature> mStoredFeatures = new ArrayList<>();
 
     SampleSidecarImpl(Context context) {
         ((Application) context.getApplicationContext())
                 .registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
-        DataProducer<String> settingsFeatureProducer = new RawFoldingFeatureProducer(context);
-        mFoldingFeatureProducer = new DeviceStateManagerFoldingFeatureProducer(context,
-                settingsFeatureProducer);
+        BaseDataProducer<String> settingsFeatureProducer = new RawFoldingFeatureProducer(context);
+        BaseDataProducer<List<CommonFoldingFeature>> foldingFeatureProducer =
+                new DeviceStateManagerFoldingFeatureProducer(context,
+                        settingsFeatureProducer);
 
-        mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
+        foldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
     }
 
-    private void onDisplayFeaturesChanged() {
+    private void setStoredFeatures(List<CommonFoldingFeature> storedFeatures) {
+        mStoredFeatures = storedFeatures;
+    }
+
+    private void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) {
+        setStoredFeatures(storedFeatures);
         updateDeviceState(getDeviceState());
         for (IBinder windowToken : getWindowsListeningForLayoutChanges()) {
             SidecarWindowLayoutInfo newLayout = getWindowLayoutInfo(windowToken);
@@ -79,16 +80,16 @@
     }
 
     private int deviceStateFromFeature() {
-        List<CommonFoldingFeature> storedFeatures = mFoldingFeatureProducer.getData()
-                .orElse(Collections.emptyList());
-        for (int i = 0; i < storedFeatures.size(); i++) {
-            CommonFoldingFeature feature = storedFeatures.get(i);
+        for (int i = 0; i < mStoredFeatures.size(); i++) {
+            CommonFoldingFeature feature = mStoredFeatures.get(i);
             final int state = feature.getState();
             switch (state) {
                 case CommonFoldingFeature.COMMON_STATE_FLAT:
                     return SidecarDeviceState.POSTURE_OPENED;
                 case CommonFoldingFeature.COMMON_STATE_HALF_OPENED:
                     return SidecarDeviceState.POSTURE_HALF_OPENED;
+                case CommonFoldingFeature.COMMON_STATE_UNKNOWN:
+                    return SidecarDeviceState.POSTURE_UNKNOWN;
             }
         }
         return SidecarDeviceState.POSTURE_UNKNOWN;
@@ -109,7 +110,6 @@
     private List<SidecarDisplayFeature> getDisplayFeatures(@NonNull Activity activity) {
         int displayId = activity.getDisplay().getDisplayId();
         if (displayId != DEFAULT_DISPLAY) {
-            Log.w(TAG, "This sample doesn't support display features on secondary displays");
             return Collections.emptyList();
         }
 
@@ -119,18 +119,15 @@
             return Collections.emptyList();
         }
 
-        Optional<List<CommonFoldingFeature>> storedFeatures = mFoldingFeatureProducer.getData();
         List<SidecarDisplayFeature> features = new ArrayList<>();
-        if (storedFeatures.isPresent()) {
-            for (CommonFoldingFeature baseFeature : storedFeatures.get()) {
-                SidecarDisplayFeature feature = new SidecarDisplayFeature();
-                Rect featureRect = baseFeature.getRect();
-                rotateRectToDisplayRotation(displayId, featureRect);
-                transformToWindowSpaceRect(activity, featureRect);
-                feature.setRect(featureRect);
-                feature.setType(baseFeature.getType());
-                features.add(feature);
-            }
+        for (CommonFoldingFeature baseFeature : mStoredFeatures) {
+            SidecarDisplayFeature feature = new SidecarDisplayFeature();
+            Rect featureRect = baseFeature.getRect();
+            rotateRectToDisplayRotation(displayId, featureRect);
+            transformToWindowSpaceRect(activity, featureRect);
+            feature.setRect(featureRect);
+            feature.setType(baseFeature.getType());
+            features.add(feature);
         }
         return Collections.unmodifiableList(features);
     }
@@ -138,7 +135,7 @@
     @Override
     protected void onListenersChanged() {
         if (hasListeners()) {
-            onDisplayFeaturesChanged();
+            onDisplayFeaturesChanged(mStoredFeatures);
         }
     }
 
@@ -158,7 +155,7 @@
         private void onDisplayFeaturesChangedForActivity(@NonNull Activity activity) {
             IBinder token = activity.getWindow().getAttributes().token;
             if (token == null || mWindowLayoutChangeListenerTokens.contains(token)) {
-                onDisplayFeaturesChanged();
+                onDisplayFeaturesChanged(mStoredFeatures);
             }
         }
     }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/AcceptOnceConsumer.java b/libs/WindowManager/Jetpack/src/androidx/window/util/AcceptOnceConsumer.java
new file mode 100644
index 0000000..7624b69
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/util/AcceptOnceConsumer.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window.util;
+
+import android.annotation.NonNull;
+
+import java.util.function.Consumer;
+
+/**
+ * A base class that works with {@link BaseDataProducer} to add/remove a consumer that should
+ * only be used once when {@link BaseDataProducer#notifyDataChanged} is called.
+ * @param <T> The type of data this producer returns through {@link DataProducer#getData}.
+ */
+public class AcceptOnceConsumer<T> implements Consumer<T> {
+    private final Consumer<T> mCallback;
+    private final DataProducer<T> mProducer;
+
+    public AcceptOnceConsumer(@NonNull DataProducer<T> producer, @NonNull Consumer<T> callback) {
+        mProducer = producer;
+        mCallback = callback;
+    }
+
+    @Override
+    public void accept(@NonNull T t) {
+        mCallback.accept(t);
+        mProducer.removeDataChangedCallback(this);
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
index 930db3b..0da44ac 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/util/BaseDataProducer.java
@@ -19,38 +19,48 @@
 import androidx.annotation.NonNull;
 
 import java.util.LinkedHashSet;
+import java.util.Optional;
 import java.util.Set;
+import java.util.function.Consumer;
 
 /**
  * Base class that provides the implementation for the callback mechanism of the
  * {@link DataProducer} API.
  *
- * @param <T> The type of data this producer returns through {@link #getData()}.
+ * @param <T> The type of data this producer returns through {@link DataProducer#getData}.
  */
 public abstract class BaseDataProducer<T> implements DataProducer<T> {
-    private final Set<Runnable> mCallbacks = new LinkedHashSet<>();
+    private final Set<Consumer<T>> mCallbacks = new LinkedHashSet<>();
 
     @Override
-    public final void addDataChangedCallback(@NonNull Runnable callback) {
+    public final void addDataChangedCallback(@NonNull Consumer<T> callback) {
         mCallbacks.add(callback);
+        Optional<T> currentData = getCurrentData();
+        currentData.ifPresent(callback);
         onListenersChanged(mCallbacks);
     }
 
     @Override
-    public final void removeDataChangedCallback(@NonNull Runnable callback) {
+    public final void removeDataChangedCallback(@NonNull Consumer<T> callback) {
         mCallbacks.remove(callback);
         onListenersChanged(mCallbacks);
     }
 
-    protected void onListenersChanged(Set<Runnable> callbacks) {}
+    protected void onListenersChanged(Set<Consumer<T>> callbacks) {}
 
     /**
-     * Called to notify all registered callbacks that the data provided by {@link #getData()} has
-     * changed.
+     * @return the current data if available and {@code Optional.empty()} otherwise.
      */
-    protected void notifyDataChanged() {
-        for (Runnable callback : mCallbacks) {
-            callback.run();
+    @NonNull
+    public abstract Optional<T> getCurrentData();
+
+    /**
+     * Called to notify all registered consumers that the data provided
+     * by {@link DataProducer#getData} has changed.
+     */
+    protected void notifyDataChanged(T value) {
+        for (Consumer<T> callback : mCallbacks) {
+            callback.accept(value);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/DataProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/util/DataProducer.java
index d4d1a23..ec301dc 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/DataProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/util/DataProducer.java
@@ -18,26 +18,27 @@
 
 import android.annotation.NonNull;
 
-import java.util.Optional;
+import java.util.function.Consumer;
 
 /**
- * Produces data through {@link #getData()} and provides a mechanism for receiving a callback when
- * the data managed by the produces has changed.
+ * Produces data through {@link DataProducer#getData} and provides a mechanism for receiving
+ * a callback when the data managed by the produces has changed.
  *
- * @param <T> The type of data this producer returns through {@link #getData()}.
+ * @param <T> The type of data this producer returns through {@link DataProducer#getData}.
  */
 public interface DataProducer<T> {
     /**
-     * Returns the data currently stored in the provider, or {@link Optional#empty()} if the
-     * provider has no data.
+     * Emits the first available data at that point in time.
+     * @param dataConsumer a {@link Consumer} that will receive one value.
      */
-    Optional<T> getData();
+    void getData(@NonNull Consumer<T> dataConsumer);
 
     /**
-     * Adds a callback to be notified when the data returned from {@link #getData()} has changed.
+     * Adds a callback to be notified when the data returned
+     * from {@link DataProducer#getData} has changed.
      */
-    void addDataChangedCallback(@NonNull Runnable callback);
+    void addDataChangedCallback(@NonNull Consumer<T> callback);
 
-    /** Removes a callback previously added with {@link #addDataChangedCallback(Runnable)}.  */
-    void removeDataChangedCallback(@NonNull Runnable callback);
+    /** Removes a callback previously added with {@link #addDataChangedCallback(Consumer)}. */
+    void removeDataChangedCallback(@NonNull Consumer<T> callback);
 }
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 ad496a9..042547f 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
@@ -865,6 +865,8 @@
         assertSplitPair(activityBelow, mActivity, true /* matchParentBounds */);
     }
 
+    // Suppress GuardedBy warning on unit tests
+    @SuppressWarnings("GuardedBy")
     @Test
     public void testResolveActivityToContainer_minDimensions_shouldExpandSplitContainer() {
         final Activity primaryActivity = createMockActivity();
diff --git a/libs/WindowManager/Shell/res/color/decor_button_dark_color.xml b/libs/WindowManager/Shell/res/color/decor_button_dark_color.xml
new file mode 100644
index 0000000..bf325bd
--- /dev/null
+++ b/libs/WindowManager/Shell/res/color/decor_button_dark_color.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item app:state_task_focused="true" android:color="#FF000000" />
+    <item android:color="#33000000" />
+</selector>
diff --git a/libs/WindowManager/Shell/res/color/decor_button_light_color.xml b/libs/WindowManager/Shell/res/color/decor_button_light_color.xml
new file mode 100644
index 0000000..2e48bca
--- /dev/null
+++ b/libs/WindowManager/Shell/res/color/decor_button_light_color.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item app:state_task_focused="true" android:color="#FFFFFFFF" />
+    <item android:color="#33FFFFFF" />
+</selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/color/decor_caption_title_color.xml b/libs/WindowManager/Shell/res/color/decor_caption_title_color.xml
new file mode 100644
index 0000000..1ecc13e
--- /dev/null
+++ b/libs/WindowManager/Shell/res/color/decor_caption_title_color.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto">
+     <!-- Fading the to 85% blackness -->
+    <item app:state_task_focused="true" android:color="#D8D8D8" />
+    <!-- Fading the to 95% blackness -->
+    <item android:color="#F2F2F2" />
+</selector>
diff --git a/libs/WindowManager/Shell/res/color/taskbar_background.xml b/libs/WindowManager/Shell/res/color/taskbar_background.xml
index 329e5b9b..b3d26029 100644
--- a/libs/WindowManager/Shell/res/color/taskbar_background.xml
+++ b/libs/WindowManager/Shell/res/color/taskbar_background.xml
@@ -14,6 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
+<!-- Should be the same as in packages/apps/Launcher3/res/color-v31/taskbar_background.xml -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral1_500" android:lStar="35" />
+    <item android:color="@android:color/system_neutral1_500" android:lStar="15" />
 </selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/decor_caption_title.xml b/libs/WindowManager/Shell/res/drawable/decor_caption_title.xml
new file mode 100644
index 0000000..8207365
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/decor_caption_title.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<shape android:shape="rectangle"
+       android:tintMode="multiply"
+       android:tint="@color/decor_caption_title_color"
+       xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="?android:attr/colorPrimary" />
+</shape>
diff --git a/libs/WindowManager/Shell/res/drawable/decor_close_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_close_button_dark.xml
new file mode 100644
index 0000000..f2f1a1d
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/decor_close_button_dark.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="32.0dp"
+        android:height="32.0dp"
+        android:viewportWidth="32.0"
+        android:viewportHeight="32.0"
+        android:tint="@color/decor_button_dark_color"
+        >
+    <group android:scaleX="0.5"
+            android:scaleY="0.5"
+            android:translateX="8.0"
+            android:translateY="8.0" >
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
+    </group>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/decor_maximize_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_maximize_button_dark.xml
new file mode 100644
index 0000000..ab4e29a
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/decor_maximize_button_dark.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="32.0dp"
+        android:height="32.0dp"
+        android:viewportWidth="32.0"
+        android:viewportHeight="32.0"
+        android:tint="@color/decor_button_dark_color">
+    <group android:scaleX="0.5"
+            android:scaleY="0.5"
+            android:translateX="8.0"
+            android:translateY="8.0" >
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
+    </group>
+</vector>
+
+
diff --git a/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml b/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml
index cb516cd..df5985c 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml
@@ -30,7 +30,8 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_gravity="center_horizontal"
-        android:gravity="center"/>
+        android:gravity="center"
+        android:clipChildren="false"/>
 
     <LinearLayout
         android:id="@+id/bubble_overflow_empty_state"
diff --git a/libs/WindowManager/Shell/res/layout/caption_window_decoration.xml b/libs/WindowManager/Shell/res/layout/caption_window_decoration.xml
new file mode 100644
index 0000000..a112f19
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/caption_window_decoration.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<com.android.wm.shell.windowdecor.WindowDecorLinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/caption"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="end"
+    android:background="@drawable/decor_caption_title">
+    <Button
+        android:id="@+id/maximize_window"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_margin="5dp"
+        android:padding="4dp"
+        android:layout_gravity="center_vertical|end"
+        android:contentDescription="@string/maximize_button_text"
+        android:background="@drawable/decor_maximize_button_dark"
+        android:duplicateParentState="true"/>
+    <Button
+        android:id="@+id/close_window"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_margin="5dp"
+        android:padding="4dp"
+        android:layout_gravity="center_vertical|end"
+        android:contentDescription="@string/close_button_text"
+        android:background="@drawable/decor_close_button_dark"
+        android:duplicateParentState="true"/>
+</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>
+
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 2476f65..e7bc74a 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Draai jou toestel om dit volskerm te maak"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dubbeltik langs ’n program om dit te herposisioneer"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Het dit"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Vou uit vir meer inligting."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimeer"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Maak toe"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index f0c391c..8b2a892 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ወደ የሙሉ ገጽ ዕይታ ለመሄድ መሣሪያዎን ያሽከርክሩት"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ቦታውን ለመቀየር ከመተግበሪያው ቀጥሎ ላይ ሁለቴ መታ ያድርጉ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ገባኝ"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ለተጨማሪ መረጃ ይዘርጉ።"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"አስፋ"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"ዝጋ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index aa4b3b7..2afce7f 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"قم بتدوير الشاشة للانتقال إلى وضع ملء الشاشة."</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"انقر مرتين بجانب التطبيق لتغيير موضعه."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"حسنًا"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"التوسيع للحصول على مزيد من المعلومات"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"تكبير"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"إغلاق"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 985d3b9..df97575 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"পূৰ্ণ স্ক্ৰীনলৈ যাবলৈ আপোনাৰ ডিভাইচটো ঘূৰাওক"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"এপ্‌টোৰ স্থান সলনি কৰিবলৈ ইয়াৰ কাষত দুবাৰ টিপক"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"বুজি পালোঁ"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"অধিক তথ্যৰ বাবে বিস্তাৰ কৰক।"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"সৰ্বাধিক মাত্ৰালৈ বঢ়াওক"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"বন্ধ কৰক"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 8cd9b7a..892be93 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Tam ekrana keçmək üçün cihazınızı fırladın"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tətbiqin yerini dəyişmək üçün yanına iki dəfə toxunun"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ətraflı məlumat üçün genişləndirin."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Böyüdün"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Bağlayın"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 49524c6..b34920e 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotirajte uređaj za prikaz preko celog ekrana"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvaput dodirnite pored aplikacije da biste promenili njenu poziciju"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Važi"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite za još informacija."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Uvećajte"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Zatvorite"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 1767e0d..525e46f 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Каб перайсці ў поўнаэкранны рэжым, павярніце прыладу"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Двойчы націсніце побач з праграмай, каб перамясціць яе"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Зразумела"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Разгарнуць для дадатковай інфармацыі"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Разгарнуць"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Закрыць"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index c22fb86..e27ec8e 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Завъртете екрана си, за да преминете в режим на цял екран"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Докоснете два пъти дадено приложение, за да промените позицията му"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Разбрах"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Разгъване за още информация."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Увеличаване"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Затваряне"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index c0944e05..0a8b0b7 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"\'ফুল স্ক্রিন\' মোডে যেতে ডিভাইস ঘোরান"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"কোনও অ্যাপের পাশে ডবল ট্যাপ করে সেটির জায়গা পরিবর্তন করুন"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"বুঝেছি"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"আরও তথ্যের জন্য বড় করুন।"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"বড় করুন"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"বন্ধ করুন"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index ae01c64..aadbfa4 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zarotirajte uređaj da aktivirate prikaz preko cijelog ekrana"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvaput dodirnite pored aplikacije da promijenite njen položaj"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Razumijem"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite za više informacija."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiziranje"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Zatvaranje"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 8a522b3..ab67246 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gira el dispositiu per passar a pantalla completa"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Fes doble toc al costat d\'una aplicació per canviar-ne la posició"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entesos"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Desplega per obtenir més informació."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximitza"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Tanca"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index d0cf80a..d7b1a38 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Otočením zařízení přejděte do režimu celé obrazovky"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvojitým klepnutím vedle aplikace změňte její umístění"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Rozbalením zobrazíte další informace."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximalizovat"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Zavřít"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index bb81c10..c0acc08 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Drej din enhed for at gå til fuld skærm"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tryk to gange ud for en app for at ændre dens placering"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Udvid for at få flere oplysninger."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimér"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Luk"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index c5d945a..e06bebd 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gerät drehen, um zum Vollbildmodus zu wechseln"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Neben einer App doppeltippen, um die Position zu ändern"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ok"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Für weitere Informationen maximieren."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximieren"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Schließen"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 70f5505..0d9d3ea 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Περιστρέψτε τη συσκευή σας για μετάβαση σε πλήρη οθόνη."</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Πατήστε δύο φορές δίπλα σε μια εφαρμογή για να αλλάξετε τη θέση της."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Το κατάλαβα"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ανάπτυξη για περισσότερες πληροφορίες."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Μεγιστοποίηση"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Κλείσιμο"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 0b5aefa5..48525cd 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Close"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 0b5aefa5..48525cd 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Close"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 0b5aefa5..48525cd 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Close"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 0b5aefa5..48525cd 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expand for more information."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximise"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Close"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index 5c3d0f6..fb6db5f 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‏‎Rotate your device to go full screen‎‏‎‎‏‎"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎Double-tap next to an app to reposition it‎‏‎‎‏‎"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‎‎‏‎Got it‎‏‎‎‏‎"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎Expand for more information.‎‏‎‎‏‎"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎Maximize‎‏‎‎‏‎"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎Close‎‏‎‎‏‎"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index e523ae5..3db353a 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rota el dispositivo para ver la pantalla completa"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Presiona dos veces junto a una app para cambiar su posición"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expande para obtener más información."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 39990dc..c249328 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gira el dispositivo para ir al modo de pantalla completa"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toca dos veces junto a una aplicación para cambiar su posición"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Mostrar más información"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index a5f82a6..0133336 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pöörake seadet, et aktiveerida täisekraanirežiim"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Topeltpuudutage rakenduse kõrval, et selle asendit muuta"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Selge"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Laiendage lisateabe saamiseks."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimeeri"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Sule"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 67b9a43..71ccad5 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pantaila osoko modua erabiltzeko, biratu gailua"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Aplikazioaren posizioa aldatzeko, sakatu birritan haren ondoko edozein toki"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ados"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Informazio gehiago lortzeko, zabaldu hau."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximizatu"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Itxi"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 761fb9d..20045ef 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"برای رفتن به حالت تمام صفحه، دستگاهتان را بچرخانید"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"در کنار برنامه دوضربه بزنید تا جابه‌جا شود"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"متوجه‌ام"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"برای اطلاعات بیشتر، گسترده کنید."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"بزرگ کردن"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"بستن"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index c809b487..2cd265e 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Käännä laitetta, niin se siirtyy koko näytön tilaan"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Kaksoisnapauta sovellusta, jos haluat siirtää sitä"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Katso lisätietoja laajentamalla."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Suurenna"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Sulje"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 62b2bb6..eb25a8d 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Faites pivoter votre appareil pour passer en plein écran"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Touchez deux fois à côté d\'une application pour la repositionner"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développer pour en savoir plus."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 0747505..53358b7 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Faites pivoter l\'appareil pour passer en plein écran"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Appuyez deux fois à côté d\'une appli pour la repositionner"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développez pour obtenir plus d\'informations"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index b8e0396..09977a1 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Xira o dispositivo para ver o contido en pantalla completa"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toca dúas veces a carón dunha aplicación para cambiala de posición"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Despregar para obter máis información."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Pechar"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index deda2d7..8e9f086 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"પૂર્ણ સ્ક્રીન મોડ લાગુ કરવા માટે, તમારા ડિવાઇસને ફેરવો"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"કોઈ ઍપની જગ્યા બદલવા માટે, તેની બાજુમાં બે વાર ટૅપ કરો"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"સમજાઈ ગયું"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"વધુ માહિતી માટે મોટું કરો."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"મોટું કરો"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"બંધ કરો"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index a5fcb97..3d83005 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"फ़ुल स्क्रीन मोड में जाने के लिए, डिवाइस को घुमाएं"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"किसी ऐप्लिकेशन की जगह बदलने के लिए, उसके बगल में दो बार टैप करें"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ठीक है"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ज़्यादा जानकारी के लिए बड़ा करें."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"बड़ा करें"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"बंद करें"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 5ecc558..1c4116d 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zakrenite uređaj radi prikaza na cijelom zaslonu"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvaput dodirnite pored aplikacije da biste joj promijenili položaj"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Shvaćam"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite da biste saznali više."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiziraj"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Zatvori"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 2295250..d749775 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"A teljes képernyős mód elindításához forgassa el az eszközt"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Koppintson duplán az alkalmazás mellett az áthelyezéséhez"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Értem"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Kibontással további információkhoz juthat."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Teljes méret"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Bezárás"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 2089365..160651c 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Պտտեք սարքը՝ լիաէկրան ռեժիմին անցնելու համար"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Կրկնակի հպեք հավելվածի կողքին՝ այն տեղափոխելու համար"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Եղավ"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ծավալեք՝ ավելին իմանալու համար։"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Ծավալել"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Փակել"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 1b46b2f..fab3486 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Putar perangkat untuk tampilan layar penuh"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Ketuk dua kali di samping aplikasi untuk mengubah posisinya"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Oke"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Luaskan untuk melihat informasi selengkapnya."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimalkan"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index a201c95..c22b881 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Snúðu tækinu til að nota allan skjáinn"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Ýttu tvisvar við hlið forritsins til að færa það"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ég skil"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Stækka til að sjá frekari upplýsingar."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Stækka"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Loka"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 7157ed0..7ec13c4 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Ruota il dispositivo per passare alla modalità a schermo intero"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tocca due volte accanto a un\'app per riposizionarla"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Espandi per avere ulteriori informazioni."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Ingrandisci"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Chiudi"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 52a6b06..8625a2a 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"מסובבים את המכשיר כדי לעבור לתצוגה במסך מלא"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"מקישים הקשה כפולה ליד אפליקציה כדי למקם אותה מחדש"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"הבנתי"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"מרחיבים כדי לקבל מידע נוסף."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"הגדלה"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"סגירה"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 5a25c24..4d09b20 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"全画面表示にするにはデバイスを回転させてください"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"位置を変えるにはアプリの横をダブルタップしてください"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"開くと詳細が表示されます。"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"閉じる"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index bff86fa..8cbc3d8 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"მოატრიალეთ თქვენი მოწყობილობა სრული ეკრანის გასაშლელად"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ორმაგად შეეხეთ აპის გვერდითა სივრცეს, რათა ის სხვაგან გადაიტანოთ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"გასაგებია"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"დამატებითი ინფორმაციისთვის გააფართოეთ."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"მაქსიმალურად გაშლა"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"დახურვა"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index f57f3f5..22cf08b 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Толық экранға ауысу үшін құрылғыңызды бұрыңыз."</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Қолданбаның орнын ауыстыру үшін жанынан екі рет түртіңіз."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Түсінікті"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Толығырақ ақпарат алу үшін терезені жайыңыз."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Жаю"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Жабу"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 5c04f88..1e72d4f 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"បង្វិលឧបករណ៍របស់អ្នក ដើម្បីចូលប្រើអេក្រង់ពេញ"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ចុចពីរដងនៅជាប់កម្មវិធីណាមួយ ដើម្បីប្ដូរទីតាំងកម្មវិធីនោះ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"យល់ហើយ"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ពង្រីកដើម្បីទទួលបានព័ត៌មានបន្ថែម។"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"ពង្រីក"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"បិទ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index e91383c..24d0c82 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ಗೆ ಹೋಗಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ತಿರುಗಿಸಿ"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ಆ್ಯಪ್ ಒಂದರ ಸ್ಥಾನವನ್ನು ಬದಲಾಯಿಸಲು ಅದರ ಪಕ್ಕದಲ್ಲಿ ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ಸರಿ"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ವಿಸ್ತೃತಗೊಳಿಸಿ."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"ಹಿಗ್ಗಿಸಿ"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"ಮುಚ್ಚಿರಿ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 104ba3f..15e8a90 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"전체 화면 모드로 전환하려면 기기를 회전하세요."</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"앱 위치를 조정하려면 앱 옆을 두 번 탭하세요."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"확인"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"추가 정보는 펼쳐서 확인하세요."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"최대화"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"닫기"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 8203622..94ea9fb 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Толук экран режимине өтүү үчүн түзмөктү буруңуз"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Колдонмонун ракурсун өзгөртүү үчүн анын тушуна эки жолу басыңыз"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Түшүндүм"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Толук маалымат алуу үчүн жайып көрүңүз."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Чоңойтуу"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Жабуу"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 2439678..be72d8e 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ໝຸນອຸປະກອນຂອງທ່ານເພື່ອໃຊ້ແບບເຕັມຈໍ"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ແຕະສອງເທື່ອໃສ່ຖັດຈາກແອັບໃດໜຶ່ງເພື່ອຈັດຕຳແໜ່ງຂອງມັນຄືນໃໝ່"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ເຂົ້າໃຈແລ້ວ"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ຂະຫຍາຍເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"ຂະຫຍາຍໃຫຍ່ສຸດ"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"ປິດ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index e2ae643..3fa163b 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pasukite įrenginį, kad įjungtumėte viso ekrano režimą"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dukart palieskite šalia programos, kad pakeistumėte jos poziciją"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Supratau"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Išskleiskite, jei reikia daugiau informacijos."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Padidinti"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Uždaryti"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index a77160b..90cd4be 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pagrieziet ierīci, lai aktivizētu pilnekrāna režīmu"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Veiciet dubultskārienu blakus lietotnei, lai manītu tās pozīciju"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Labi"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Izvērsiet, lai iegūtu plašāku informāciju."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimizēt"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Aizvērt"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index bac0c9e..56e9b40 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Ротирајте го уредот за да отворите на цел екран"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Допрете двапати до некоја апликација за да ја преместите"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Сфатив"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Проширете за повеќе информации."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Зголеми"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Затвори"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index de0f837..88e49e7 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറാൻ ഈ ഉപകരണം റൊട്ടേറ്റ് ചെയ്യുക"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ഒരു ആപ്പിന്റെ സ്ഥാനം മാറ്റാൻ, അതിന് തൊട്ടടുത്ത് ഡബിൾ ടാപ്പ് ചെയ്യുക"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"മനസ്സിലായി"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"കൂടുതൽ വിവരങ്ങൾക്ക് വികസിപ്പിക്കുക."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"വലുതാക്കുക"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"അടയ്ക്കുക"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 1205306..7a6f625 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Төхөөрөмжөө бүтэн дэлгэцээр үзэхийн тулд эргүүлнэ"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Аппыг дахин байрлуулахын тулд хажууд нь хоёр товшино"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ойлголоо"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Нэмэлт мэдээлэл авах бол дэлгэнэ үү."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Томруулах"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Хаах"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index c91d06f..c2a9475 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"फुल स्क्रीन करण्यासाठी, तुमचे डिव्हाइस फिरवा"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ॲपची स्थिती पुन्हा बदलण्यासाठी, त्याच्या शेजारी दोनदा टॅप करा"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"समजले"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"अधिक माहितीसाठी विस्तार करा."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"मोठे करा"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"बंद करा"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 652a991..35512c1 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Putar peranti anda untuk beralih ke skrin penuh"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Ketik dua kali bersebelahan apl untuk menempatkan semula apl"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Kembangkan untuk mendapatkan maklumat lanjut."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimumkan"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 15d182c..5aea49f 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ဖန်သားပြင်အပြည့်လုပ်ရန် သင့်စက်ကို လှည့်နိုင်သည်"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"အက်ပ်နေရာပြန်ချရန် ၎င်းဘေးတွင် နှစ်ချက်တို့နိုင်သည်"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ရပြီ"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"နောက်ထပ်အချက်အလက်များအတွက် ချဲ့နိုင်သည်။"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"ချဲ့ရန်"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"ပိတ်ရန်"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 2f2fea6..8e87bc10 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Roter enheten for å starte fullskjerm"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dobbelttrykk ved siden av en app for å flytte den"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Greit"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Vis for å få mer informasjon."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimer"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Lukk"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 8dfec88..831f6e2 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"तपाईं फुल स्क्रिन मोड हेर्न चाहनुहुन्छ भने आफ्नो डिभाइस रोटेट गर्नुहोस्"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"तपाईं जुन एपको स्थिति मिलाउन चाहनुहुन्छ सोही एपको छेउमा डबल ट्याप गर्नुहोस्"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"बुझेँ"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"थप जानकारी प्राप्त गर्न चाहनुहुन्छ भने एक्स्पान्ड गर्नुहोस्।"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"ठुलो बनाउनुहोस्"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"बन्द गर्नुहोस्"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 8468b04..affdd0e 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Draai je apparaat om naar volledig scherm te schakelen"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dubbeltik naast een app om deze opnieuw te positioneren"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Uitvouwen voor meer informatie."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximaliseren"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Sluiten"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index a8d8448..f150cb9 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ପୂର୍ଣ୍ଣ-ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବାକୁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ରୋଟେଟ କରନ୍ତୁ"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ଏକ ଆପକୁ ରିପୋଜିସନ କରିବା ପାଇଁ ଏହା ପାଖରେ ଦୁଇଥର-ଟାପ କରନ୍ତୁ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ବୁଝିଗଲି"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ଅଧିକ ସୂଚନା ପାଇଁ ବିସ୍ତାର କରନ୍ତୁ।"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"ବଡ଼ କରନ୍ତୁ"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"ବନ୍ଦ କରନ୍ତୁ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index f99176c..62587e5 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ਪੂਰੀ-ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਣ ਲਈ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਘੁਮਾਓ"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ਕਿਸੇ ਐਪ ਦੀ ਜਗ੍ਹਾ ਬਦਲਣ ਲਈ ਉਸ ਦੇ ਅੱਗੇ ਡਬਲ ਟੈਪ ਕਰੋ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ਸਮਝ ਲਿਆ"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਵਿਸਤਾਰ ਕਰੋ।"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"ਵੱਡਾ ਕਰੋ"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"ਬੰਦ ਕਰੋ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index f2147c0..363c851 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Obróć urządzenie, aby przejść do pełnego ekranu"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Kliknij dwukrotnie obok aplikacji, aby ją przenieść"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Rozwiń, aby wyświetlić więcej informacji."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksymalizuj"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Zamknij"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 2efc554..f328b6c 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gire o dispositivo para entrar no modo de tela cheia"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toque duas vezes ao lado de um app para reposicionar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendi"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Abra para ver mais informações."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index c68a693..67369b8 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rode o dispositivo para ficar em ecrã inteiro"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toque duas vezes junto a uma app para a reposicionar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expandir para obter mais informações"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 2efc554..f328b6c 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gire o dispositivo para entrar no modo de tela cheia"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toque duas vezes ao lado de um app para reposicionar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendi"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Abra para ver mais informações."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 804d34f..8da1d67 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotiți dispozitivul pentru a trece în modul ecran complet"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Atingeți de două ori lângă o aplicație pentru a o repoziționa"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Extindeți pentru mai multe informații"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximizați"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Închideți"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 95bf1cf..49efac6 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Чтобы перейти в полноэкранный режим, поверните устройство."</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Чтобы переместить приложение, нажмите на него дважды."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ОК"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Развернуть, чтобы узнать больше."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Развернуть"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Закрыть"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 23dd65a..1f8cba8 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"සම්පූර්ණ තිරයට යාමට ඔබගේ උපාංගය කරකවන්න"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"එය නැවත ස්ථානගත කිරීමට යෙදුමකට යාබදව දෙවරක් තට්ටු කරන්න"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"තේරුණා"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"වැඩිදුර තොරතුරු සඳහා දිග හරින්න"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"විහිදන්න"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"වසන්න"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index a231cac..ca14dd7 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Otočením zariadenia prejdete do režimu celej obrazovky"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvojitým klepnutím vedľa aplikácie zmeníte jej pozíciu"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Dobre"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Po rozbalení sa dozviete viac."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maximalizovať"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Zavrieť"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index adeaae97..626be8b 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Če želite preklopiti v celozaslonski način, zasukajte napravo."</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvakrat se dotaknite ob aplikaciji, če jo želite prestaviti."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"V redu"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Razširitev za več informacij"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiraj"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Zapri"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 2839b4b..591f4b7 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rrotullo ekranin për të kaluar në ekran të plotë"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Trokit dy herë pranë një aplikacioni për ta ripozicionuar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"E kuptova"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Zgjeroje për më shumë informacion."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Maksimizo"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Mbyll"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 9db6b7c..fdd49b5 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Ротирајте уређај за приказ преко целог екрана"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Двапут додирните поред апликације да бисте променили њену позицију"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Важи"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Проширите за још информација."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Увећајте"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Затворите"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index f6bd554..54384ca 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotera skärmen för att gå över till helskärmsläge"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tryck snabbt två gånger bredvid en app för att flytta den"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Utöka för mer information."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Utöka"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Stäng"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index f6e55852..2f7d224 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zungusha kifaa chako ili uende kwenye hali ya skrini nzima"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Gusa mara mbili karibu na programu ili uihamishe"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Nimeelewa"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Panua ili upate maelezo zaidi."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Panua"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Funga"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index d8334ad..b626994 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"முழுத்திரைக்குச் செல்ல உங்கள் சாதனத்தைச் சுழற்றவும்"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ஆப்ஸை இடம் மாற்ற, ஆப்ஸுக்கு அடுத்து இருமுறை தட்டவும்"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"சரி"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"கூடுதல் தகவல்களுக்கு விரிவாக்கலாம்."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"பெரிதாக்கும்"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"மூடும்"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 7330755..f080350 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ఫుల్ స్క్రీన్‌కు వెళ్లడానికి మీ పరికరాన్ని తిప్పండి"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"యాప్ స్థానాన్ని మార్చడానికి దాని పక్కన డబుల్-ట్యాప్ చేయండి"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"అర్థమైంది"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"మరింత సమాచారం కోసం విస్తరించండి."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"గరిష్టీకరించండి"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"మూసివేయండి"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index cfee8ea..0d1f23b 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"หมุนอุปกรณ์ให้แสดงเต็มหน้าจอ"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"แตะสองครั้งข้างแอปเพื่อเปลี่ยนตำแหน่ง"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"รับทราบ"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ขยายเพื่อดูข้อมูลเพิ่มเติม"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"ขยายใหญ่สุด"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"ปิด"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index eed624d..bfae45af 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"I-rotate ang iyong device para mag-full screen"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Mag-double tap sa tabi ng isang app para iposisyon ito ulit"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"I-expand para sa higit pang impormasyon."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"I-maximize"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Isara"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 2b4a2d0..6a9be80 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Tam ekrana geçmek için cihazınızı döndürün"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Yeniden konumlandırmak için uygulamanın yanına iki kez dokunun"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Daha fazla bilgi için genişletin."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Ekranı Kapla"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Kapat"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index c3411a8..52f6d11 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Щоб перейти в повноекранний режим, поверніть пристрій"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Щоб перемістити додаток, двічі торкніться області поруч із ним"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ОK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Розгорніть, щоб дізнатися більше."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Збільшити"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Закрити"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index a31c2be..3abfb0d 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"پوری اسکرین پر جانے کیلئے اپنا آلہ گھمائیں"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"کسی ایپ کی پوزیشن تبدیل کرنے کے لیے اس کے آگے دو بار تھپتھپائیں"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"سمجھ آ گئی"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"مزید معلومات کے لیے پھیلائیں۔"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"بڑا کریں"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"بند کریں"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 2e32225..0c0771f8 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Butun ekranda ochish uchun qurilmani buring"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Qayta joylash uchun keyingi ilova ustiga ikki marta bosing"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Batafsil axborot olish uchun kengaytiring."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Yoyish"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Yopish"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 8f3cffe..8b692a71 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Xoay thiết bị để chuyển sang chế độ toàn màn hình"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Nhấn đúp vào bên cạnh ứng dụng để đặt lại vị trí"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Mở rộng để xem thêm thông tin."</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Phóng to"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Đóng"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 19a9d37..8fed6bf 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"旋转设备即可进入全屏模式"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"在某个应用旁边连续点按两次,即可调整它的位置"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展开即可了解详情。"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"关闭"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 0c40e96..add3291 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"旋轉裝置方向即可進入全螢幕模式"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"在應用程式旁輕按兩下即可調整位置"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展開即可查看詳情。"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"關閉"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 8691352..f2c2a29 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"旋轉裝置方向即可進入全螢幕模式"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"在應用程式旁輕觸兩下即可調整位置"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"我知道了"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展開即可查看詳細資訊。"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"關閉"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 44ffbc6..94e5b9b 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -81,4 +81,7 @@
     <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zungezisa idivayisi yakho ukuze uye esikrinini esigcwele"</string>
     <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Thepha kabili eduze kwe-app ukuze uyimise kabusha"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ngiyezwa"</string>
+    <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Nweba ukuze uthole ulwazi olwengeziwe"</string>
+    <string name="maximize_button_text" msgid="1650859196290301963">"Khulisa"</string>
+    <string name="close_button_text" msgid="2913281996024033299">"Vala"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values/attrs.xml b/libs/WindowManager/Shell/res/values/attrs.xml
index 4aaeef8..2aad4c1c 100644
--- a/libs/WindowManager/Shell/res/values/attrs.xml
+++ b/libs/WindowManager/Shell/res/values/attrs.xml
@@ -19,4 +19,8 @@
         <attr name="icon" format="reference" />
         <attr name="text" format="string" />
     </declare-styleable>
+
+    <declare-styleable name="MessageState">
+        <attr name="state_task_focused" format="boolean"/>
+    </declare-styleable>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index a24311f..68a08513 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -157,7 +157,7 @@
     <string name="accessibility_bubble_dismissed">Bubble dismissed.</string>
 
     <!-- Description of the restart button in the hint of size compatibility mode. [CHAR LIMIT=NONE] -->
-    <string name="restart_button_description">Tap to restart this app and go full screen.</string>
+    <string name="restart_button_description">Tap to restart this app for a better view.</string>
 
     <!-- Description of the camera compat button for applying stretched issues treatment in the hint for
          compatibility control. [CHAR LIMIT=NONE] -->
@@ -186,4 +186,12 @@
     <!-- Button text for dismissing the letterbox education dialog. [CHAR LIMIT=20] -->
     <string name="letterbox_education_got_it">Got it</string>
 
+    <!-- Accessibility description of the letterbox education toast expand to dialog button. [CHAR LIMIT=NONE] -->
+    <string name="letterbox_education_expand_button_description">Expand for more information.</string>
+
+    <!-- Freeform window caption strings -->
+    <!-- Accessibility text for the maximize window button [CHAR LIMIT=NONE] -->
+    <string name="maximize_button_text">Maximize</string>
+    <!-- Accessibility text for the close window button [CHAR LIMIT=NONE] -->
+    <string name="close_button_text">Close</string>
 </resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
index 06f4367..c5f7c19 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellCommandHandlerImpl.java
@@ -18,11 +18,9 @@
 
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 
-import com.android.wm.shell.apppairs.AppPairsController;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
 import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
 import com.android.wm.shell.onehanded.OneHandedController;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.recents.RecentTasksController;
@@ -39,12 +37,10 @@
 public final class ShellCommandHandlerImpl {
     private static final String TAG = ShellCommandHandlerImpl.class.getSimpleName();
 
-    private final Optional<LegacySplitScreenController> mLegacySplitScreenOptional;
     private final Optional<SplitScreenController> mSplitScreenOptional;
     private final Optional<Pip> mPipOptional;
     private final Optional<OneHandedController> mOneHandedOptional;
     private final Optional<HideDisplayCutoutController> mHideDisplayCutout;
-    private final Optional<AppPairsController> mAppPairsOptional;
     private final Optional<RecentTasksController> mRecentTasks;
     private final ShellTaskOrganizer mShellTaskOrganizer;
     private final KidsModeTaskOrganizer mKidsModeTaskOrganizer;
@@ -54,23 +50,19 @@
     public ShellCommandHandlerImpl(
             ShellTaskOrganizer shellTaskOrganizer,
             KidsModeTaskOrganizer kidsModeTaskOrganizer,
-            Optional<LegacySplitScreenController> legacySplitScreenOptional,
             Optional<SplitScreenController> splitScreenOptional,
             Optional<Pip> pipOptional,
             Optional<OneHandedController> oneHandedOptional,
             Optional<HideDisplayCutoutController> hideDisplayCutout,
-            Optional<AppPairsController> appPairsOptional,
             Optional<RecentTasksController> recentTasks,
             ShellExecutor mainExecutor) {
         mShellTaskOrganizer = shellTaskOrganizer;
         mKidsModeTaskOrganizer = kidsModeTaskOrganizer;
         mRecentTasks = recentTasks;
-        mLegacySplitScreenOptional = legacySplitScreenOptional;
         mSplitScreenOptional = splitScreenOptional;
         mPipOptional = pipOptional;
         mOneHandedOptional = oneHandedOptional;
         mHideDisplayCutout = hideDisplayCutout;
-        mAppPairsOptional = appPairsOptional;
         mMainExecutor = mainExecutor;
     }
 
@@ -84,14 +76,10 @@
         pw.println();
         pw.println();
         mPipOptional.ifPresent(pip -> pip.dump(pw));
-        mLegacySplitScreenOptional.ifPresent(splitScreen -> splitScreen.dump(pw));
         mOneHandedOptional.ifPresent(oneHanded -> oneHanded.dump(pw));
         mHideDisplayCutout.ifPresent(hideDisplayCutout -> hideDisplayCutout.dump(pw));
         pw.println();
         pw.println();
-        mAppPairsOptional.ifPresent(appPairs -> appPairs.dump(pw, ""));
-        pw.println();
-        pw.println();
         mSplitScreenOptional.ifPresent(splitScreen -> splitScreen.dump(pw, ""));
         pw.println();
         pw.println();
@@ -109,10 +97,6 @@
             return false;
         }
         switch (args[1]) {
-            case "pair":
-                return runPair(args, pw);
-            case "unpair":
-                return runUnpair(args, pw);
             case "moveToSideStage":
                 return runMoveToSideStage(args, pw);
             case "removeFromSideStage":
@@ -126,29 +110,6 @@
         }
     }
 
-    private boolean runPair(String[] args, PrintWriter pw) {
-        if (args.length < 4) {
-            // First two arguments are "WMShell" and command name.
-            pw.println("Error: two task ids should be provided as arguments");
-            return false;
-        }
-        final int taskId1 = new Integer(args[2]);
-        final int taskId2 = new Integer(args[3]);
-        mAppPairsOptional.ifPresent(appPairs -> appPairs.pair(taskId1, taskId2));
-        return true;
-    }
-
-    private boolean runUnpair(String[] args, PrintWriter pw) {
-        if (args.length < 3) {
-            // First two arguments are "WMShell" and command name.
-            pw.println("Error: task id should be provided as an argument");
-            return false;
-        }
-        final int taskId = new Integer(args[2]);
-        mAppPairsOptional.ifPresent(appPairs -> appPairs.unpair(taskId));
-        return true;
-    }
-
     private boolean runMoveToSideStage(String[] args, PrintWriter pw) {
         if (args.length < 3) {
             // First arguments are "WMShell" and command name.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
index 62fb840..992f315 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellInitImpl.java
@@ -18,7 +18,6 @@
 
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
 
-import com.android.wm.shell.apppairs.AppPairsController;
 import com.android.wm.shell.bubbles.BubbleController;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
@@ -28,13 +27,14 @@
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.freeform.FreeformTaskListener;
 import com.android.wm.shell.fullscreen.FullscreenTaskListener;
-import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
 import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
 import com.android.wm.shell.pip.phone.PipTouchHandler;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.startingsurface.StartingWindowController;
+import com.android.wm.shell.transition.DefaultMixedHandler;
 import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.unfold.UnfoldAnimationController;
 import com.android.wm.shell.unfold.UnfoldTransitionHandler;
 
 import java.util.Optional;
@@ -53,12 +53,11 @@
     private final KidsModeTaskOrganizer mKidsModeTaskOrganizer;
     private final Optional<BubbleController> mBubblesOptional;
     private final Optional<SplitScreenController> mSplitScreenOptional;
-    private final Optional<AppPairsController> mAppPairsOptional;
     private final Optional<PipTouchHandler> mPipTouchHandlerOptional;
     private final FullscreenTaskListener mFullscreenTaskListener;
-    private final Optional<FullscreenUnfoldController> mFullscreenUnfoldController;
+    private final Optional<UnfoldAnimationController> mUnfoldController;
     private final Optional<UnfoldTransitionHandler> mUnfoldTransitionHandler;
-    private final Optional<FreeformTaskListener> mFreeformTaskListenerOptional;
+    private final Optional<FreeformTaskListener<?>> mFreeformTaskListenerOptional;
     private final ShellExecutor mMainExecutor;
     private final Transitions mTransitions;
     private final StartingWindowController mStartingWindow;
@@ -75,12 +74,11 @@
             KidsModeTaskOrganizer kidsModeTaskOrganizer,
             Optional<BubbleController> bubblesOptional,
             Optional<SplitScreenController> splitScreenOptional,
-            Optional<AppPairsController> appPairsOptional,
             Optional<PipTouchHandler> pipTouchHandlerOptional,
             FullscreenTaskListener fullscreenTaskListener,
-            Optional<FullscreenUnfoldController> fullscreenUnfoldTransitionController,
+            Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
-            Optional<FreeformTaskListener> freeformTaskListenerOptional,
+            Optional<FreeformTaskListener<?>> freeformTaskListenerOptional,
             Optional<RecentTasksController> recentTasks,
             Transitions transitions,
             StartingWindowController startingWindow,
@@ -93,10 +91,9 @@
         mKidsModeTaskOrganizer = kidsModeTaskOrganizer;
         mBubblesOptional = bubblesOptional;
         mSplitScreenOptional = splitScreenOptional;
-        mAppPairsOptional = appPairsOptional;
         mFullscreenTaskListener = fullscreenTaskListener;
         mPipTouchHandlerOptional = pipTouchHandlerOptional;
-        mFullscreenUnfoldController = fullscreenUnfoldTransitionController;
+        mUnfoldController = unfoldAnimationController;
         mUnfoldTransitionHandler = unfoldTransitionHandler;
         mFreeformTaskListenerOptional = freeformTaskListenerOptional;
         mRecentTasks = recentTasks;
@@ -121,7 +118,6 @@
         mShellTaskOrganizer.initStartingWindow(mStartingWindow);
         mShellTaskOrganizer.registerOrganizer();
 
-        mAppPairsOptional.ifPresent(AppPairsController::onOrganizerRegistered);
         mSplitScreenOptional.ifPresent(SplitScreenController::onOrganizerRegistered);
         mBubblesOptional.ifPresent(BubbleController::initialize);
 
@@ -131,6 +127,13 @@
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
             mTransitions.register(mShellTaskOrganizer);
             mUnfoldTransitionHandler.ifPresent(UnfoldTransitionHandler::init);
+            if (mSplitScreenOptional.isPresent() && mPipTouchHandlerOptional.isPresent()) {
+                final DefaultMixedHandler mixedHandler = new DefaultMixedHandler(mTransitions,
+                        mPipTouchHandlerOptional.get().getTransitionHandler(),
+                        mSplitScreenOptional.get().getTransitionHandler());
+                // Added at end so that it has highest priority.
+                mTransitions.addHandler(mixedHandler);
+            }
         }
 
         // TODO(b/181599115): This should really be the pip controller, but until we can provide the
@@ -143,7 +146,7 @@
                 mShellTaskOrganizer.addListenerForType(
                         f, ShellTaskOrganizer.TASK_LISTENER_TYPE_FREEFORM));
 
-        mFullscreenUnfoldController.ifPresent(FullscreenUnfoldController::init);
+        mUnfoldController.ifPresent(UnfoldAnimationController::init);
         mRecentTasks.ifPresent(RecentTasksController::init);
 
         // Initialize kids mode task organizer
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 31f0ef01..e9d24fb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -55,6 +55,7 @@
 import com.android.wm.shell.compatui.CompatUIController;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.startingsurface.StartingWindowController;
+import com.android.wm.shell.unfold.UnfoldAnimationController;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -179,33 +180,41 @@
     private final Optional<RecentTasksController> mRecentTasks;
 
     @Nullable
+    private final UnfoldAnimationController mUnfoldAnimationController;
+
+    @Nullable
     private RunningTaskInfo mLastFocusedTaskInfo;
 
     public ShellTaskOrganizer(ShellExecutor mainExecutor, Context context) {
         this(null /* taskOrganizerController */, mainExecutor, context, null /* compatUI */,
+                Optional.empty() /* unfoldAnimationController */,
                 Optional.empty() /* recentTasksController */);
     }
 
     public ShellTaskOrganizer(ShellExecutor mainExecutor, Context context, @Nullable
             CompatUIController compatUI) {
         this(null /* taskOrganizerController */, mainExecutor, context, compatUI,
+                Optional.empty() /* unfoldAnimationController */,
                 Optional.empty() /* recentTasksController */);
     }
 
     public ShellTaskOrganizer(ShellExecutor mainExecutor, Context context, @Nullable
             CompatUIController compatUI,
+            Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<RecentTasksController> recentTasks) {
         this(null /* taskOrganizerController */, mainExecutor, context, compatUI,
-                recentTasks);
+                unfoldAnimationController, recentTasks);
     }
 
     @VisibleForTesting
     protected ShellTaskOrganizer(ITaskOrganizerController taskOrganizerController,
             ShellExecutor mainExecutor, Context context, @Nullable CompatUIController compatUI,
+            Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<RecentTasksController> recentTasks) {
         super(taskOrganizerController, mainExecutor);
         mCompatUI = compatUI;
         mRecentTasks = recentTasks;
+        mUnfoldAnimationController = unfoldAnimationController.orElse(null);
         if (compatUI != null) {
             compatUI.setCompatUICallback(this);
         }
@@ -437,6 +446,9 @@
         if (listener != null) {
             listener.onTaskAppeared(info.getTaskInfo(), info.getLeash());
         }
+        if (mUnfoldAnimationController != null) {
+            mUnfoldAnimationController.onTaskAppeared(info.getTaskInfo(), info.getLeash());
+        }
         notifyLocusVisibilityIfNeeded(info.getTaskInfo());
         notifyCompatUI(info.getTaskInfo(), listener);
     }
@@ -458,6 +470,11 @@
     public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
         synchronized (mLock) {
             ProtoLog.v(WM_SHELL_TASK_ORG, "Task info changed taskId=%d", taskInfo.taskId);
+
+            if (mUnfoldAnimationController != null) {
+                mUnfoldAnimationController.onTaskInfoChanged(taskInfo);
+            }
+
             final TaskAppearedInfo data = mTasks.get(taskInfo.taskId);
             final TaskListener oldListener = getTaskListener(data.getTaskInfo());
             final TaskListener newListener = getTaskListener(taskInfo);
@@ -507,6 +524,10 @@
     public void onTaskVanished(RunningTaskInfo taskInfo) {
         synchronized (mLock) {
             ProtoLog.v(WM_SHELL_TASK_ORG, "Task vanished taskId=%d", taskInfo.taskId);
+            if (mUnfoldAnimationController != null) {
+                mUnfoldAnimationController.onTaskVanished(taskInfo);
+            }
+
             final int taskId = taskInfo.taskId;
             final TaskListener listener = getTaskListener(mTasks.get(taskId).getTaskInfo());
             mTasks.remove(taskId);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java
index 2aead93..a0dde6a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java
@@ -53,6 +53,19 @@
     public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
 
     /**
+     * The accelerated emphasized interpolator. Used for hero / emphasized movement of content that
+     * is disappearing e.g. when moving off screen.
+     */
+    public static final Interpolator EMPHASIZED_ACCELERATE = new PathInterpolator(
+            0.3f, 0f, 0.8f, 0.15f);
+
+    /**
+     * The decelerating emphasized interpolator. Used for hero / emphasized movement of content that
+     * is appearing e.g. when coming from off screen
+     */
+    public static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator(
+            0.05f, 0.7f, 0.1f, 1f);
+    /**
      * Interpolator to be used when animating a move based on a click. Pair with enough duration.
      */
     public static final Interpolator TOUCH_RESPONSE = new PathInterpolator(0.3f, 0f, 0.1f, 1f);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
deleted file mode 100644
index 3f0b01b..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.apppairs;
-
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
-import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
-
-import android.app.ActivityManager;
-import android.view.SurfaceControl;
-import android.view.SurfaceSession;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.protolog.common.ProtoLog;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.DisplayInsetsController;
-import com.android.wm.shell.common.SurfaceUtils;
-import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.common.split.SplitLayout;
-import com.android.wm.shell.common.split.SplitWindowManager;
-
-import java.io.PrintWriter;
-
-/**
- * An app-pairs consisting of {@link #mRootTaskInfo} that acts as the hierarchy parent of
- * {@link #mTaskInfo1} and {@link #mTaskInfo2} in the pair.
- * Also includes all UI for managing the pair like the divider.
- */
-class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayoutHandler {
-    private static final String TAG = AppPair.class.getSimpleName();
-
-    private ActivityManager.RunningTaskInfo mRootTaskInfo;
-    private SurfaceControl mRootTaskLeash;
-    private ActivityManager.RunningTaskInfo mTaskInfo1;
-    private SurfaceControl mTaskLeash1;
-    private ActivityManager.RunningTaskInfo mTaskInfo2;
-    private SurfaceControl mTaskLeash2;
-    private SurfaceControl mDimLayer1;
-    private SurfaceControl mDimLayer2;
-    private final SurfaceSession mSurfaceSession = new SurfaceSession();
-
-    private final AppPairsController mController;
-    private final SyncTransactionQueue mSyncQueue;
-    private final DisplayController mDisplayController;
-    private final DisplayImeController mDisplayImeController;
-    private final DisplayInsetsController mDisplayInsetsController;
-    private SplitLayout mSplitLayout;
-
-    private final SplitWindowManager.ParentContainerCallbacks mParentContainerCallbacks =
-            new SplitWindowManager.ParentContainerCallbacks() {
-        @Override
-        public void attachToParentSurface(SurfaceControl.Builder b) {
-            b.setParent(mRootTaskLeash);
-        }
-
-        @Override
-        public void onLeashReady(SurfaceControl leash) {
-            mSyncQueue.runInSync(t -> t
-                    .show(leash)
-                    .setLayer(leash, Integer.MAX_VALUE)
-                    .setPosition(leash,
-                            mSplitLayout.getDividerBounds().left,
-                            mSplitLayout.getDividerBounds().top));
-        }
-    };
-
-    AppPair(AppPairsController controller) {
-        mController = controller;
-        mSyncQueue = controller.getSyncTransactionQueue();
-        mDisplayController = controller.getDisplayController();
-        mDisplayImeController = controller.getDisplayImeController();
-        mDisplayInsetsController = controller.getDisplayInsetsController();
-    }
-
-    int getRootTaskId() {
-        return mRootTaskInfo != null ? mRootTaskInfo.taskId : INVALID_TASK_ID;
-    }
-
-    private int getTaskId1() {
-        return mTaskInfo1 != null ? mTaskInfo1.taskId : INVALID_TASK_ID;
-    }
-
-    private int getTaskId2() {
-        return mTaskInfo2 != null ? mTaskInfo2.taskId : INVALID_TASK_ID;
-    }
-
-    boolean contains(int taskId) {
-        return taskId == getRootTaskId() || taskId == getTaskId1() || taskId == getTaskId2();
-    }
-
-    boolean pair(ActivityManager.RunningTaskInfo task1, ActivityManager.RunningTaskInfo task2) {
-        ProtoLog.v(WM_SHELL_TASK_ORG, "pair task1=%d task2=%d in AppPair=%s",
-                task1.taskId, task2.taskId, this);
-
-        if (!task1.supportsMultiWindow || !task2.supportsMultiWindow) {
-            ProtoLog.e(WM_SHELL_TASK_ORG,
-                    "Can't pair tasks that doesn't support multi window, "
-                            + "task1.supportsMultiWindow=%b, task2.supportsMultiWindow=%b",
-                    task1.supportsMultiWindow, task2.supportsMultiWindow);
-            return false;
-        }
-
-        mTaskInfo1 = task1;
-        mTaskInfo2 = task2;
-        mSplitLayout = new SplitLayout(TAG + "SplitDivider",
-                mDisplayController.getDisplayContext(mRootTaskInfo.displayId),
-                mRootTaskInfo.configuration, this /* layoutChangeListener */,
-                mParentContainerCallbacks, mDisplayImeController, mController.getTaskOrganizer(),
-                SplitLayout.PARALLAX_DISMISSING);
-        mDisplayInsetsController.addInsetsChangedListener(mRootTaskInfo.displayId, mSplitLayout);
-
-        final WindowContainerToken token1 = task1.token;
-        final WindowContainerToken token2 = task2.token;
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-
-        wct.setHidden(mRootTaskInfo.token, false)
-                .reparent(token1, mRootTaskInfo.token, true /* onTop */)
-                .reparent(token2, mRootTaskInfo.token, true /* onTop */)
-                .setWindowingMode(token1, WINDOWING_MODE_MULTI_WINDOW)
-                .setWindowingMode(token2, WINDOWING_MODE_MULTI_WINDOW)
-                .setBounds(token1, mSplitLayout.getBounds1())
-                .setBounds(token2, mSplitLayout.getBounds2())
-                // Moving the root task to top after the child tasks were repareted , or the root
-                // task cannot be visible and focused.
-                .reorder(mRootTaskInfo.token, true);
-        mController.getTaskOrganizer().applyTransaction(wct);
-        return true;
-    }
-
-    void unpair() {
-        unpair(null /* toTopToken */);
-    }
-
-    private void unpair(@Nullable WindowContainerToken toTopToken) {
-        final WindowContainerToken token1 = mTaskInfo1.token;
-        final WindowContainerToken token2 = mTaskInfo2.token;
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-
-        // Reparent out of this container and reset windowing mode.
-        wct.setHidden(mRootTaskInfo.token, true)
-                .reorder(mRootTaskInfo.token, false)
-                .reparent(token1, null, token1 == toTopToken /* onTop */)
-                .reparent(token2, null, token2 == toTopToken /* onTop */)
-                .setWindowingMode(token1, WINDOWING_MODE_UNDEFINED)
-                .setWindowingMode(token2, WINDOWING_MODE_UNDEFINED);
-        mController.getTaskOrganizer().applyTransaction(wct);
-
-        mTaskInfo1 = null;
-        mTaskInfo2 = null;
-        mSplitLayout.release();
-        mSplitLayout = null;
-    }
-
-    @Override
-    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
-        if (mRootTaskInfo == null || taskInfo.taskId == mRootTaskInfo.taskId) {
-            mRootTaskInfo = taskInfo;
-            mRootTaskLeash = leash;
-        } else if (taskInfo.taskId == getTaskId1()) {
-            mTaskInfo1 = taskInfo;
-            mTaskLeash1 = leash;
-            mSyncQueue.runInSync(t -> mDimLayer1 =
-                    SurfaceUtils.makeDimLayer(t, mTaskLeash1, "Dim layer", mSurfaceSession));
-        } else if (taskInfo.taskId == getTaskId2()) {
-            mTaskInfo2 = taskInfo;
-            mTaskLeash2 = leash;
-            mSyncQueue.runInSync(t -> mDimLayer2 =
-                    SurfaceUtils.makeDimLayer(t, mTaskLeash2, "Dim layer", mSurfaceSession));
-        } else {
-            throw new IllegalStateException("Unknown task=" + taskInfo.taskId);
-        }
-
-        if (mTaskLeash1 == null || mTaskLeash2 == null) return;
-
-        mSplitLayout.init();
-
-        mSyncQueue.runInSync(t -> t
-                .show(mRootTaskLeash)
-                .show(mTaskLeash1)
-                .show(mTaskLeash2)
-                .setPosition(mTaskLeash1,
-                        mTaskInfo1.positionInParent.x,
-                        mTaskInfo1.positionInParent.y)
-                .setPosition(mTaskLeash2,
-                        mTaskInfo2.positionInParent.x,
-                        mTaskInfo2.positionInParent.y));
-    }
-
-    @Override
-    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
-        if (!taskInfo.supportsMultiWindow) {
-            // Dismiss AppPair if the task no longer supports multi window.
-            mController.unpair(mRootTaskInfo.taskId);
-            return;
-        }
-        if (taskInfo.taskId == getRootTaskId()) {
-            if (mRootTaskInfo.isVisible != taskInfo.isVisible) {
-                mSyncQueue.runInSync(t -> {
-                    if (taskInfo.isVisible) {
-                        t.show(mRootTaskLeash);
-                    } else {
-                        t.hide(mRootTaskLeash);
-                    }
-                });
-            }
-            mRootTaskInfo = taskInfo;
-
-            if (mSplitLayout != null
-                    && mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)) {
-                onLayoutSizeChanged(mSplitLayout);
-            }
-        } else if (taskInfo.taskId == getTaskId1()) {
-            mTaskInfo1 = taskInfo;
-        } else if (taskInfo.taskId == getTaskId2()) {
-            mTaskInfo2 = taskInfo;
-        } else {
-            throw new IllegalStateException("Unknown task=" + taskInfo.taskId);
-        }
-    }
-
-    @Override
-    public int getSplitItemPosition(WindowContainerToken token) {
-        if (token == null) {
-            return SPLIT_POSITION_UNDEFINED;
-        }
-
-        if (token.equals(mTaskInfo1.getToken())) {
-            return SPLIT_POSITION_TOP_OR_LEFT;
-        } else if (token.equals(mTaskInfo2.getToken())) {
-            return SPLIT_POSITION_BOTTOM_OR_RIGHT;
-        }
-
-        return SPLIT_POSITION_UNDEFINED;
-    }
-
-    @Override
-    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
-        if (taskInfo.taskId == getRootTaskId()) {
-            // We don't want to release this object back to the pool since the root task went away.
-            mController.unpair(mRootTaskInfo.taskId, false /* releaseToPool */);
-        } else if (taskInfo.taskId == getTaskId1()) {
-            mController.unpair(mRootTaskInfo.taskId);
-            mSyncQueue.runInSync(t -> t.remove(mDimLayer1));
-        } else if (taskInfo.taskId == getTaskId2()) {
-            mController.unpair(mRootTaskInfo.taskId);
-            mSyncQueue.runInSync(t -> t.remove(mDimLayer2));
-        }
-    }
-
-    @Override
-    public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
-        b.setParent(findTaskSurface(taskId));
-    }
-
-    @Override
-    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
-            SurfaceControl.Transaction t) {
-        t.reparent(sc, findTaskSurface(taskId));
-    }
-
-    private SurfaceControl findTaskSurface(int taskId) {
-        if (getRootTaskId() == taskId) {
-            return mRootTaskLeash;
-        } else if (getTaskId1() == taskId) {
-            return mTaskLeash1;
-        } else if (getTaskId2() == taskId) {
-            return mTaskLeash2;
-        } else {
-            throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
-        }
-    }
-
-    @Override
-    public void dump(@NonNull PrintWriter pw, String prefix) {
-        final String innerPrefix = prefix + "  ";
-        final String childPrefix = innerPrefix + "  ";
-        pw.println(prefix + this);
-        if (mRootTaskInfo != null) {
-            pw.println(innerPrefix + "Root taskId=" + mRootTaskInfo.taskId
-                    + " winMode=" + mRootTaskInfo.getWindowingMode());
-        }
-        if (mTaskInfo1 != null) {
-            pw.println(innerPrefix + "1 taskId=" + mTaskInfo1.taskId
-                    + " winMode=" + mTaskInfo1.getWindowingMode());
-        }
-        if (mTaskInfo2 != null) {
-            pw.println(innerPrefix + "2 taskId=" + mTaskInfo2.taskId
-                    + " winMode=" + mTaskInfo2.getWindowingMode());
-        }
-    }
-
-    @Override
-    public String toString() {
-        return TAG + "#" + getRootTaskId();
-    }
-
-    @Override
-    public void onSnappedToDismiss(boolean snappedToEnd) {
-        unpair(snappedToEnd ? mTaskInfo1.token : mTaskInfo2.token /* toTopToken */);
-    }
-
-    @Override
-    public void onLayoutPositionChanging(SplitLayout layout) {
-        mSyncQueue.runInSync(t ->
-                layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2,
-                        true /* applyResizingOffset */));
-    }
-
-    @Override
-    public void onLayoutSizeChanging(SplitLayout layout) {
-        mSyncQueue.runInSync(t ->
-                layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2,
-                        true /* applyResizingOffset */));
-    }
-
-    @Override
-    public void onLayoutSizeChanged(SplitLayout layout) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        layout.applyTaskChanges(wct, mTaskInfo1, mTaskInfo2);
-        mSyncQueue.queue(wct);
-        mSyncQueue.runInSync(t ->
-                layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2,
-                        false /* applyResizingOffset */));
-    }
-
-    @Override
-    public void setLayoutOffsetTarget(int offsetX, int offsetY, SplitLayout layout) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        layout.applyLayoutOffsetTarget(wct, offsetX, offsetY, mTaskInfo1, mTaskInfo2);
-        mController.getTaskOrganizer().applyTransaction(wct);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java
deleted file mode 100644
index a9b1dbc..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairs.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.apppairs;
-
-import android.app.ActivityManager;
-
-import androidx.annotation.NonNull;
-
-import com.android.wm.shell.common.annotations.ExternalThread;
-
-import java.io.PrintWriter;
-
-/**
- * Interface to engage app pairs feature.
- */
-@ExternalThread
-public interface AppPairs {
-    /** Pairs indicated tasks. */
-    boolean pair(int task1, int task2);
-    /** Pairs indicated tasks. */
-    boolean pair(ActivityManager.RunningTaskInfo task1, ActivityManager.RunningTaskInfo task2);
-    /** Unpairs any app-pair containing this task id. */
-    void unpair(int taskId);
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java
deleted file mode 100644
index 53234ab..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsController.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.apppairs;
-
-import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
-
-import android.app.ActivityManager;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.DisplayInsetsController;
-import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.SyncTransactionQueue;
-
-import java.io.PrintWriter;
-
-/**
- * Class manages app-pairs multitasking mode and implements the main interface {@link AppPairs}.
- */
-public class AppPairsController {
-    private static final String TAG = AppPairsController.class.getSimpleName();
-
-    private final ShellTaskOrganizer mTaskOrganizer;
-    private final SyncTransactionQueue mSyncQueue;
-    private final ShellExecutor mMainExecutor;
-    private final AppPairsImpl mImpl = new AppPairsImpl();
-
-    private AppPairsPool mPairsPool;
-    // Active app-pairs mapped by root task id key.
-    private final SparseArray<AppPair> mActiveAppPairs = new SparseArray<>();
-    private final DisplayController mDisplayController;
-    private final DisplayImeController mDisplayImeController;
-    private final DisplayInsetsController mDisplayInsetsController;
-
-    public AppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
-            DisplayController displayController, ShellExecutor mainExecutor,
-            DisplayImeController displayImeController,
-            DisplayInsetsController displayInsetsController) {
-        mTaskOrganizer = organizer;
-        mSyncQueue = syncQueue;
-        mDisplayController = displayController;
-        mDisplayImeController = displayImeController;
-        mDisplayInsetsController = displayInsetsController;
-        mMainExecutor = mainExecutor;
-    }
-
-    public AppPairs asAppPairs() {
-        return mImpl;
-    }
-
-    public void onOrganizerRegistered() {
-        if (mPairsPool == null) {
-            setPairsPool(new AppPairsPool(this));
-        }
-    }
-
-    @VisibleForTesting
-    public void setPairsPool(AppPairsPool pool) {
-        mPairsPool = pool;
-    }
-
-    public boolean pair(int taskId1, int taskId2) {
-        final ActivityManager.RunningTaskInfo task1 = mTaskOrganizer.getRunningTaskInfo(taskId1);
-        final ActivityManager.RunningTaskInfo task2 = mTaskOrganizer.getRunningTaskInfo(taskId2);
-        if (task1 == null || task2 == null) {
-            return false;
-        }
-        return pair(task1, task2);
-    }
-
-    public boolean pair(ActivityManager.RunningTaskInfo task1,
-            ActivityManager.RunningTaskInfo task2) {
-        return pairInner(task1, task2) != null;
-    }
-
-    @VisibleForTesting
-    public AppPair pairInner(
-            @NonNull ActivityManager.RunningTaskInfo task1,
-            @NonNull ActivityManager.RunningTaskInfo task2) {
-        final AppPair pair = mPairsPool.acquire();
-        if (!pair.pair(task1, task2)) {
-            mPairsPool.release(pair);
-            return null;
-        }
-
-        mActiveAppPairs.put(pair.getRootTaskId(), pair);
-        return pair;
-    }
-
-    public void unpair(int taskId) {
-        unpair(taskId, true /* releaseToPool */);
-    }
-
-    public void unpair(int taskId, boolean releaseToPool) {
-        AppPair pair = mActiveAppPairs.get(taskId);
-        if (pair == null) {
-            for (int i = mActiveAppPairs.size() - 1; i >= 0; --i) {
-                final AppPair candidate = mActiveAppPairs.valueAt(i);
-                if (candidate.contains(taskId)) {
-                    pair = candidate;
-                    break;
-                }
-            }
-        }
-        if (pair == null) {
-            ProtoLog.v(WM_SHELL_TASK_ORG, "taskId %d isn't isn't in an app-pair.", taskId);
-            return;
-        }
-
-        ProtoLog.v(WM_SHELL_TASK_ORG, "unpair taskId=%d pair=%s", taskId, pair);
-        mActiveAppPairs.remove(pair.getRootTaskId());
-        pair.unpair();
-        if (releaseToPool) {
-            mPairsPool.release(pair);
-        }
-    }
-
-    ShellTaskOrganizer getTaskOrganizer() {
-        return mTaskOrganizer;
-    }
-
-    SyncTransactionQueue getSyncTransactionQueue() {
-        return mSyncQueue;
-    }
-
-    DisplayController getDisplayController() {
-        return mDisplayController;
-    }
-
-    DisplayImeController getDisplayImeController() {
-        return mDisplayImeController;
-    }
-
-    DisplayInsetsController getDisplayInsetsController() {
-        return mDisplayInsetsController;
-    }
-
-    public void dump(@NonNull PrintWriter pw, String prefix) {
-        final String innerPrefix = prefix + "  ";
-        final String childPrefix = innerPrefix + "  ";
-        pw.println(prefix + this);
-
-        for (int i = mActiveAppPairs.size() - 1; i >= 0; --i) {
-            mActiveAppPairs.valueAt(i).dump(pw, childPrefix);
-        }
-
-        if (mPairsPool != null) {
-            mPairsPool.dump(pw, prefix);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return TAG + "#" + mActiveAppPairs.size();
-    }
-
-    private class AppPairsImpl implements AppPairs {
-        @Override
-        public boolean pair(int task1, int task2) {
-            boolean[] result = new boolean[1];
-            try {
-                mMainExecutor.executeBlocking(() -> {
-                    result[0] = AppPairsController.this.pair(task1, task2);
-                });
-            } catch (InterruptedException e) {
-                Slog.e(TAG, "Failed to pair tasks: " + task1 + ", " + task2);
-            }
-            return result[0];
-        }
-
-        @Override
-        public boolean pair(ActivityManager.RunningTaskInfo task1,
-                ActivityManager.RunningTaskInfo task2) {
-            boolean[] result = new boolean[1];
-            try {
-                mMainExecutor.executeBlocking(() -> {
-                    result[0] = AppPairsController.this.pair(task1, task2);
-                });
-            } catch (InterruptedException e) {
-                Slog.e(TAG, "Failed to pair tasks: " + task1 + ", " + task2);
-            }
-            return result[0];
-        }
-
-        @Override
-        public void unpair(int taskId) {
-            mMainExecutor.execute(() -> {
-                AppPairsController.this.unpair(taskId);
-            });
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsPool.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsPool.java
deleted file mode 100644
index 5c6037e..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPairsPool.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.apppairs;
-
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/**
- * Class that manager pool of {@link AppPair} objects. Helps reduce the need to call system_server
- *  to create a root task for the app-pair when needed since we always have one ready to go.
- */
-class AppPairsPool {
-    private static final String TAG = AppPairsPool.class.getSimpleName();
-
-    @VisibleForTesting
-    final AppPairsController mController;
-    // The pool
-    private final ArrayList<AppPair> mPool = new ArrayList();
-
-    AppPairsPool(AppPairsController controller) {
-        mController = controller;
-        incrementPool();
-    }
-
-    AppPair acquire() {
-        final AppPair entry = mPool.remove(mPool.size() - 1);
-        ProtoLog.v(WM_SHELL_TASK_ORG, "acquire entry.taskId=%s listener=%s size=%d",
-                entry.getRootTaskId(), entry, mPool.size());
-        if (mPool.size() == 0) {
-            incrementPool();
-        }
-        return entry;
-    }
-
-    void release(AppPair entry) {
-        mPool.add(entry);
-        ProtoLog.v(WM_SHELL_TASK_ORG, "release entry.taskId=%s listener=%s size=%d",
-                entry.getRootTaskId(), entry, mPool.size());
-    }
-
-    @VisibleForTesting
-    void incrementPool() {
-        ProtoLog.v(WM_SHELL_TASK_ORG, "incrementPool size=%d", mPool.size());
-        final AppPair entry = new AppPair(mController);
-        // TODO: multi-display...
-        mController.getTaskOrganizer().createRootTask(
-                DEFAULT_DISPLAY, WINDOWING_MODE_FULLSCREEN, entry);
-        mPool.add(entry);
-    }
-
-    @VisibleForTesting
-    int poolSize() {
-        return mPool.size();
-    }
-
-    public void dump(@NonNull PrintWriter pw, String prefix) {
-        final String innerPrefix = prefix + "  ";
-        final String childPrefix = innerPrefix + "  ";
-        pw.println(prefix + this);
-        for (int i = mPool.size() - 1; i >= 0; --i) {
-            mPool.get(i).dump(pw, childPrefix);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return TAG + "#" + mPool.size();
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/OWNERS
deleted file mode 100644
index 4d9b520..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# WM shell sub-modules apppair owner
-chenghsiuchang@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index f427a2c..a2c4055 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -25,6 +25,7 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_CONTROLLER;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_GESTURE;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.wm.shell.bubbles.BubblePositioner.TASKBAR_POSITION_BOTTOM;
@@ -79,7 +80,6 @@
 import android.view.ViewGroup;
 import android.view.WindowInsets;
 import android.view.WindowManager;
-import android.window.WindowContainerTransaction;
 
 import androidx.annotation.MainThread;
 import androidx.annotation.Nullable;
@@ -90,7 +90,6 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.TaskViewTransitions;
 import com.android.wm.shell.WindowManagerShellWrapper;
-import com.android.wm.shell.common.DisplayChangeController;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.ShellExecutor;
@@ -435,17 +434,13 @@
         });
 
         mDisplayController.addDisplayChangingController(
-                new DisplayChangeController.OnDisplayChangingListener() {
-                    @Override
-                    public void onRotateDisplay(int displayId, int fromRotation, int toRotation,
-                            WindowContainerTransaction t) {
-                        // This is triggered right before the rotation is applied
-                        if (fromRotation != toRotation) {
-                            if (mStackView != null) {
-                                // Layout listener set on stackView will update the positioner
-                                // once the rotation is applied
-                                mStackView.onOrientationChanged();
-                            }
+                (displayId, fromRotation, toRotation, newDisplayAreaInfo, t) -> {
+                    // This is triggered right before the rotation is applied
+                    if (fromRotation != toRotation) {
+                        if (mStackView != null) {
+                            // Layout listener set on stackView will update the positioner
+                            // once the rotation is applied
+                            mStackView.onOrientationChanged();
                         }
                     }
                 });
@@ -885,6 +880,19 @@
         }
     }
 
+    private void onNotificationPanelExpandedChanged(boolean expanded) {
+        if (DEBUG_BUBBLE_GESTURE) {
+            Log.d(TAG, "onNotificationPanelExpandedChanged: expanded=" + expanded);
+        }
+        if (mStackView != null && mStackView.isExpanded()) {
+            if (expanded) {
+                mStackView.stopMonitoringSwipeUpGesture();
+            } else {
+                mStackView.startMonitoringSwipeUpGesture();
+            }
+        }
+    }
+
     private void setSysuiProxy(Bubbles.SysuiProxy proxy) {
         mSysuiProxy = proxy;
     }
@@ -1342,14 +1350,18 @@
                 mStackView.setBubbleSuppressed(update.unsuppressedBubble, false);
             }
 
+            boolean collapseStack = update.expandedChanged && !update.expanded;
+
             // At this point, the correct bubbles are inflated in the stack.
             // Make sure the order in bubble data is reflected in bubble row.
             if (update.orderChanged && mStackView != null) {
                 mDataRepository.addBubbles(mCurrentUserId, update.bubbles);
-                mStackView.updateBubbleOrder(update.bubbles);
+                // if the stack is going to be collapsed, do not update pointer position
+                // after reordering
+                mStackView.updateBubbleOrder(update.bubbles, !collapseStack);
             }
 
-            if (update.expandedChanged && !update.expanded) {
+            if (collapseStack) {
                 mStackView.setExpanded(false);
                 mSysuiProxy.requestNotificationShadeTopUi(false, TAG);
             }
@@ -1468,6 +1480,18 @@
     }
 
     /**
+     * Check if notification panel is in an expanded state.
+     * Makes a call to System UI process and delivers the result via {@code callback} on the
+     * WM Shell main thread.
+     *
+     * @param callback callback that has the result of notification panel expanded state
+     */
+    public void isNotificationPanelExpanded(Consumer<Boolean> callback) {
+        mSysuiProxy.isNotificationPanelExpand(expanded ->
+                mMainExecutor.execute(() -> callback.accept(expanded)));
+    }
+
+    /**
      * Description of current bubble state.
      */
     private void dump(PrintWriter pw, String[] args) {
@@ -1546,7 +1570,7 @@
         public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
             mBubblePositioner.setImeVisible(imeVisible, imeHeight);
             if (mStackView != null) {
-                mStackView.animateForIme(imeVisible);
+                mStackView.setImeVisible(imeVisible);
             }
         }
     }
@@ -1843,6 +1867,12 @@
         }
 
         @Override
+        public void onNotificationPanelExpandedChanged(boolean expanded) {
+            mMainExecutor.execute(
+                    () -> BubbleController.this.onNotificationPanelExpandedChanged(expanded));
+        }
+
+        @Override
         public void dump(PrintWriter pw, String[] args) {
             try {
                 mMainExecutor.executeBlocking(() -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java
index dc2ace9..dce6b56 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java
@@ -46,6 +46,9 @@
     static final boolean DEBUG_OVERFLOW = false;
     static final boolean DEBUG_USER_EDUCATION = false;
     static final boolean DEBUG_POSITIONER = false;
+    public static final boolean DEBUG_COLLAPSE_ANIMATOR = false;
+    static final boolean DEBUG_BUBBLE_GESTURE = false;
+    public static boolean DEBUG_EXPANDED_VIEW_DRAGGING = false;
 
     private static final boolean FORCE_SHOW_USER_EDUCATION = false;
     private static final String FORCE_SHOW_USER_EDUCATION_SETTING =
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 b8bf1a8..4f225ff 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
@@ -43,10 +43,13 @@
 import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.Picture;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.drawable.ShapeDrawable;
 import android.os.RemoteException;
 import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.util.IntProperty;
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
@@ -75,6 +78,62 @@
 public class BubbleExpandedView extends LinearLayout {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleExpandedView" : TAG_BUBBLES;
 
+    /** {@link IntProperty} for updating bottom clip */
+    public static final IntProperty<BubbleExpandedView> BOTTOM_CLIP_PROPERTY =
+            new IntProperty<BubbleExpandedView>("bottomClip") {
+                @Override
+                public void setValue(BubbleExpandedView expandedView, int value) {
+                    expandedView.setBottomClip(value);
+                }
+
+                @Override
+                public Integer get(BubbleExpandedView expandedView) {
+                    return expandedView.mBottomClip;
+                }
+            };
+
+    /** {@link FloatProperty} for updating taskView or overflow alpha */
+    public static final FloatProperty<BubbleExpandedView> CONTENT_ALPHA =
+            new FloatProperty<BubbleExpandedView>("contentAlpha") {
+                @Override
+                public void setValue(BubbleExpandedView expandedView, float value) {
+                    expandedView.setContentAlpha(value);
+                }
+
+                @Override
+                public Float get(BubbleExpandedView expandedView) {
+                    return expandedView.getContentAlpha();
+                }
+            };
+
+    /** {@link FloatProperty} for updating background and pointer alpha */
+    public static final FloatProperty<BubbleExpandedView> BACKGROUND_ALPHA =
+            new FloatProperty<BubbleExpandedView>("backgroundAlpha") {
+                @Override
+                public void setValue(BubbleExpandedView expandedView, float value) {
+                    expandedView.setBackgroundAlpha(value);
+                }
+
+                @Override
+                public Float get(BubbleExpandedView expandedView) {
+                    return expandedView.getAlpha();
+                }
+            };
+
+    /** {@link FloatProperty} for updating manage button alpha */
+    public static final FloatProperty<BubbleExpandedView> MANAGE_BUTTON_ALPHA =
+            new FloatProperty<BubbleExpandedView>("manageButtonAlpha") {
+                @Override
+                public void setValue(BubbleExpandedView expandedView, float value) {
+                    expandedView.mManageButton.setAlpha(value);
+                }
+
+                @Override
+                public Float get(BubbleExpandedView expandedView) {
+                    return expandedView.mManageButton.getAlpha();
+                }
+            };
+
     // The triangle pointing to the expanded view
     private View mPointerView;
     @Nullable private int[] mExpandedViewContainerLocation;
@@ -90,7 +149,7 @@
 
     /**
      * Whether we want the {@code TaskView}'s content to be visible (alpha = 1f). If
-     * {@link #mIsAlphaAnimating} is true, this may not reflect the {@code TaskView}'s actual alpha
+     * {@link #mIsAnimating} is true, this may not reflect the {@code TaskView}'s actual alpha
      * value until the animation ends.
      */
     private boolean mIsContentVisible = false;
@@ -99,12 +158,13 @@
      * Whether we're animating the {@code TaskView}'s alpha value. If so, we will hold off on
      * applying alpha changes from {@link #setContentVisibility} until the animation ends.
      */
-    private boolean mIsAlphaAnimating = false;
+    private boolean mIsAnimating = false;
 
     private int mPointerWidth;
     private int mPointerHeight;
     private float mPointerRadius;
     private float mPointerOverlap;
+    private final PointF mPointerPos = new PointF();
     private CornerPathEffect mPointerEffect;
     private ShapeDrawable mCurrentPointer;
     private ShapeDrawable mTopPointer;
@@ -113,11 +173,13 @@
     private float mCornerRadius = 0f;
     private int mBackgroundColorFloating;
     private boolean mUsingMaxHeight;
-
+    private int mTopClip = 0;
+    private int mBottomClip = 0;
     @Nullable private Bubble mBubble;
     private PendingIntent mPendingIntent;
     // TODO(b/170891664): Don't use a flag, set the BubbleOverflow object instead
     private boolean mIsOverflow;
+    private boolean mIsClipping;
 
     private BubbleController mController;
     private BubbleStackView mStackView;
@@ -268,7 +330,8 @@
         mExpandedViewContainer.setOutlineProvider(new ViewOutlineProvider() {
             @Override
             public void getOutline(View view, Outline outline) {
-                outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mCornerRadius);
+                Rect clip = new Rect(0, mTopClip, view.getWidth(), view.getHeight() - mBottomClip);
+                outline.setRoundRect(clip, mCornerRadius);
             }
         });
         mExpandedViewContainer.setClipToOutline(true);
@@ -300,9 +363,9 @@
             // they should not collapse the stack (which all other touches on areas around the AV
             // would do).
             if (motionEvent.getRawY() >= avBounds.top
-                            && motionEvent.getRawY() <= avBounds.bottom
-                            && (motionEvent.getRawX() < avBounds.left
-                                || motionEvent.getRawX() > avBounds.right)) {
+                    && motionEvent.getRawY() <= avBounds.bottom
+                    && (motionEvent.getRawX() < avBounds.left
+                    || motionEvent.getRawX() > avBounds.right)) {
                 return true;
             }
 
@@ -384,7 +447,7 @@
     }
 
     void applyThemeAttrs() {
-        final TypedArray ta = mContext.obtainStyledAttributes(new int[] {
+        final TypedArray ta = mContext.obtainStyledAttributes(new int[]{
                 android.R.attr.dialogCornerRadius,
                 android.R.attr.colorBackgroundFloating});
         boolean supportsRoundedCorners = ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
@@ -429,7 +492,7 @@
      * ordering surfaces during animations. When content is drawn on top of the app (e.g. bubble
      * being dragged out, the manage menu) this is set to false, otherwise it should be true.
      */
-    void setSurfaceZOrderedOnTop(boolean onTop) {
+    public void setSurfaceZOrderedOnTop(boolean onTop) {
         if (mTaskView == null) {
             return;
         }
@@ -510,12 +573,12 @@
     }
 
     /**
-     * Whether we are currently animating the {@code TaskView}'s alpha value. If this is set to
+     * Whether we are currently animating the {@code TaskView}. If this is set to
      * true, calls to {@link #setContentVisibility} will not be applied until this is set to false
      * again.
      */
-    void setAlphaAnimating(boolean animating) {
-        mIsAlphaAnimating = animating;
+    public void setAnimating(boolean animating) {
+        mIsAnimating = animating;
 
         // If we're done animating, apply the correct
         if (!animating) {
@@ -524,18 +587,139 @@
     }
 
     /**
-     * Sets the alpha of the underlying {@code TaskView}, since changing the expanded view's alpha
-     * does not affect the {@code TaskView} since it uses a Surface.
+     * Get alpha from underlying {@code TaskView} if this view is for a bubble.
+     * Or get alpha for the overflow view if this view is for overflow.
+     *
+     * @return alpha for the content being shown
      */
-    void setTaskViewAlpha(float alpha) {
+    public float getContentAlpha() {
+        if (mIsOverflow) {
+            return mOverflowView.getAlpha();
+        }
         if (mTaskView != null) {
+            return mTaskView.getAlpha();
+        }
+        return 1f;
+    }
+
+    /**
+     * Set alpha of the underlying {@code TaskView} if this view is for a bubble.
+     * Or set alpha for the overflow view if this view is for overflow.
+     *
+     * Changing expanded view's alpha does not affect the {@code TaskView} since it uses a Surface.
+     */
+    public void setContentAlpha(float alpha) {
+        if (mIsOverflow) {
+            mOverflowView.setAlpha(alpha);
+        } else if (mTaskView != null) {
             mTaskView.setAlpha(alpha);
         }
+    }
+
+    /**
+     * Sets the alpha of the background and the pointer view.
+     */
+    public void setBackgroundAlpha(float alpha) {
         mPointerView.setAlpha(alpha);
         setAlpha(alpha);
     }
 
     /**
+     * Set translation Y for the expanded view content.
+     * Excludes manage button and pointer.
+     */
+    public void setContentTranslationY(float translationY) {
+        mExpandedViewContainer.setTranslationY(translationY);
+
+        // Left or right pointer can become detached when moving the view up
+        if (translationY <= 0 && (isShowingLeftPointer() || isShowingRightPointer())) {
+            // Y coordinate where the pointer would start to get detached from the expanded view.
+            // Takes into account bottom clipping and rounded corners
+            float detachPoint =
+                    mExpandedViewContainer.getBottom() - mBottomClip - mCornerRadius + translationY;
+            float pointerBottom = mPointerPos.y + mPointerHeight;
+            // If pointer bottom is past detach point, move it in by that many pixels
+            float horizontalShift = 0;
+            if (pointerBottom > detachPoint) {
+                horizontalShift = pointerBottom - detachPoint;
+            }
+            if (isShowingLeftPointer()) {
+                // Move left pointer right
+                movePointerBy(horizontalShift, 0);
+            } else {
+                // Move right pointer left
+                movePointerBy(-horizontalShift, 0);
+            }
+            // Hide pointer if it is moved by entire width
+            mPointerView.setVisibility(
+                    horizontalShift > mPointerWidth ? View.INVISIBLE : View.VISIBLE);
+        }
+    }
+
+    /**
+     * Update alpha value for the manage button
+     */
+    public void setManageButtonAlpha(float alpha) {
+        mManageButton.setAlpha(alpha);
+    }
+
+    /**
+     * Set {@link #setTranslationY(float) translationY} for the manage button
+     */
+    public void setManageButtonTranslationY(float translationY) {
+        mManageButton.setTranslationY(translationY);
+    }
+
+    /**
+     * Set top clipping for the view
+     */
+    public void setTopClip(int clip) {
+        mTopClip = clip;
+        onContainerClipUpdate();
+    }
+
+    /**
+     * Set bottom clipping for the view
+     */
+    public void setBottomClip(int clip) {
+        mBottomClip = clip;
+        onContainerClipUpdate();
+    }
+
+    private void onContainerClipUpdate() {
+        if (mTopClip == 0 && mBottomClip == 0) {
+            if (mIsClipping) {
+                mIsClipping = false;
+                if (mTaskView != null) {
+                    mTaskView.setClipBounds(null);
+                    mTaskView.setEnableSurfaceClipping(false);
+                }
+                mExpandedViewContainer.invalidateOutline();
+            }
+        } else {
+            if (!mIsClipping) {
+                mIsClipping = true;
+                if (mTaskView != null) {
+                    mTaskView.setEnableSurfaceClipping(true);
+                }
+            }
+            mExpandedViewContainer.invalidateOutline();
+            if (mTaskView != null) {
+                mTaskView.setClipBounds(new Rect(0, mTopClip, mTaskView.getWidth(),
+                        mTaskView.getHeight() - mBottomClip));
+            }
+        }
+    }
+
+    /**
+     * Move pointer from base position
+     */
+    public void movePointerBy(float x, float y) {
+        mPointerView.setTranslationX(mPointerPos.x + x);
+        mPointerView.setTranslationY(mPointerPos.y + y);
+    }
+
+    /**
      * Set visibility of contents in the expanded state.
      *
      * @param visibility {@code true} if the contents should be visible on the screen.
@@ -543,13 +727,13 @@
      * Note that this contents visibility doesn't affect visibility at {@link android.view.View},
      * and setting {@code false} actually means rendering the contents in transparent.
      */
-    void setContentVisibility(boolean visibility) {
+    public void setContentVisibility(boolean visibility) {
         if (DEBUG_BUBBLE_EXPANDED_VIEW) {
             Log.d(TAG, "setContentVisibility: visibility=" + visibility
                     + " bubble=" + getBubbleKey());
         }
         mIsContentVisible = visibility;
-        if (mTaskView != null && !mIsAlphaAnimating) {
+        if (mTaskView != null && !mIsAnimating) {
             mTaskView.setAlpha(visibility ? 1f : 0f);
             mPointerView.setAlpha(visibility ? 1f : 0f);
         }
@@ -560,6 +744,44 @@
         return mTaskView;
     }
 
+    @VisibleForTesting
+    public BubbleOverflowContainerView getOverflow() {
+        return mOverflowView;
+    }
+
+
+    /**
+     * Return content height: taskView or overflow.
+     * Takes into account clippings set by {@link #setTopClip(int)} and {@link #setBottomClip(int)}
+     *
+     * @return if bubble is for overflow, return overflow height, otherwise return taskView height
+     */
+    public int getContentHeight() {
+        if (mIsOverflow) {
+            return mOverflowView.getHeight() - mTopClip - mBottomClip;
+        }
+        if (mTaskView != null) {
+            return mTaskView.getHeight() - mTopClip - mBottomClip;
+        }
+        return 0;
+    }
+
+    /**
+     * Return bottom position of the content on screen
+     *
+     * @return if bubble is for overflow, return value for overflow, otherwise taskView
+     */
+    public int getContentBottomOnScreen() {
+        Rect out = new Rect();
+        if (mIsOverflow) {
+            mOverflowView.getBoundsOnScreen(out);
+        }
+        if (mTaskView != null) {
+            mTaskView.getBoundsOnScreen(out);
+        }
+        return out.bottom;
+    }
+
     int getTaskId() {
         return mTaskId;
     }
@@ -687,7 +909,9 @@
             mTaskView.onLocationChanged();
         }
         if (mIsOverflow) {
-            mOverflowView.show();
+            post(() -> {
+                mOverflowView.show();
+            });
         }
     }
 
@@ -730,38 +954,59 @@
         post(() -> {
             mCurrentPointer = showVertically ? onLeft ? mLeftPointer : mRightPointer : mTopPointer;
             updatePointerView();
-            float pointerY;
-            float pointerX;
             if (showVertically) {
-                pointerY = bubbleCenter - (mPointerWidth / 2f);
+                mPointerPos.y = bubbleCenter - (mPointerWidth / 2f);
                 if (!isRtl) {
-                    pointerX = onLeft
+                    mPointerPos.x = onLeft
                             ? -mPointerHeight + mPointerOverlap
                             : getWidth() - mPaddingRight - mPointerOverlap;
                 } else {
-                    pointerX = onLeft
+                    mPointerPos.x = onLeft
                             ? -(getWidth() - mPaddingLeft - mPointerOverlap)
                             : mPointerHeight - mPointerOverlap;
                 }
             } else {
-                pointerY = mPointerOverlap;
+                mPointerPos.y = mPointerOverlap;
                 if (!isRtl) {
-                    pointerX = bubbleCenter - (mPointerWidth / 2f);
+                    mPointerPos.x = bubbleCenter - (mPointerWidth / 2f);
                 } else {
-                    pointerX = -(getWidth() - mPaddingLeft - bubbleCenter) + (mPointerWidth / 2f);
+                    mPointerPos.x = -(getWidth() - mPaddingLeft - bubbleCenter)
+                      + (mPointerWidth / 2f);
                 }
             }
             if (animate) {
-                mPointerView.animate().translationX(pointerX).translationY(pointerY).start();
+                mPointerView.animate().translationX(mPointerPos.x).translationY(
+                        mPointerPos.y).start();
             } else {
-                mPointerView.setTranslationY(pointerY);
-                mPointerView.setTranslationX(pointerX);
+                mPointerView.setTranslationY(mPointerPos.y);
+                mPointerView.setTranslationX(mPointerPos.x);
                 mPointerView.setVisibility(VISIBLE);
             }
         });
     }
 
     /**
+     * Return true if pointer is shown on the left
+     */
+    public boolean isShowingLeftPointer() {
+        return mCurrentPointer == mLeftPointer;
+    }
+
+    /**
+     * Return true if pointer is shown on the right
+     */
+    public boolean isShowingRightPointer() {
+        return mCurrentPointer == mRightPointer;
+    }
+
+    /**
+     * Return width of the current pointer
+     */
+    public int getPointerWidth() {
+        return mPointerWidth;
+    }
+
+    /**
      * Position of the manage button displayed in the expanded view. Used for placing user
      * education about the manage button.
      */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
index fcd0ed7..9aa285f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
@@ -167,7 +167,10 @@
 
     void updateOverflow() {
         Resources res = getResources();
-        final int columns = res.getInteger(R.integer.bubbles_overflow_columns);
+        int columns = (int) Math.round(getWidth()
+                / (res.getDimension(R.dimen.bubble_name_width)));
+        columns = columns > 0 ? columns : res.getInteger(R.integer.bubbles_overflow_columns);
+
         mRecyclerView.setLayoutManager(
                 new OverflowGridLayoutManager(getContext(), columns));
         if (mRecyclerView.getItemDecorationCount() == 0) {
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 e9729e4..dbad5df 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
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.bubbles;
 
+import static android.view.View.LAYOUT_DIRECTION_RTL;
+
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.annotation.IntDef;
@@ -28,7 +30,6 @@
 import android.graphics.RectF;
 import android.util.Log;
 import android.view.Surface;
-import android.view.View;
 import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.WindowMetrics;
@@ -366,6 +367,14 @@
         return mImeVisible ? mImeHeight : 0;
     }
 
+    /** Return top position of the IME if it's visible */
+    public int getImeTop() {
+        if (mImeVisible) {
+            return getScreenRect().bottom - getImeHeight() - getInsets().bottom;
+        }
+        return 0;
+    }
+
     /** Sets whether the IME is visible. **/
     public void setImeVisible(boolean visible, int height) {
         mImeVisible = visible;
@@ -557,16 +566,30 @@
      * @return the position of the bubble on-screen when the stack is expanded.
      */
     public PointF getExpandedBubbleXY(int index, BubbleStackView.StackViewState state) {
-        final float positionInRow = index * (mBubbleSize + mSpacingBetweenBubbles);
+        boolean showBubblesVertically = showBubblesVertically();
+        boolean isRtl = mContext.getResources().getConfiguration().getLayoutDirection()
+                == LAYOUT_DIRECTION_RTL;
+
+        int onScreenIndex;
+        if (showBubblesVertically || !isRtl) {
+            onScreenIndex = index;
+        } else {
+            // If bubbles are shown horizontally, check if RTL language is used.
+            // If RTL is active, position first bubble on the right and last on the left.
+            // Last bubble has screen index 0 and first bubble has max screen index value.
+            onScreenIndex = state.numberOfBubbles - 1 - index;
+        }
+
+        final float positionInRow = onScreenIndex * (mBubbleSize + mSpacingBetweenBubbles);
         final float expandedStackSize = getExpandedStackSize(state.numberOfBubbles);
-        final float centerPosition = showBubblesVertically()
+        final float centerPosition = showBubblesVertically
                 ? mPositionRect.centerY()
                 : mPositionRect.centerX();
         // alignment - centered on the edge
         final float rowStart = centerPosition - (expandedStackSize / 2f);
         float x;
         float y;
-        if (showBubblesVertically()) {
+        if (showBubblesVertically) {
             int inset = mExpandedViewLargeScreenInsetClosestEdge;
             y = rowStart + positionInRow;
             int left = mIsLargeScreen
@@ -583,8 +606,8 @@
             x = rowStart + positionInRow;
         }
 
-        if (showBubblesVertically() && mImeVisible) {
-            return new PointF(x, getExpandedBubbleYForIme(index, state));
+        if (showBubblesVertically && mImeVisible) {
+            return new PointF(x, getExpandedBubbleYForIme(onScreenIndex, state));
         }
         return new PointF(x, y);
     }
@@ -693,7 +716,7 @@
         // Start on the left if we're in LTR, right otherwise.
         final boolean startOnLeft =
                 mContext.getResources().getConfiguration().getLayoutDirection()
-                        != View.LAYOUT_DIRECTION_RTL;
+                        != LAYOUT_DIRECTION_RTL;
         final float startingVerticalOffset = mContext.getResources().getDimensionPixelOffset(
                 R.dimen.bubble_stack_starting_offset_y);
         // TODO: placement bug here because mPositionRect doesn't handle the overhanging edge
@@ -749,4 +772,21 @@
     public void setPinnedLocation(PointF point) {
         mPinLocation = point;
     }
+
+    /**
+     * Navigation bar has an area where system gestures can be started from.
+     *
+     * @return {@link Rect} for system navigation bar gesture zone
+     */
+    public Rect getNavBarGestureZone() {
+        // Gesture zone height from the bottom
+        int gestureZoneHeight = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.navigation_bar_gesture_height);
+        Rect screen = getScreenRect();
+        return new Rect(
+                screen.left,
+                screen.bottom - gestureZoneHeight,
+                screen.right,
+                screen.bottom);
+    }
 }
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 0a33414..2d0be06 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
@@ -21,6 +21,7 @@
 
 import static com.android.wm.shell.animation.Interpolators.ALPHA_IN;
 import static com.android.wm.shell.animation.Interpolators.ALPHA_OUT;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_GESTURE;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_STACK_VIEW;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
@@ -44,6 +45,7 @@
 import android.graphics.RectF;
 import android.graphics.drawable.ColorDrawable;
 import android.os.Bundle;
+import android.os.SystemProperties;
 import android.provider.Settings;
 import android.util.Log;
 import android.view.Choreographer;
@@ -56,6 +58,7 @@
 import android.view.ViewGroup;
 import android.view.ViewOutlineProvider;
 import android.view.ViewTreeObserver;
+import android.view.WindowManagerPolicyConstants;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.widget.FrameLayout;
@@ -75,8 +78,12 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.bubbles.BubblesNavBarMotionEventHandler.MotionEventListener;
 import com.android.wm.shell.bubbles.animation.AnimatableScaleMatrix;
 import com.android.wm.shell.bubbles.animation.ExpandedAnimationController;
+import com.android.wm.shell.bubbles.animation.ExpandedViewAnimationController;
+import com.android.wm.shell.bubbles.animation.ExpandedViewAnimationControllerImpl;
+import com.android.wm.shell.bubbles.animation.ExpandedViewAnimationControllerStub;
 import com.android.wm.shell.bubbles.animation.PhysicsAnimationLayout;
 import com.android.wm.shell.bubbles.animation.StackAnimationController;
 import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -89,6 +96,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
@@ -97,6 +105,12 @@
  */
 public class BubbleStackView extends FrameLayout
         implements ViewTreeObserver.OnComputeInternalInsetsListener {
+    /**
+     * Set to {@code true} to enable home gesture handling in bubbles
+     */
+    public static final boolean HOME_GESTURE_ENABLED =
+            SystemProperties.getBoolean("persist.wm.debug.bubbles_home_gesture", true);
+
     private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleStackView" : TAG_BUBBLES;
 
     /** How far the flyout needs to be dragged before it's dismissed regardless of velocity. */
@@ -123,6 +137,9 @@
 
     private static final float SCRIM_ALPHA = 0.6f;
 
+    /** Minimum alpha value for scrim when alpha is being changed via drag */
+    private static final float MIN_SCRIM_ALPHA_FOR_DRAG = 0.2f;
+
     /**
      * How long to wait to animate the stack temporarily invisible after a drag/flyout hide
      * animation ends, if we are in fact temporarily invisible.
@@ -148,7 +165,7 @@
      * Handler to use for all delayed animations - this way, we can easily cancel them before
      * starting a new animation.
      */
-    private final ShellExecutor mDelayedAnimationExecutor;
+    private final ShellExecutor mMainExecutor;
     private Runnable mDelayedAnimation;
 
     /**
@@ -197,8 +214,10 @@
     private PhysicsAnimationLayout mBubbleContainer;
     private StackAnimationController mStackAnimationController;
     private ExpandedAnimationController mExpandedAnimationController;
+    private ExpandedViewAnimationController mExpandedViewAnimationController;
 
     private View mScrim;
+    private boolean mScrimAnimating;
     private View mManageMenuScrim;
     private FrameLayout mExpandedViewContainer;
 
@@ -276,6 +295,9 @@
      */
     private int mPointerIndexDown = -1;
 
+    @Nullable
+    private BubblesNavBarGestureTracker mBubblesNavBarGestureTracker;
+
     /** Description of current animation controller state. */
     public void dump(PrintWriter pw, String[] args) {
         pw.println("Stack view state:");
@@ -693,6 +715,90 @@
         }
     };
 
+    /** Touch listener set on the whole view that forwards event to the swipe up listener. */
+    private final RelativeTouchListener mContainerSwipeListener = new RelativeTouchListener() {
+        @Override
+        public boolean onDown(@NonNull View v, @NonNull MotionEvent ev) {
+            // Pass move event on to swipe listener
+            mSwipeUpListener.onDown(ev.getX(), ev.getY());
+            return true;
+        }
+
+        @Override
+        public void onMove(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX,
+                float viewInitialY, float dx, float dy) {
+            // Pass move event on to swipe listener
+            mSwipeUpListener.onMove(dx, dy);
+        }
+
+        @Override
+        public void onUp(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX,
+                float viewInitialY, float dx, float dy, float velX, float velY) {
+            // Pass up even on to swipe listener
+            mSwipeUpListener.onUp(velX, velY);
+        }
+    };
+
+    /** MotionEventListener that listens from home gesture swipe event. */
+    private final MotionEventListener mSwipeUpListener = new MotionEventListener() {
+        @Override
+        public void onDown(float x, float y) {}
+
+        @Override
+        public void onMove(float dx, float dy) {
+            if ((mManageEduView != null && mManageEduView.getVisibility() == VISIBLE)
+                    || isStackEduShowing()) {
+                return;
+            }
+
+            if (mShowingManage) {
+                showManageMenu(false /* show */);
+            }
+            // Only allow up, normalize for up direction
+            float collapsed = -Math.min(dy, 0);
+            mExpandedViewAnimationController.updateDrag((int) collapsed);
+
+            // Update scrim
+            if (!mScrimAnimating) {
+                mScrim.setAlpha(getScrimAlphaForDrag(collapsed));
+            }
+        }
+
+        @Override
+        public void onCancel() {
+            mExpandedViewAnimationController.animateBackToExpanded();
+        }
+
+        @Override
+        public void onUp(float velX, float velY) {
+            mExpandedViewAnimationController.setSwipeVelocity(velY);
+            if (mExpandedViewAnimationController.shouldCollapse()) {
+                // Update data first and start the animation when we are processing change
+                mBubbleData.setExpanded(false);
+            } else {
+                mExpandedViewAnimationController.animateBackToExpanded();
+
+                // Update scrim
+                if (!mScrimAnimating) {
+                    showScrim(true);
+                }
+            }
+        }
+
+        private float getScrimAlphaForDrag(float dragAmount) {
+            // dragAmount should be negative as we allow scroll up only
+            if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+                float alphaRange = SCRIM_ALPHA - MIN_SCRIM_ALPHA_FOR_DRAG;
+
+                int dragMax = mExpandedBubble.getExpandedView().getContentHeight();
+                float dragFraction = dragAmount / dragMax;
+
+                return Math.max(SCRIM_ALPHA - alphaRange * dragFraction, MIN_SCRIM_ALPHA_FOR_DRAG);
+            }
+            return SCRIM_ALPHA;
+        }
+    };
+
     /** Click listener set on the flyout, which expands the stack when the flyout is tapped. */
     private OnClickListener mFlyoutClickListener = new OnClickListener() {
         @Override
@@ -766,7 +872,7 @@
             ShellExecutor mainExecutor) {
         super(context);
 
-        mDelayedAnimationExecutor = mainExecutor;
+        mMainExecutor = mainExecutor;
         mBubbleController = bubbleController;
         mBubbleData = data;
 
@@ -796,6 +902,14 @@
 
         mExpandedAnimationController = new ExpandedAnimationController(mPositioner,
                 onBubbleAnimatedOut, this);
+
+        if (HOME_GESTURE_ENABLED) {
+            mExpandedViewAnimationController =
+                    new ExpandedViewAnimationControllerImpl(context, mPositioner);
+        } else {
+            mExpandedViewAnimationController = new ExpandedViewAnimationControllerStub();
+        }
+
         mSurfaceSynchronizer = synchronizer != null ? synchronizer : DEFAULT_SURFACE_SYNCHRONIZER;
 
         // Force LTR by default since most of the Bubbles UI is positioned manually by the user, or
@@ -971,7 +1085,7 @@
                 if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
                     // We need to be Z ordered on top in order for alpha animations to work.
                     mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(true);
-                    mExpandedBubble.getExpandedView().setAlphaAnimating(true);
+                    mExpandedBubble.getExpandedView().setAnimating(true);
                 }
             }
 
@@ -985,14 +1099,15 @@
                         // = 0f remains in effect.
                         && !mExpandedViewTemporarilyHidden) {
                     mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
-                    mExpandedBubble.getExpandedView().setAlphaAnimating(false);
+                    mExpandedBubble.getExpandedView().setAnimating(false);
                 }
             }
         });
         mExpandedViewAlphaAnimator.addUpdateListener(valueAnimator -> {
             if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
-                mExpandedBubble.getExpandedView().setTaskViewAlpha(
-                        (float) valueAnimator.getAnimatedValue());
+                float alpha = (float) valueAnimator.getAnimatedValue();
+                mExpandedBubble.getExpandedView().setContentAlpha(alpha);
+                mExpandedBubble.getExpandedView().setBackgroundAlpha(alpha);
             }
         });
 
@@ -1708,7 +1823,7 @@
     /**
      * Update bubble order and pointer position.
      */
-    public void updateBubbleOrder(List<Bubble> bubbles) {
+    public void updateBubbleOrder(List<Bubble> bubbles, boolean updatePointerPositoion) {
         final Runnable reorder = () -> {
             for (int i = 0; i < bubbles.size(); i++) {
                 Bubble bubble = bubbles.get(i);
@@ -1724,7 +1839,10 @@
                     .map(b -> b.getIconView()).collect(Collectors.toList());
             mStackAnimationController.animateReorder(bubbleViews, reorder);
         }
-        updatePointerPosition(false /* forIme */);
+
+        if (updatePointerPositoion) {
+            updatePointerPosition(false /* forIme */);
+        }
     }
 
     /**
@@ -1795,6 +1913,7 @@
     private void showNewlySelectedBubble(BubbleViewProvider bubbleToSelect) {
         final BubbleViewProvider previouslySelected = mExpandedBubble;
         mExpandedBubble = bubbleToSelect;
+        mExpandedViewAnimationController.setExpandedView(mExpandedBubble.getExpandedView());
 
         if (mIsExpanded) {
             hideCurrentInputMethod();
@@ -1843,12 +1962,19 @@
             return;
         }
 
+        boolean wasExpanded = mIsExpanded;
+
         hideCurrentInputMethod();
 
         mBubbleController.getSysuiProxy().onStackExpandChanged(shouldExpand);
 
-        if (mIsExpanded) {
-            animateCollapse();
+        if (wasExpanded) {
+            stopMonitoringSwipeUpGesture();
+            if (HOME_GESTURE_ENABLED) {
+                animateCollapse();
+            } else {
+                animateCollapseWithScale();
+            }
             logBubbleEvent(mExpandedBubble, FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__COLLAPSED);
         } else {
             animateExpansion();
@@ -1856,11 +1982,58 @@
             logBubbleEvent(mExpandedBubble, FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__EXPANDED);
             logBubbleEvent(mExpandedBubble,
                     FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__STACK_EXPANDED);
+            if (HOME_GESTURE_ENABLED) {
+                mBubbleController.isNotificationPanelExpanded(notifPanelExpanded -> {
+                    if (!notifPanelExpanded && mIsExpanded) {
+                        startMonitoringSwipeUpGesture();
+                    }
+                });
+            }
         }
         notifyExpansionChanged(mExpandedBubble, mIsExpanded);
     }
 
     /**
+     * Monitor for swipe up gesture that is used to collapse expanded view
+     */
+    void startMonitoringSwipeUpGesture() {
+        if (DEBUG_BUBBLE_GESTURE) {
+            Log.d(TAG, "startMonitoringSwipeUpGesture");
+        }
+        stopMonitoringSwipeUpGestureInternal();
+
+        if (isGestureNavEnabled()) {
+            mBubblesNavBarGestureTracker = new BubblesNavBarGestureTracker(mContext, mPositioner);
+            mBubblesNavBarGestureTracker.start(mSwipeUpListener);
+            setOnTouchListener(mContainerSwipeListener);
+        }
+    }
+
+    private boolean isGestureNavEnabled() {
+        return mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_navBarInteractionMode)
+                == WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+    }
+
+    /**
+     * Stop monitoring for swipe up gesture
+     */
+    void stopMonitoringSwipeUpGesture() {
+        if (DEBUG_BUBBLE_GESTURE) {
+            Log.d(TAG, "stopMonitoringSwipeUpGesture");
+        }
+        stopMonitoringSwipeUpGestureInternal();
+    }
+
+    private void stopMonitoringSwipeUpGestureInternal() {
+        if (mBubblesNavBarGestureTracker != null) {
+            mBubblesNavBarGestureTracker.stop();
+            mBubblesNavBarGestureTracker = null;
+            setOnTouchListener(null);
+        }
+    }
+
+    /**
      * Called when back press occurs while bubbles are expanded.
      */
     public void onBackPressed() {
@@ -1982,15 +2155,28 @@
     }
 
     private void showScrim(boolean show) {
+        AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                mScrimAnimating = true;
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mScrimAnimating = false;
+            }
+        };
         if (show) {
             mScrim.animate()
                     .setInterpolator(ALPHA_IN)
                     .alpha(SCRIM_ALPHA)
+                    .setListener(listener)
                     .start();
         } else {
             mScrim.animate()
                     .alpha(0f)
                     .setInterpolator(ALPHA_OUT)
+                    .setListener(listener)
                     .start();
         }
     }
@@ -2072,11 +2258,12 @@
         mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
 
         if (mExpandedBubble.getExpandedView() != null) {
-            mExpandedBubble.getExpandedView().setTaskViewAlpha(0f);
+            mExpandedBubble.getExpandedView().setContentAlpha(0f);
+            mExpandedBubble.getExpandedView().setBackgroundAlpha(0f);
 
             // We'll be starting the alpha animation after a slight delay, so set this flag early
             // here.
-            mExpandedBubble.getExpandedView().setAlphaAnimating(true);
+            mExpandedBubble.getExpandedView().setAnimating(true);
         }
 
         mDelayedAnimation = () -> {
@@ -2114,10 +2301,10 @@
                     })
                     .start();
         };
-        mDelayedAnimationExecutor.executeDelayed(mDelayedAnimation, startDelay);
+        mMainExecutor.executeDelayed(mDelayedAnimation, startDelay);
     }
 
-    private void animateCollapse() {
+    private void animateCollapseWithScale() {
         cancelDelayedExpandCollapseSwitchAnimations();
 
         if (mManageEduView != null && mManageEduView.getVisibility() == VISIBLE) {
@@ -2217,6 +2404,68 @@
                 .start();
     }
 
+    private void animateCollapse() {
+        cancelDelayedExpandCollapseSwitchAnimations();
+
+        if (mManageEduView != null && mManageEduView.getVisibility() == VISIBLE) {
+            mManageEduView.hide();
+        }
+
+        mIsExpanded = false;
+        mIsExpansionAnimating = true;
+
+        showScrim(false);
+
+        mBubbleContainer.cancelAllAnimations();
+
+        // If we were in the middle of swapping, the animating-out surface would have been scaling
+        // to zero - finish it off.
+        PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer).cancel();
+        mAnimatingOutSurfaceContainer.setScaleX(0f);
+        mAnimatingOutSurfaceContainer.setScaleY(0f);
+
+        // Let the expanded animation controller know that it shouldn't animate child adds/reorders
+        // since we're about to animate collapsed.
+        mExpandedAnimationController.notifyPreparingToCollapse();
+
+        final Runnable collapseBackToStack = () -> mExpandedAnimationController.collapseBackToStack(
+                mStackAnimationController
+                        .getStackPositionAlongNearestHorizontalEdge()
+                /* collapseTo */,
+                () -> mBubbleContainer.setActiveController(mStackAnimationController));
+
+        final Runnable after = () -> {
+            final BubbleViewProvider previouslySelected = mExpandedBubble;
+            // TODO(b/231350255): investigate why this call is needed here
+            beforeExpandedViewAnimation();
+            if (mManageEduView != null) {
+                mManageEduView.hide();
+            }
+
+            if (DEBUG_BUBBLE_STACK_VIEW) {
+                Log.d(TAG, "animateCollapse");
+                Log.d(TAG, BubbleDebugConfig.formatBubblesString(getBubblesOnScreen(),
+                        mExpandedBubble));
+            }
+            updateOverflowVisibility();
+            updateZOrder();
+            updateBadges(true /* setBadgeForCollapsedStack */);
+            afterExpandedViewAnimation();
+            if (previouslySelected != null) {
+                previouslySelected.setTaskViewVisibility(false);
+            }
+            mExpandedViewAnimationController.reset();
+        };
+        mExpandedViewAnimationController.animateCollapse(collapseBackToStack, after);
+        if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+            // When the animation completes, we should no longer be showing the content.
+            // This won't actually update content visibility immediately, if we are currently
+            // animating. But updates the internal state for the content to be hidden after
+            // animation completes.
+            mExpandedBubble.getExpandedView().setContentVisibility(false);
+        }
+    }
+
     private void animateSwitchBubbles() {
         // If we're no longer expanded, this is meaningless.
         if (!mIsExpanded) {
@@ -2277,7 +2526,7 @@
 
         mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
 
-        mDelayedAnimationExecutor.executeDelayed(() -> {
+        mMainExecutor.executeDelayed(() -> {
             if (!mIsExpanded) {
                 mIsBubbleSwitchAnimating = false;
                 return;
@@ -2308,7 +2557,7 @@
      * animating flags for those animations.
      */
     private void cancelDelayedExpandCollapseSwitchAnimations() {
-        mDelayedAnimationExecutor.removeCallbacks(mDelayedAnimation);
+        mMainExecutor.removeCallbacks(mDelayedAnimation);
 
         mIsExpansionAnimating = false;
         mIsBubbleSwitchAnimating = false;
@@ -2332,9 +2581,18 @@
     /**
      * Updates the stack based for IME changes. When collapsed it'll move the stack if it
      * overlaps where they IME would be. When expanded it'll shift the expanded bubbles
-     * if they might overlap with the IME (this only happens for large screens).
+     * if they might overlap with the IME (this only happens for large screens)
+     * and clip the expanded view.
      */
-    public void animateForIme(boolean visible) {
+    public void setImeVisible(boolean visible) {
+        if (HOME_GESTURE_ENABLED) {
+            setImeVisibleInternal(visible);
+        } else {
+            setImeVisibleWithoutClipping(visible);
+        }
+    }
+
+    private void setImeVisibleWithoutClipping(boolean visible) {
         if ((mIsExpansionAnimating || mIsBubbleSwitchAnimating) && mIsExpanded) {
             // This will update the animation so the bubbles move to position for the IME
             mExpandedAnimationController.expandFromStack(() -> {
@@ -2385,6 +2643,62 @@
         }
     }
 
+    private void setImeVisibleInternal(boolean visible) {
+        if ((mIsExpansionAnimating || mIsBubbleSwitchAnimating) && mIsExpanded) {
+            // This will update the animation so the bubbles move to position for the IME
+            mExpandedAnimationController.expandFromStack(() -> {
+                updatePointerPosition(false /* forIme */);
+                afterExpandedViewAnimation();
+                mExpandedViewAnimationController.animateForImeVisibilityChange(visible);
+            } /* after */);
+            return;
+        }
+
+        if (!mIsExpanded && getBubbleCount() > 0) {
+            final float stackDestinationY =
+                    mStackAnimationController.animateForImeVisibility(visible);
+
+            // How far the stack is animating due to IME, we'll just animate the flyout by that
+            // much too.
+            final float stackDy =
+                    stackDestinationY - mStackAnimationController.getStackPosition().y;
+
+            // If the flyout is visible, translate it along with the bubble stack.
+            if (mFlyout.getVisibility() == VISIBLE) {
+                PhysicsAnimator.getInstance(mFlyout)
+                        .spring(DynamicAnimation.TRANSLATION_Y,
+                                mFlyout.getTranslationY() + stackDy,
+                                FLYOUT_IME_ANIMATION_SPRING_CONFIG)
+                        .start();
+            }
+        }
+
+        if (mIsExpanded) {
+            mExpandedViewAnimationController.animateForImeVisibilityChange(visible);
+            if (mPositioner.showBubblesVertically()
+                    && mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
+                float selectedY = mPositioner.getExpandedBubbleXY(getState().selectedIndex,
+                        getState()).y;
+                float newExpandedViewTop = mPositioner.getExpandedViewY(mExpandedBubble, selectedY);
+                mExpandedBubble.getExpandedView().setImeVisible(visible);
+                if (!mExpandedBubble.getExpandedView().isUsingMaxHeight()) {
+                    mExpandedViewContainer.animate().translationY(newExpandedViewTop);
+                }
+                List<Animator> animList = new ArrayList();
+                for (int i = 0; i < mBubbleContainer.getChildCount(); i++) {
+                    View child = mBubbleContainer.getChildAt(i);
+                    float transY = mPositioner.getExpandedBubbleXY(i, getState()).y;
+                    ObjectAnimator anim = ObjectAnimator.ofFloat(child, TRANSLATION_Y, transY);
+                    animList.add(anim);
+                }
+                updatePointerPosition(true /* forIme */);
+                AnimatorSet set = new AnimatorSet();
+                set.playTogether(animList);
+                set.start();
+            }
+        }
+    }
+
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
         if (ev.getAction() != MotionEvent.ACTION_DOWN && ev.getActionIndex() != mPointerIndexDown) {
@@ -2473,8 +2787,10 @@
 
     private void dismissBubbleIfExists(@Nullable BubbleViewProvider bubble) {
         if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
-            if (mIsExpanded && mBubbleData.getBubbles().size() > 1) {
-                // If we have more than 1 bubble we will perform the switch animation
+            if (mIsExpanded && mBubbleData.getBubbles().size() > 1
+                    && Objects.equals(bubble, mExpandedBubble)) {
+                // If we have more than 1 bubble and it's the current bubble being dismissed,
+                // we will perform the switch animation
                 mIsBubbleSwitchAnimating = true;
             }
             mBubbleData.dismissBubbleWithKey(bubble.getKey(), Bubbles.DISMISS_USER_GESTURE);
@@ -2820,7 +3136,7 @@
                 && mExpandedBubble.getExpandedView() != null) {
             BubbleExpandedView bev = mExpandedBubble.getExpandedView();
             bev.setContentVisibility(false);
-            bev.setAlphaAnimating(!mIsExpansionAnimating);
+            bev.setAnimating(!mIsExpansionAnimating);
             mExpandedViewContainerMatrix.setScaleX(0f);
             mExpandedViewContainerMatrix.setScaleY(0f);
             mExpandedViewContainerMatrix.setTranslate(0f, 0f);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 8a0db0a..0072da1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -214,6 +214,11 @@
             int modificationType);
 
     /**
+     * Called when notification panel is expanded or collapsed
+     */
+    void onNotificationPanelExpandedChanged(boolean expanded);
+
+    /**
      * Called when the status bar has become visible or invisible (either permanently or
      * temporarily).
      */
@@ -285,7 +290,7 @@
 
     /** Callback to tell SysUi components execute some methods. */
     interface SysuiProxy {
-        void isNotificationShadeExpand(Consumer<Boolean> callback);
+        void isNotificationPanelExpand(Consumer<Boolean> callback);
 
         void getPendingOrActiveEntry(String key, Consumer<BubbleEntry> callback);
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java
new file mode 100644
index 0000000..e7beeeb
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.bubbles;
+
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.content.Context;
+import android.hardware.input.InputManager;
+import android.util.Log;
+import android.view.Choreographer;
+import android.view.InputChannel;
+import android.view.InputEventReceiver;
+import android.view.InputMonitor;
+
+import androidx.annotation.Nullable;
+
+import com.android.wm.shell.bubbles.BubblesNavBarMotionEventHandler.MotionEventListener;
+
+/**
+ * Set up tracking bubbles gestures that begin in navigation bar
+ */
+class BubblesNavBarGestureTracker {
+
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "BubblesGestureTracker" : TAG_BUBBLES;
+
+    private static final String GESTURE_MONITOR = "bubbles-gesture";
+    private final Context mContext;
+    private final BubblePositioner mPositioner;
+
+    @Nullable
+    private InputMonitor mInputMonitor;
+    @Nullable
+    private InputEventReceiver mInputEventReceiver;
+
+    BubblesNavBarGestureTracker(Context context, BubblePositioner positioner) {
+        mContext = context;
+        mPositioner = positioner;
+    }
+
+    /**
+     * Start tracking gestures
+     *
+     * @param listener listener that is notified of touch events
+     */
+    void start(MotionEventListener listener) {
+        if (BubbleDebugConfig.DEBUG_BUBBLE_GESTURE) {
+            Log.d(TAG, "start monitoring bubbles swipe up gesture");
+        }
+
+        stopInternal();
+
+        mInputMonitor = InputManager.getInstance().monitorGestureInput(GESTURE_MONITOR,
+                mContext.getDisplayId());
+        InputChannel inputChannel = mInputMonitor.getInputChannel();
+
+        BubblesNavBarMotionEventHandler motionEventHandler =
+                new BubblesNavBarMotionEventHandler(mContext, mPositioner,
+                        this::onInterceptTouch, listener);
+        mInputEventReceiver = new BubblesNavBarInputEventReceiver(inputChannel,
+                Choreographer.getInstance(), motionEventHandler);
+    }
+
+    void stop() {
+        if (BubbleDebugConfig.DEBUG_BUBBLE_GESTURE) {
+            Log.d(TAG, "stop monitoring bubbles swipe up gesture");
+        }
+        stopInternal();
+    }
+
+    private void stopInternal() {
+        if (mInputEventReceiver != null) {
+            mInputEventReceiver.dispose();
+            mInputEventReceiver = null;
+        }
+        if (mInputMonitor != null) {
+            mInputMonitor.dispose();
+            mInputMonitor = null;
+        }
+    }
+
+    private void onInterceptTouch() {
+        if (BubbleDebugConfig.DEBUG_BUBBLE_GESTURE) {
+            Log.d(TAG, "intercept touch event");
+        }
+        if (mInputMonitor != null) {
+            mInputMonitor.pilferPointers();
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarInputEventReceiver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarInputEventReceiver.java
new file mode 100644
index 0000000..45037b8
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarInputEventReceiver.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.bubbles;
+
+import android.os.Looper;
+import android.view.BatchedInputEventReceiver;
+import android.view.Choreographer;
+import android.view.InputChannel;
+import android.view.InputEvent;
+import android.view.MotionEvent;
+
+/**
+ * Bubbles {@link BatchedInputEventReceiver} for monitoring touches from navbar gesture area
+ */
+class BubblesNavBarInputEventReceiver extends BatchedInputEventReceiver {
+
+    private final BubblesNavBarMotionEventHandler mMotionEventHandler;
+
+    BubblesNavBarInputEventReceiver(InputChannel inputChannel,
+            Choreographer choreographer, BubblesNavBarMotionEventHandler motionEventHandler) {
+        super(inputChannel, Looper.myLooper(), choreographer);
+        mMotionEventHandler = motionEventHandler;
+    }
+
+    @Override
+    public void onInputEvent(InputEvent event) {
+        boolean handled = false;
+        try {
+            if (!(event instanceof MotionEvent)) {
+                return;
+            }
+            handled = mMotionEventHandler.onMotionEvent((MotionEvent) event);
+        } finally {
+            finishInputEvent(event, handled);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java
new file mode 100644
index 0000000..844526ca
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.bubbles;
+
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_GESTURE;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.content.Context;
+import android.graphics.PointF;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.ViewConfiguration;
+
+import androidx.annotation.Nullable;
+
+/**
+ * Handles {@link MotionEvent}s for bubbles that begin in the nav bar area
+ */
+class BubblesNavBarMotionEventHandler {
+    private static final String TAG =
+            TAG_WITH_CLASS_NAME ? "BubblesNavBarMotionEventHandler" : TAG_BUBBLES;
+    private static final int VELOCITY_UNITS = 1000;
+
+    private final Runnable mOnInterceptTouch;
+    private final MotionEventListener mMotionEventListener;
+    private final int mTouchSlop;
+    private final BubblePositioner mPositioner;
+    private final PointF mTouchDown = new PointF();
+    private boolean mTrackingTouches;
+    private boolean mInterceptingTouches;
+    @Nullable
+    private VelocityTracker mVelocityTracker;
+
+    BubblesNavBarMotionEventHandler(Context context, BubblePositioner positioner,
+            Runnable onInterceptTouch, MotionEventListener motionEventListener) {
+        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+        mPositioner = positioner;
+        mOnInterceptTouch = onInterceptTouch;
+        mMotionEventListener = motionEventListener;
+    }
+
+    /**
+     * Handle {@link MotionEvent} and forward it to {@code motionEventListener} defined in
+     * constructor
+     *
+     * @return {@code true} if this {@link MotionEvent} is handled (it started in the gesture area)
+     */
+    public boolean onMotionEvent(MotionEvent motionEvent) {
+        float dx = motionEvent.getX() - mTouchDown.x;
+        float dy = motionEvent.getY() - mTouchDown.y;
+
+        switch (motionEvent.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                if (isInGestureRegion(motionEvent)) {
+                    mTouchDown.set(motionEvent.getX(), motionEvent.getY());
+                    mMotionEventListener.onDown(motionEvent.getX(), motionEvent.getY());
+                    mTrackingTouches = true;
+                    return true;
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                if (mTrackingTouches) {
+                    if (!mInterceptingTouches && Math.hypot(dx, dy) > mTouchSlop) {
+                        mInterceptingTouches = true;
+                        mOnInterceptTouch.run();
+                    }
+                    if (mInterceptingTouches) {
+                        getVelocityTracker().addMovement(motionEvent);
+                        mMotionEventListener.onMove(dx, dy);
+                    }
+                    return true;
+                }
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                if (mTrackingTouches) {
+                    mMotionEventListener.onCancel();
+                    finishTracking();
+                    return true;
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+                if (mTrackingTouches) {
+                    if (mInterceptingTouches) {
+                        getVelocityTracker().computeCurrentVelocity(VELOCITY_UNITS);
+                        mMotionEventListener.onUp(getVelocityTracker().getXVelocity(),
+                                getVelocityTracker().getYVelocity());
+                    }
+                    finishTracking();
+                    return true;
+                }
+                break;
+        }
+        return false;
+    }
+
+    private boolean isInGestureRegion(MotionEvent ev) {
+        // Only handles touch events beginning in navigation bar system gesture zone
+        if (mPositioner.getNavBarGestureZone().contains((int) ev.getX(), (int) ev.getY())) {
+            if (DEBUG_BUBBLE_GESTURE) {
+                Log.d(TAG, "handling touch y=" + ev.getY()
+                        + " navBarGestureZone=" + mPositioner.getNavBarGestureZone());
+            }
+            return true;
+        }
+        return false;
+    }
+
+    private VelocityTracker getVelocityTracker() {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+        return mVelocityTracker;
+    }
+
+    private void finishTracking() {
+        mTouchDown.set(0, 0);
+        mTrackingTouches = false;
+        mInterceptingTouches = false;
+        if (mVelocityTracker != null) {
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+        }
+    }
+
+    /**
+     * Callback for receiving {@link MotionEvent} updates
+     */
+    interface MotionEventListener {
+        /**
+         * Touch down action.
+         *
+         * @param x x coordinate
+         * @param y y coordinate
+         */
+        void onDown(float x, float y);
+
+        /**
+         * Move action.
+         * Reports distance from point reported in {@link #onDown(float, float)}
+         *
+         * @param dx distance moved on x-axis from starting point, in pixels
+         * @param dy distance moved on y-axis from starting point, in pixels
+         */
+        void onMove(float dx, float dy);
+
+        /**
+         * Touch up action.
+         *
+         * @param velX velocity of the move action on x axis
+         * @param velY velocity of the move actin on y axis
+         */
+        void onUp(float velX, float velY);
+
+        /**
+         * Motion action was cancelled.
+         */
+        void onCancel();
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt
index cf0cefe..ea9d065 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt
@@ -17,8 +17,6 @@
 package com.android.wm.shell.bubbles
 
 import android.graphics.PointF
-import android.os.Handler
-import android.os.Looper
 import android.view.MotionEvent
 import android.view.VelocityTracker
 import android.view.View
@@ -146,6 +144,12 @@
                 velocityTracker.clear()
                 movedEnough = false
             }
+
+            MotionEvent.ACTION_CANCEL -> {
+                v.handler.removeCallbacksAndMessages(null)
+                velocityTracker.clear()
+                movedEnough = false
+            }
         }
 
         return true
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
index 573f424..b521cb6a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
@@ -16,12 +16,16 @@
 
 package com.android.wm.shell.bubbles.animation;
 
+import static android.view.View.LAYOUT_DIRECTION_RTL;
+
 import static com.android.wm.shell.bubbles.BubblePositioner.NUM_VISIBLE_WHEN_RESTING;
+import static com.android.wm.shell.bubbles.BubbleStackView.HOME_GESTURE_ENABLED;
 
 import android.content.res.Resources;
 import android.graphics.Path;
 import android.graphics.PointF;
 import android.view.View;
+import android.view.animation.Interpolator;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -61,7 +65,10 @@
     private static final float DAMPING_RATIO_MEDIUM_LOW_BOUNCY = 0.65f;
 
     /** Stiffness for the expand/collapse path-following animation. */
-    private static final int EXPAND_COLLAPSE_ANIM_STIFFNESS = 1000;
+    private static final int EXPAND_COLLAPSE_ANIM_STIFFNESS = 400;
+
+    /** Stiffness for the expand/collapse animation when home gesture handling is off */
+    private static final int EXPAND_COLLAPSE_ANIM_STIFFNESS_WITHOUT_HOME_GESTURE = 1000;
 
     /**
      * Velocity required to dismiss an individual bubble without dragging it into the dismiss
@@ -73,6 +80,11 @@
             new PhysicsAnimator.SpringConfig(
                     EXPAND_COLLAPSE_ANIM_STIFFNESS, SpringForce.DAMPING_RATIO_NO_BOUNCY);
 
+    private final PhysicsAnimator.SpringConfig mAnimateOutSpringConfigWithoutHomeGesture =
+            new PhysicsAnimator.SpringConfig(
+                    EXPAND_COLLAPSE_ANIM_STIFFNESS_WITHOUT_HOME_GESTURE,
+                    SpringForce.DAMPING_RATIO_NO_BOUNCY);
+
     /** Horizontal offset between bubbles, which we need to know to re-stack them. */
     private float mStackOffsetPx;
     /** Size of each bubble. */
@@ -233,6 +245,11 @@
             };
         }
 
+        boolean showBubblesVertically = mPositioner.showBubblesVertically();
+        final boolean isRtl =
+                mLayout.getContext().getResources().getConfiguration().getLayoutDirection()
+                        == LAYOUT_DIRECTION_RTL;
+
         // Animate each bubble individually, since each path will end in a different spot.
         animationsForChildrenFromIndex(0, (index, animation) -> {
             final View bubble = mLayout.getChildAt(index);
@@ -267,9 +284,20 @@
             // right side, the first bubble is traveling to the top left, so it leads. During
             // collapse to the left, the first bubble has the shortest travel time back to the stack
             // position, so it leads (and vice versa).
-            final boolean firstBubbleLeads =
-                    (expanding && !mLayout.isFirstChildXLeftOfCenter(bubble.getTranslationX()))
+            final boolean firstBubbleLeads;
+            if (showBubblesVertically || !isRtl) {
+                firstBubbleLeads =
+                        (expanding && !mLayout.isFirstChildXLeftOfCenter(bubble.getTranslationX()))
                             || (!expanding && mLayout.isFirstChildXLeftOfCenter(mCollapsePoint.x));
+            } else {
+                // For RTL languages, when showing bubbles horizontally, it is reversed. The bubbles
+                // are positioned right to left. This means that when expanding from left, the top
+                // bubble will lead as it will be positioned on the right. And when expanding from
+                // right, the top bubble will have the least travel distance.
+                firstBubbleLeads =
+                        (expanding && mLayout.isFirstChildXLeftOfCenter(bubble.getTranslationX()))
+                            || (!expanding && !mLayout.isFirstChildXLeftOfCenter(mCollapsePoint.x));
+            }
             final int startDelay = firstBubbleLeads
                     ? (index * 10)
                     : ((mLayout.getChildCount() - index) * 10);
@@ -278,11 +306,20 @@
                     (firstBubbleLeads && index == 0)
                             || (!firstBubbleLeads && index == mLayout.getChildCount() - 1);
 
+            Interpolator interpolator;
+            if (HOME_GESTURE_ENABLED) {
+                // When home gesture is enabled, we use a different animation timing for collapse
+                interpolator = expanding
+                        ? Interpolators.EMPHASIZED_ACCELERATE : Interpolators.EMPHASIZED_DECELERATE;
+            } else {
+                interpolator = Interpolators.LINEAR;
+            }
+
             animation
                     .followAnimatedTargetAlongPath(
                             path,
                             EXPAND_COLLAPSE_TARGET_ANIM_DURATION /* targetAnimDuration */,
-                            Interpolators.LINEAR /* targetAnimInterpolator */,
+                            interpolator /* targetAnimInterpolator */,
                             isLeadBubble ? mLeadBubbleEndAction : null /* endAction */,
                             () -> mLeadBubbleEndAction = null /* endAction */)
                     .withStartDelay(startDelay)
@@ -525,10 +562,16 @@
             finishRemoval.run();
             mOnBubbleAnimatedOutAction.run();
         } else {
+            PhysicsAnimator.SpringConfig springConfig;
+            if (HOME_GESTURE_ENABLED) {
+                springConfig = mAnimateOutSpringConfig;
+            } else {
+                springConfig = mAnimateOutSpringConfigWithoutHomeGesture;
+            }
             PhysicsAnimator.getInstance(child)
                     .spring(DynamicAnimation.ALPHA, 0f)
-                    .spring(DynamicAnimation.SCALE_X, 0f, mAnimateOutSpringConfig)
-                    .spring(DynamicAnimation.SCALE_Y, 0f, mAnimateOutSpringConfig)
+                    .spring(DynamicAnimation.SCALE_X, 0f, springConfig)
+                    .spring(DynamicAnimation.SCALE_Y, 0f, springConfig)
                     .withEndActions(finishRemoval, mOnBubbleAnimatedOutAction)
                     .start();
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationController.java
new file mode 100644
index 0000000..8a33780
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationController.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.animation;
+
+import com.android.wm.shell.bubbles.BubbleExpandedView;
+
+/**
+ * Animation controller for bubble expanded view collapsing
+ */
+public interface ExpandedViewAnimationController {
+    /**
+     * Set expanded view that this controller is working with.
+     */
+    void setExpandedView(BubbleExpandedView expandedView);
+
+    /**
+     * Set current collapse value, in pixels.
+     *
+     * @param distance pixels that user dragged the view by
+     */
+    void updateDrag(float distance);
+
+    /**
+     * Set current swipe velocity.
+     * Velocity is directional:
+     * <ul>
+     *     <li>velocity < 0 means swipe direction is up</li>
+     *     <li>velocity > 0 means swipe direction is down</li>
+     * </ul>
+     */
+    void setSwipeVelocity(float velocity);
+
+    /**
+     * Check if view is dragged past collapse threshold or swipe up velocity exceeds min velocity
+     * required to collapse the view
+     */
+    boolean shouldCollapse();
+
+    /**
+     * Animate view to collapsed state
+     *
+     * @param startStackCollapse runnable that is triggered when bubbles can start moving back to
+     *                           their collapsed location
+     * @param after              runnable to run after animation is complete
+     */
+    void animateCollapse(Runnable startStackCollapse, Runnable after);
+
+    /**
+     * Animate the view back to fully expanded state.
+     */
+    void animateBackToExpanded();
+
+    /**
+     * Animate view for IME visibility change
+     */
+    void animateForImeVisibilityChange(boolean visible);
+
+    /**
+     * Reset the view to fully expanded state
+     */
+    void reset();
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java
new file mode 100644
index 0000000..845dca3
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.animation;
+
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_COLLAPSE_ANIMATOR;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_EXPANDED_VIEW_DRAGGING;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.wm.shell.bubbles.BubbleExpandedView.BACKGROUND_ALPHA;
+import static com.android.wm.shell.bubbles.BubbleExpandedView.BOTTOM_CLIP_PROPERTY;
+import static com.android.wm.shell.bubbles.BubbleExpandedView.CONTENT_ALPHA;
+import static com.android.wm.shell.bubbles.BubbleExpandedView.MANAGE_BUTTON_ALPHA;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.util.Log;
+import android.view.HapticFeedbackConstants;
+import android.view.ViewConfiguration;
+
+import androidx.annotation.Nullable;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+import androidx.dynamicanimation.animation.FloatPropertyCompat;
+import androidx.dynamicanimation.animation.SpringAnimation;
+import androidx.dynamicanimation.animation.SpringForce;
+
+import com.android.wm.shell.animation.FlingAnimationUtils;
+import com.android.wm.shell.animation.Interpolators;
+import com.android.wm.shell.bubbles.BubbleExpandedView;
+import com.android.wm.shell.bubbles.BubblePositioner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implementation of {@link ExpandedViewAnimationController} that uses a collapse animation to
+ * hide the {@link BubbleExpandedView}
+ */
+public class ExpandedViewAnimationControllerImpl implements ExpandedViewAnimationController {
+
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "ExpandedViewAnimCtrl" : TAG_BUBBLES;
+
+    private static final float COLLAPSE_THRESHOLD = 0.02f;
+
+    private static final int COLLAPSE_DURATION_MS = 250;
+
+    private static final int MANAGE_BUTTON_ANIM_DURATION_MS = 78;
+
+    private static final int CONTENT_OPACITY_ANIM_DELAY_MS = 93;
+    private static final int CONTENT_OPACITY_ANIM_DURATION_MS = 78;
+
+    private static final int BACKGROUND_OPACITY_ANIM_DELAY_MS = 172;
+    private static final int BACKGROUND_OPACITY_ANIM_DURATION_MS = 78;
+
+    /** Animation fraction threshold for content alpha animation when stack collapse should begin */
+    private static final float STACK_COLLAPSE_THRESHOLD = 0.5f;
+
+    private static final FloatPropertyCompat<ExpandedViewAnimationControllerImpl>
+            COLLAPSE_HEIGHT_PROPERTY =
+            new FloatPropertyCompat<ExpandedViewAnimationControllerImpl>("CollapseSpring") {
+                @Override
+                public float getValue(ExpandedViewAnimationControllerImpl controller) {
+                    return controller.getCollapsedAmount();
+                }
+
+                @Override
+                public void setValue(ExpandedViewAnimationControllerImpl controller,
+                        float value) {
+                    controller.setCollapsedAmount(value);
+                }
+            };
+
+    private final int mMinFlingVelocity;
+    private float mSwipeUpVelocity;
+    private float mSwipeDownVelocity;
+    private final BubblePositioner mPositioner;
+    private final FlingAnimationUtils mFlingAnimationUtils;
+    private int mDraggedAmount;
+    private float mCollapsedAmount;
+    @Nullable
+    private BubbleExpandedView mExpandedView;
+    @Nullable
+    private AnimatorSet mCollapseAnimation;
+    private boolean mNotifiedAboutThreshold;
+    private SpringAnimation mBackToExpandedAnimation;
+    @Nullable
+    private ObjectAnimator mBottomClipAnim;
+
+    public ExpandedViewAnimationControllerImpl(Context context, BubblePositioner positioner) {
+        mFlingAnimationUtils = new FlingAnimationUtils(context.getResources().getDisplayMetrics(),
+                COLLAPSE_DURATION_MS / 1000f);
+        mMinFlingVelocity = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();
+        mPositioner = positioner;
+    }
+
+    private static void adjustAnimatorSetDuration(AnimatorSet animatorSet,
+            float durationAdjustment) {
+        for (Animator animator : animatorSet.getChildAnimations()) {
+            animator.setStartDelay((long) (animator.getStartDelay() * durationAdjustment));
+            animator.setDuration((long) (animator.getDuration() * durationAdjustment));
+        }
+    }
+
+    @Override
+    public void setExpandedView(BubbleExpandedView expandedView) {
+        if (mExpandedView != null) {
+            if (DEBUG_COLLAPSE_ANIMATOR) {
+                Log.d(TAG, "updating expandedView, resetting previous");
+            }
+            if (mCollapseAnimation != null) {
+                mCollapseAnimation.cancel();
+            }
+            if (mBackToExpandedAnimation != null) {
+                mBackToExpandedAnimation.cancel();
+            }
+            reset();
+        }
+        mExpandedView = expandedView;
+    }
+
+    @Override
+    public void updateDrag(float distance) {
+        if (mExpandedView != null) {
+            mDraggedAmount = OverScroll.dampedScroll(distance, mExpandedView.getContentHeight());
+
+            if (DEBUG_COLLAPSE_ANIMATOR && DEBUG_EXPANDED_VIEW_DRAGGING) {
+                Log.d(TAG, "updateDrag: distance=" + distance + " dragged=" + mDraggedAmount);
+            }
+
+            setCollapsedAmount(mDraggedAmount);
+
+            if (!mNotifiedAboutThreshold && isPastCollapseThreshold()) {
+                mNotifiedAboutThreshold = true;
+                if (DEBUG_COLLAPSE_ANIMATOR) {
+                    Log.d(TAG, "notifying over collapse threshold");
+                }
+                vibrateIfEnabled();
+            }
+        }
+    }
+
+    @Override
+    public void setSwipeVelocity(float velocity) {
+        if (velocity < 0) {
+            mSwipeUpVelocity = Math.abs(velocity);
+            mSwipeDownVelocity = 0;
+        } else {
+            mSwipeUpVelocity = 0;
+            mSwipeDownVelocity = velocity;
+        }
+    }
+
+    @Override
+    public boolean shouldCollapse() {
+        if (mSwipeDownVelocity > mMinFlingVelocity) {
+            // Swipe velocity is positive and over fling velocity.
+            // This is a swipe down, always reset to expanded state, regardless of dragged amount.
+            if (DEBUG_COLLAPSE_ANIMATOR) {
+                Log.d(TAG,
+                        "not collapsing expanded view, swipe down velocity: " + mSwipeDownVelocity
+                                + " minV: " + mMinFlingVelocity);
+            }
+            return false;
+        }
+
+        if (mSwipeUpVelocity > mMinFlingVelocity) {
+            // Swiping up and over fling velocity, collapse the view.
+            if (DEBUG_COLLAPSE_ANIMATOR) {
+                Log.d(TAG,
+                        "collapse expanded view, swipe up velocity: " + mSwipeUpVelocity + " minV: "
+                                + mMinFlingVelocity);
+            }
+            return true;
+        }
+
+        if (isPastCollapseThreshold()) {
+            if (DEBUG_COLLAPSE_ANIMATOR) {
+                Log.d(TAG, "collapse expanded view, past threshold, dragged: " + mDraggedAmount);
+            }
+            return true;
+        }
+
+        if (DEBUG_COLLAPSE_ANIMATOR) {
+            Log.d(TAG, "not collapsing expanded view");
+        }
+
+        return false;
+    }
+
+    @Override
+    public void animateCollapse(Runnable startStackCollapse, Runnable after) {
+        if (DEBUG_COLLAPSE_ANIMATOR) {
+            Log.d(TAG,
+                    "expandedView animate collapse swipeVel=" + mSwipeUpVelocity + " minFlingVel="
+                            + mMinFlingVelocity);
+        }
+        if (mExpandedView != null) {
+            // Mark it as animating immediately to avoid updates to the view before animation starts
+            mExpandedView.setAnimating(true);
+
+            if (mCollapseAnimation != null) {
+                mCollapseAnimation.cancel();
+            }
+            mCollapseAnimation = createCollapseAnimation(mExpandedView, startStackCollapse, after);
+
+            if (mSwipeUpVelocity >= mMinFlingVelocity) {
+                int contentHeight = mExpandedView.getContentHeight();
+
+                // Use a temp animator to get adjusted duration value for swipe.
+                // This new value will be used to adjust animation times proportionally in the
+                // animator set. If we adjust animator set duration directly, all child animations
+                // will get the same animation time.
+                ValueAnimator tempAnimator = new ValueAnimator();
+                mFlingAnimationUtils.applyDismissing(tempAnimator, mCollapsedAmount, contentHeight,
+                        mSwipeUpVelocity, (contentHeight - mCollapsedAmount));
+
+                float durationAdjustment =
+                        (float) tempAnimator.getDuration() / COLLAPSE_DURATION_MS;
+
+                adjustAnimatorSetDuration(mCollapseAnimation, durationAdjustment);
+                mCollapseAnimation.setInterpolator(tempAnimator.getInterpolator());
+            }
+            mCollapseAnimation.start();
+        }
+    }
+
+    @Override
+    public void animateBackToExpanded() {
+        if (DEBUG_COLLAPSE_ANIMATOR) {
+            Log.d(TAG, "expandedView animate back to expanded");
+        }
+        BubbleExpandedView expandedView = mExpandedView;
+        if (expandedView == null) {
+            return;
+        }
+
+        expandedView.setAnimating(true);
+
+        mBackToExpandedAnimation = new SpringAnimation(this, COLLAPSE_HEIGHT_PROPERTY);
+        mBackToExpandedAnimation.setSpring(new SpringForce()
+                .setStiffness(SpringForce.STIFFNESS_LOW)
+                .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
+        );
+        mBackToExpandedAnimation.addEndListener(new OneTimeEndListener() {
+            @Override
+            public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value,
+                    float velocity) {
+                super.onAnimationEnd(animation, canceled, value, velocity);
+                mNotifiedAboutThreshold = false;
+                mBackToExpandedAnimation = null;
+                expandedView.setAnimating(false);
+            }
+        });
+        mBackToExpandedAnimation.setStartValue(mCollapsedAmount);
+        mBackToExpandedAnimation.animateToFinalPosition(0);
+    }
+
+    @Override
+    public void animateForImeVisibilityChange(boolean visible) {
+        if (mExpandedView != null) {
+            if (mBottomClipAnim != null) {
+                mBottomClipAnim.cancel();
+            }
+            int clip = 0;
+            if (visible) {
+                // Clip the expanded view at the top of the IME view
+                clip = mExpandedView.getContentBottomOnScreen() - mPositioner.getImeTop();
+                // Don't allow negative clip value
+                clip = Math.max(clip, 0);
+            }
+            mBottomClipAnim = ObjectAnimator.ofInt(mExpandedView, BOTTOM_CLIP_PROPERTY, clip);
+            mBottomClipAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mBottomClipAnim = null;
+                }
+            });
+            mBottomClipAnim.start();
+        }
+    }
+
+    @Override
+    public void reset() {
+        if (DEBUG_COLLAPSE_ANIMATOR) {
+            Log.d(TAG, "reset expandedView collapsed state");
+        }
+        if (mExpandedView == null) {
+            return;
+        }
+        mExpandedView.setAnimating(false);
+
+        if (mCollapseAnimation != null) {
+            mCollapseAnimation.cancel();
+        }
+        if (mBackToExpandedAnimation != null) {
+            mBackToExpandedAnimation.cancel();
+        }
+        mExpandedView.setContentAlpha(1);
+        mExpandedView.setBackgroundAlpha(1);
+        mExpandedView.setManageButtonAlpha(1);
+        setCollapsedAmount(0);
+        mExpandedView.setBottomClip(0);
+        mExpandedView.movePointerBy(0, 0);
+        mCollapsedAmount = 0;
+        mDraggedAmount = 0;
+        mSwipeUpVelocity = 0;
+        mSwipeDownVelocity = 0;
+        mNotifiedAboutThreshold = false;
+    }
+
+    private float getCollapsedAmount() {
+        return mCollapsedAmount;
+    }
+
+    private void setCollapsedAmount(float collapsed) {
+        if (mCollapsedAmount != collapsed) {
+            float previous = mCollapsedAmount;
+            mCollapsedAmount = collapsed;
+
+            if (mExpandedView != null) {
+                if (previous == 0) {
+                    // View was not collapsed before. Apply z order change
+                    mExpandedView.setSurfaceZOrderedOnTop(true);
+                    mExpandedView.setAnimating(true);
+                }
+
+                mExpandedView.setTopClip((int) mCollapsedAmount);
+                // Move up with translationY. Use negative collapsed value
+                mExpandedView.setContentTranslationY(-mCollapsedAmount);
+                mExpandedView.setManageButtonTranslationY(-mCollapsedAmount);
+
+                if (mCollapsedAmount == 0) {
+                    // View is no longer collapsed. Revert z order change
+                    mExpandedView.setSurfaceZOrderedOnTop(false);
+                    mExpandedView.setAnimating(false);
+                }
+            }
+        }
+    }
+
+    private boolean isPastCollapseThreshold() {
+        if (mExpandedView != null) {
+            return mDraggedAmount > mExpandedView.getContentHeight() * COLLAPSE_THRESHOLD;
+        }
+        return false;
+    }
+
+    private AnimatorSet createCollapseAnimation(BubbleExpandedView expandedView,
+            Runnable startStackCollapse, Runnable after) {
+        List<Animator> animatorList = new ArrayList<>();
+        animatorList.add(createHeightAnimation(expandedView));
+        animatorList.add(createManageButtonAnimation());
+        ObjectAnimator contentAlphaAnimation = createContentAlphaAnimation();
+        final boolean[] notified = {false};
+        contentAlphaAnimation.addUpdateListener(animation -> {
+            if (!notified[0] && animation.getAnimatedFraction() > STACK_COLLAPSE_THRESHOLD) {
+                notified[0] = true;
+                // Notify bubbles that they can start moving back to the collapsed position
+                startStackCollapse.run();
+            }
+        });
+        animatorList.add(contentAlphaAnimation);
+        animatorList.add(createBackgroundAlphaAnimation());
+
+        AnimatorSet animatorSet = new AnimatorSet();
+        animatorSet.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                after.run();
+            }
+        });
+        animatorSet.playTogether(animatorList);
+        return animatorSet;
+    }
+
+    private ValueAnimator createHeightAnimation(BubbleExpandedView expandedView) {
+        ValueAnimator animator = ValueAnimator.ofInt((int) mCollapsedAmount,
+                expandedView.getContentHeight());
+        animator.setInterpolator(Interpolators.EMPHASIZED_ACCELERATE);
+        animator.setDuration(COLLAPSE_DURATION_MS);
+        animator.addUpdateListener(anim -> setCollapsedAmount((int) anim.getAnimatedValue()));
+        return animator;
+    }
+
+    private ObjectAnimator createManageButtonAnimation() {
+        ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandedView, MANAGE_BUTTON_ALPHA, 0f);
+        animator.setDuration(MANAGE_BUTTON_ANIM_DURATION_MS);
+        animator.setInterpolator(Interpolators.LINEAR);
+        return animator;
+    }
+
+    private ObjectAnimator createContentAlphaAnimation() {
+        ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandedView, CONTENT_ALPHA, 0f);
+        animator.setDuration(CONTENT_OPACITY_ANIM_DURATION_MS);
+        animator.setInterpolator(Interpolators.LINEAR);
+        animator.setStartDelay(CONTENT_OPACITY_ANIM_DELAY_MS);
+        return animator;
+    }
+
+    private ObjectAnimator createBackgroundAlphaAnimation() {
+        ObjectAnimator animator = ObjectAnimator.ofFloat(mExpandedView, BACKGROUND_ALPHA, 0f);
+        animator.setDuration(BACKGROUND_OPACITY_ANIM_DURATION_MS);
+        animator.setInterpolator(Interpolators.LINEAR);
+        animator.setStartDelay(BACKGROUND_OPACITY_ANIM_DELAY_MS);
+        return animator;
+    }
+
+    @SuppressLint("MissingPermission")
+    private void vibrateIfEnabled() {
+        if (mExpandedView != null) {
+            mExpandedView.performHapticFeedback(HapticFeedbackConstants.DRAG_CROSSING);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerStub.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerStub.java
new file mode 100644
index 0000000..bb8a3aa
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerStub.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.animation;
+
+import com.android.wm.shell.bubbles.BubbleExpandedView;
+
+/**
+ * Stub implementation {@link ExpandedViewAnimationController} that does not animate the
+ * {@link BubbleExpandedView}
+ */
+public class ExpandedViewAnimationControllerStub implements ExpandedViewAnimationController {
+    @Override
+    public void setExpandedView(BubbleExpandedView expandedView) {
+    }
+
+    @Override
+    public void updateDrag(float distance) {
+    }
+
+    @Override
+    public void setSwipeVelocity(float velocity) {
+    }
+
+    @Override
+    public boolean shouldCollapse() {
+        return false;
+    }
+
+    @Override
+    public void animateCollapse(Runnable startStackCollapse, Runnable after) {
+    }
+
+    @Override
+    public void animateBackToExpanded() {
+    }
+
+    @Override
+    public void animateForImeVisibilityChange(boolean visible) {
+    }
+
+    @Override
+    public void reset() {
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/OverScroll.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/OverScroll.java
new file mode 100644
index 0000000..d4e76ed
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/OverScroll.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.animation;
+
+/**
+ * Utility methods for overscroll damping and related effect.
+ *
+ * Copied from packages/apps/Launcher3/src/com/android/launcher3/touch/OverScroll.java
+ */
+public class OverScroll {
+
+    private static final float OVERSCROLL_DAMP_FACTOR = 0.07f;
+
+    /**
+     * This curve determines how the effect of scrolling over the limits of the page diminishes
+     * as the user pulls further and further from the bounds
+     *
+     * @param f The percentage of how much the user has overscrolled.
+     * @return A transformed percentage based on the influence curve.
+     */
+    private static float overScrollInfluenceCurve(float f) {
+        f -= 1.0f;
+        return f * f * f + 1.0f;
+    }
+
+    /**
+     * @param amount The original amount overscrolled.
+     * @param max The maximum amount that the View can overscroll.
+     * @return The dampened overscroll amount.
+     */
+    public static int dampedScroll(float amount, int max) {
+        if (Float.compare(amount, 0) == 0) return 0;
+
+        float f = amount / max;
+        f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
+
+        // Clamp this factor, f, to -1 < f < 1
+        if (Math.abs(f) >= 1) {
+            f /= Math.abs(f);
+        }
+
+        return Math.round(OVERSCROLL_DAMP_FACTOR * f * max);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java
index c32733d..28c7367 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java
@@ -16,11 +16,13 @@
 
 package com.android.wm.shell.common;
 
+import android.annotation.Nullable;
 import android.os.RemoteException;
 import android.util.Slog;
-import android.view.IDisplayWindowRotationCallback;
-import android.view.IDisplayWindowRotationController;
+import android.view.IDisplayChangeWindowCallback;
+import android.view.IDisplayChangeWindowController;
 import android.view.IWindowManager;
+import android.window.DisplayAreaInfo;
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.BinderThread;
@@ -40,17 +42,17 @@
 
     private final ShellExecutor mMainExecutor;
     private final IWindowManager mWmService;
-    private final IDisplayWindowRotationController mControllerImpl;
+    private final IDisplayChangeWindowController mControllerImpl;
 
-    private final CopyOnWriteArrayList<OnDisplayChangingListener> mRotationListener =
+    private final CopyOnWriteArrayList<OnDisplayChangingListener> mDisplayChangeListener =
             new CopyOnWriteArrayList<>();
 
     public DisplayChangeController(IWindowManager wmService, ShellExecutor mainExecutor) {
         mMainExecutor = mainExecutor;
         mWmService = wmService;
-        mControllerImpl = new DisplayWindowRotationControllerImpl();
+        mControllerImpl = new DisplayChangeWindowControllerImpl();
         try {
-            mWmService.setDisplayWindowRotationController(mControllerImpl);
+            mWmService.setDisplayChangeWindowController(mControllerImpl);
         } catch (RemoteException e) {
             throw new RuntimeException("Unable to register rotation controller");
         }
@@ -59,63 +61,64 @@
     /**
      * Adds a display rotation controller.
      */
-    public void addRotationListener(OnDisplayChangingListener listener) {
-        mRotationListener.add(listener);
+    public void addDisplayChangeListener(OnDisplayChangingListener listener) {
+        mDisplayChangeListener.add(listener);
     }
 
     /**
      * Removes a display rotation controller.
      */
-    public void removeRotationListener(OnDisplayChangingListener listener) {
-        mRotationListener.remove(listener);
+    public void removeDisplayChangeListener(OnDisplayChangingListener listener) {
+        mDisplayChangeListener.remove(listener);
     }
 
-    /** Query all listeners for changes that should happen on rotation. */
-    public void dispatchOnRotateDisplay(WindowContainerTransaction outWct, int displayId,
-            final int fromRotation, final int toRotation) {
-        for (OnDisplayChangingListener c : mRotationListener) {
-            c.onRotateDisplay(displayId, fromRotation, toRotation, outWct);
+    /** Query all listeners for changes that should happen on display change. */
+    public void dispatchOnDisplayChange(WindowContainerTransaction outWct, int displayId,
+            int fromRotation, int toRotation, DisplayAreaInfo newDisplayAreaInfo) {
+        for (OnDisplayChangingListener c : mDisplayChangeListener) {
+            c.onDisplayChange(displayId, fromRotation, toRotation, newDisplayAreaInfo, outWct);
         }
     }
 
-    private void onRotateDisplay(int displayId, final int fromRotation, final int toRotation,
-            IDisplayWindowRotationCallback callback) {
+    private void onDisplayChange(int displayId, int fromRotation, int toRotation,
+            DisplayAreaInfo newDisplayAreaInfo, IDisplayChangeWindowCallback callback) {
         WindowContainerTransaction t = new WindowContainerTransaction();
-        dispatchOnRotateDisplay(t, displayId, fromRotation, toRotation);
+        dispatchOnDisplayChange(t, displayId, fromRotation, toRotation, newDisplayAreaInfo);
         try {
-            callback.continueRotateDisplay(toRotation, t);
+            callback.continueDisplayChange(t);
         } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to continue rotation", e);
+            Slog.e(TAG, "Failed to continue handling display change", e);
         }
     }
 
     @BinderThread
-    private class DisplayWindowRotationControllerImpl
-            extends IDisplayWindowRotationController.Stub {
+    private class DisplayChangeWindowControllerImpl
+            extends IDisplayChangeWindowController.Stub {
         @Override
-        public void onRotateDisplay(int displayId, final int fromRotation,
-                final int toRotation, IDisplayWindowRotationCallback callback) {
-            mMainExecutor.execute(() -> {
-                DisplayChangeController.this.onRotateDisplay(displayId, fromRotation, toRotation,
-                        callback);
-            });
+        public void onDisplayChange(int displayId, int fromRotation, int toRotation,
+                DisplayAreaInfo newDisplayAreaInfo, IDisplayChangeWindowCallback callback) {
+            mMainExecutor.execute(() -> DisplayChangeController.this
+                    .onDisplayChange(displayId, fromRotation, toRotation,
+                            newDisplayAreaInfo, callback));
         }
     }
 
     /**
      * Give a listener a chance to queue up configuration changes to execute as part of a
-     * display rotation. The contents of {@link #onRotateDisplay} must run synchronously.
+     * display rotation. The contents of {@link #onDisplayChange} must run synchronously.
      */
     @ShellMainThread
     public interface OnDisplayChangingListener {
         /**
-         * Called before the display is rotated. Contents of this method must run synchronously.
-         * @param displayId Id of display that is rotating.
-         * @param fromRotation starting rotation of the display.
-         * @param toRotation target rotation of the display (after rotating).
+         * Called before the display size has changed.
+         * Contents of this method must run synchronously.
+         * @param displayId display id of the display that is under the change
+         * @param fromRotation rotation before the change
+         * @param toRotation rotation after the change
+         * @param newDisplayAreaInfo display area info after applying the update
          * @param t A task transaction to populate.
          */
-        void onRotateDisplay(int displayId, int fromRotation, int toRotation,
-                WindowContainerTransaction t);
+        void onDisplayChange(int displayId, int fromRotation, int toRotation,
+                @Nullable DisplayAreaInfo newDisplayAreaInfo, WindowContainerTransaction t);
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
index 4ba32e9..764936c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
@@ -156,14 +156,14 @@
      * Adds a display rotation controller.
      */
     public void addDisplayChangingController(OnDisplayChangingListener controller) {
-        mChangeController.addRotationListener(controller);
+        mChangeController.addDisplayChangeListener(controller);
     }
 
     /**
      * Removes a display rotation controller.
      */
     public void removeDisplayChangingController(OnDisplayChangingListener controller) {
-        mChangeController.removeRotationListener(controller);
+        mChangeController.removeDisplayChangeListener(controller);
     }
 
     private void onDisplayAdded(int displayId) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
index fd3aa05..ec344d3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
@@ -18,7 +18,9 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.Context;
 import android.text.TextUtils;
+import android.view.SurfaceControl;
 import android.view.View;
 
 import com.android.internal.jank.InteractionJankMonitor;
@@ -44,6 +46,24 @@
     }
 
     /**
+     * Begin a trace session.
+     *
+     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param context the context
+     * @param surface the surface to trace
+     * @param tag the tag to distinguish different flow of same type CUJ.
+     */
+    public static void beginTracing(@InteractionJankMonitor.CujType int cujType,
+            @NonNull Context context, @NonNull SurfaceControl surface, @Nullable String tag) {
+        final InteractionJankMonitor.Configuration.Builder builder =
+                InteractionJankMonitor.Configuration.Builder.withSurface(cujType, context, surface);
+        if (!TextUtils.isEmpty(tag)) {
+            builder.setTag(tag);
+        }
+        InteractionJankMonitor.getInstance().begin(builder);
+    }
+
+    /**
      * End a trace session.
      *
      * @param cujType the specific {@link InteractionJankMonitor.CujType}.
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 6305959..5ebe384 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
@@ -286,6 +286,7 @@
                 setTouching();
                 mStartPos = touchPos;
                 mMoving = false;
+                mSplitLayout.onStartDragging();
                 break;
             case MotionEvent.ACTION_MOVE:
                 mVelocityTracker.addMovement(event);
@@ -301,7 +302,10 @@
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
                 releaseTouching();
-                if (!mMoving) break;
+                if (!mMoving) {
+                    mSplitLayout.onDraggingCancelled();
+                    break;
+                }
 
                 mVelocityTracker.addMovement(event);
                 mVelocityTracker.computeCurrentVelocity(1000 /* units */);
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 bae2357..c962de6 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
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.DOCKED_RIGHT;
 import static android.view.WindowManager.DOCKED_TOP;
 
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE;
 import static com.android.internal.policy.DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END;
 import static com.android.internal.policy.DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START;
 import static com.android.wm.shell.animation.Interpolators.DIM_INTERPOLATOR;
@@ -34,6 +35,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
 import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.app.ActivityManager;
@@ -55,7 +57,6 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.policy.DividerSnapAlgorithm;
 import com.android.internal.policy.DockedDividerUtils;
 import com.android.wm.shell.R;
@@ -78,6 +79,8 @@
     public static final int PARALLAX_DISMISSING = 1;
     public static final int PARALLAX_ALIGN_CENTER = 2;
 
+    private static final int FLING_ANIMATION_DURATION = 250;
+
     private final int mDividerWindowWidth;
     private final int mDividerInsets;
     private final int mDividerSize;
@@ -85,7 +88,9 @@
     private final Rect mTempRect = new Rect();
     private final Rect mRootBounds = new Rect();
     private final Rect mDividerBounds = new Rect();
+    // Bounds1 final position should be always at top or left
     private final Rect mBounds1 = new Rect();
+    // Bounds2 final position should be always at bottom or right
     private final Rect mBounds2 = new Rect();
     private final Rect mWinBounds1 = new Rect();
     private final Rect mWinBounds2 = new Rect();
@@ -178,6 +183,11 @@
         return outBounds;
     }
 
+    /** Gets root bounds of the whole split layout */
+    public Rect getRootBounds() {
+        return new Rect(mRootBounds);
+    }
+
     /** Gets bounds of divider window with screen based coordinate. */
     public Rect getDividerBounds() {
         return new Rect(mDividerBounds);
@@ -270,28 +280,35 @@
         updateBounds(mDividePosition);
     }
 
-    /** Updates recording bounds of divider window and both of the splits. */
     private void updateBounds(int position) {
-        mDividerBounds.set(mRootBounds);
-        mBounds1.set(mRootBounds);
-        mBounds2.set(mRootBounds);
+        updateBounds(position, mBounds1, mBounds2, mDividerBounds, true /* setEffectBounds */);
+    }
+
+    /** Updates recording bounds of divider window and both of the splits. */
+    private void updateBounds(int position, Rect bounds1, Rect bounds2, Rect dividerBounds,
+            boolean setEffectBounds) {
+        dividerBounds.set(mRootBounds);
+        bounds1.set(mRootBounds);
+        bounds2.set(mRootBounds);
         final boolean isLandscape = isLandscape(mRootBounds);
         if (isLandscape) {
             position += mRootBounds.left;
-            mDividerBounds.left = position - mDividerInsets;
-            mDividerBounds.right = mDividerBounds.left + mDividerWindowWidth;
-            mBounds1.right = position;
-            mBounds2.left = mBounds1.right + mDividerSize;
+            dividerBounds.left = position - mDividerInsets;
+            dividerBounds.right = dividerBounds.left + mDividerWindowWidth;
+            bounds1.right = position;
+            bounds2.left = bounds1.right + mDividerSize;
         } else {
             position += mRootBounds.top;
-            mDividerBounds.top = position - mDividerInsets;
-            mDividerBounds.bottom = mDividerBounds.top + mDividerWindowWidth;
-            mBounds1.bottom = position;
-            mBounds2.top = mBounds1.bottom + mDividerSize;
+            dividerBounds.top = position - mDividerInsets;
+            dividerBounds.bottom = dividerBounds.top + mDividerWindowWidth;
+            bounds1.bottom = position;
+            bounds2.top = bounds1.bottom + mDividerSize;
         }
-        DockedDividerUtils.sanitizeStackBounds(mBounds1, true /** topLeft */);
-        DockedDividerUtils.sanitizeStackBounds(mBounds2, false /** topLeft */);
-        mSurfaceEffectPolicy.applyDividerPosition(position, isLandscape);
+        DockedDividerUtils.sanitizeStackBounds(bounds1, true /** topLeft */);
+        DockedDividerUtils.sanitizeStackBounds(bounds2, false /** topLeft */);
+        if (setEffectBounds) {
+            mSurfaceEffectPolicy.applyDividerPosition(position, isLandscape);
+        }
     }
 
     /** Inflates {@link DividerView} on the root surface. */
@@ -407,6 +424,15 @@
         }
     }
 
+    void onStartDragging() {
+        InteractionJankMonitorUtils.beginTracing(CUJ_SPLIT_SCREEN_RESIZE, mContext,
+                getDividerLeash(), null /* tag */);
+    }
+
+    void onDraggingCancelled() {
+        InteractionJankMonitorUtils.cancelTracing(CUJ_SPLIT_SCREEN_RESIZE);
+    }
+
     void onDoubleTappedDivider() {
         mSplitLayoutHandler.onDoubleTappedDivider();
     }
@@ -438,13 +464,13 @@
         if (from == to) {
             // No animation run, still callback to stop resizing.
             mSplitLayoutHandler.onLayoutSizeChanged(this);
+            InteractionJankMonitorUtils.endTracing(
+                    CUJ_SPLIT_SCREEN_RESIZE);
             return;
         }
-        InteractionJankMonitorUtils.beginTracing(InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE,
-                mSplitWindowManager.getDividerView(), "Divider fling");
         ValueAnimator animator = ValueAnimator
                 .ofInt(from, to)
-                .setDuration(250);
+                .setDuration(FLING_ANIMATION_DURATION);
         animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         animator.addUpdateListener(
                 animation -> updateDivideBounds((int) animation.getAnimatedValue()));
@@ -455,7 +481,7 @@
                     flingFinishedCallback.run();
                 }
                 InteractionJankMonitorUtils.endTracing(
-                        InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE);
+                        CUJ_SPLIT_SCREEN_RESIZE);
             }
 
             @Override
@@ -466,6 +492,86 @@
         animator.start();
     }
 
+    /** Swich both surface position with animation. */
+    public void splitSwitching(SurfaceControl.Transaction t, SurfaceControl leash1,
+            SurfaceControl leash2, Runnable finishCallback) {
+        final boolean isLandscape = isLandscape();
+        final Rect insets = getDisplayInsets(mContext);
+        insets.set(isLandscape ? insets.left : 0, isLandscape ? 0 : insets.top,
+                isLandscape ? insets.right : 0, isLandscape ? 0 : insets.bottom);
+
+        final int dividerPos = mDividerSnapAlgorithm.calculateNonDismissingSnapTarget(
+                isLandscape ? mBounds2.width() : mBounds2.height()).position;
+        final Rect distBounds1 = new Rect();
+        final Rect distBounds2 = new Rect();
+        final Rect distDividerBounds = new Rect();
+        // Compute dist bounds.
+        updateBounds(dividerPos, distBounds2, distBounds1, distDividerBounds,
+                false /* setEffectBounds */);
+        // Offset to real position under root container.
+        distBounds1.offset(-mRootBounds.left, -mRootBounds.top);
+        distBounds2.offset(-mRootBounds.left, -mRootBounds.top);
+        distDividerBounds.offset(-mRootBounds.left, -mRootBounds.top);
+        // DO NOT move to insets area for smooth animation.
+        distBounds1.set(distBounds1.left, distBounds1.top,
+                distBounds1.right - insets.right, distBounds1.bottom - insets.bottom);
+        distBounds2.set(distBounds2.left + insets.left, distBounds2.top + insets.top,
+                distBounds2.right, distBounds2.bottom);
+
+        ValueAnimator animator1 = moveSurface(t, leash1, getRefBounds1(), distBounds1,
+                false /* alignStart */);
+        ValueAnimator animator2 = moveSurface(t, leash2, getRefBounds2(), distBounds2,
+                true /* alignStart */);
+        ValueAnimator animator3 = moveSurface(t, getDividerLeash(), getRefDividerBounds(),
+                distDividerBounds, true /* alignStart */);
+
+        AnimatorSet set = new AnimatorSet();
+        set.playTogether(animator1, animator2, animator3);
+        set.setDuration(FLING_ANIMATION_DURATION);
+        set.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mDividePosition = dividerPos;
+                updateBounds(mDividePosition);
+                finishCallback.run();
+            }
+        });
+        set.start();
+    }
+
+    private ValueAnimator moveSurface(SurfaceControl.Transaction t, SurfaceControl leash,
+            Rect start, Rect end, boolean alignStart) {
+        Rect tempStart = new Rect(start);
+        Rect tempEnd = new Rect(end);
+        final float diffX = tempEnd.left - tempStart.left;
+        final float diffY = tempEnd.top - tempStart.top;
+        final float diffWidth = tempEnd.width() - tempStart.width();
+        final float diffHeight = tempEnd.height() - tempStart.height();
+        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
+        animator.addUpdateListener(animation -> {
+            if (leash == null) return;
+
+            final float scale = (float) animation.getAnimatedValue();
+            final float distX = tempStart.left + scale * diffX;
+            final float distY = tempStart.top + scale * diffY;
+            final int width = (int) (tempStart.width() + scale * diffWidth);
+            final int height = (int) (tempStart.height() + scale * diffHeight);
+            if (alignStart) {
+                t.setPosition(leash, distX, distY);
+                t.setWindowCrop(leash, width, height);
+            } else {
+                final int offsetX = width - start.width();
+                final int offsetY = height - start.height();
+                t.setPosition(leash, distX + offsetX, distY + offsetY);
+                mTempRect.set(0, 0, width, height);
+                mTempRect.offsetTo(-offsetX, -offsetY);
+                t.setCrop(leash, mTempRect);
+            }
+            t.apply();
+        });
+        return animator;
+    }
+
     private static Rect getDisplayInsets(Context context) {
         return context.getSystemService(WindowManager.class)
                 .getMaximumWindowMetrics()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index db6131a..2ea111b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -38,8 +38,6 @@
 import com.android.wm.shell.TaskViewFactoryController;
 import com.android.wm.shell.TaskViewTransitions;
 import com.android.wm.shell.WindowManagerShellWrapper;
-import com.android.wm.shell.apppairs.AppPairs;
-import com.android.wm.shell.apppairs.AppPairsController;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.back.BackAnimationController;
 import com.android.wm.shell.bubbles.BubbleController;
@@ -66,12 +64,9 @@
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.freeform.FreeformTaskListener;
 import com.android.wm.shell.fullscreen.FullscreenTaskListener;
-import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutoutController;
 import com.android.wm.shell.kidsmode.KidsModeTaskOrganizer;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.onehanded.OneHandedController;
 import com.android.wm.shell.pip.Pip;
@@ -92,6 +87,7 @@
 import com.android.wm.shell.transition.ShellTransitions;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
+import com.android.wm.shell.unfold.UnfoldAnimationController;
 import com.android.wm.shell.unfold.UnfoldTransitionHandler;
 
 import java.util.Optional;
@@ -180,9 +176,11 @@
     static ShellTaskOrganizer provideShellTaskOrganizer(@ShellMainThread ShellExecutor mainExecutor,
             Context context,
             CompatUIController compatUI,
+            Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<RecentTasksController> recentTasksOptional
     ) {
-        return new ShellTaskOrganizer(mainExecutor, context, compatUI, recentTasksOptional);
+        return new ShellTaskOrganizer(mainExecutor, context, compatUI, unfoldAnimationController,
+                recentTasksOptional);
     }
 
     @WMSingleton
@@ -194,10 +192,12 @@
             SyncTransactionQueue syncTransactionQueue,
             DisplayController displayController,
             DisplayInsetsController displayInsetsController,
+            Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<RecentTasksController> recentTasksOptional
     ) {
         return new KidsModeTaskOrganizer(mainExecutor, mainHandler, context, syncTransactionQueue,
-                displayController, displayInsetsController, recentTasksOptional);
+                displayController, displayInsetsController, unfoldAnimationController,
+                recentTasksOptional);
     }
 
     @WMSingleton
@@ -294,13 +294,11 @@
     static FullscreenTaskListener provideFullscreenTaskListener(
             @DynamicOverride Optional<FullscreenTaskListener> fullscreenTaskListener,
             SyncTransactionQueue syncQueue,
-            Optional<FullscreenUnfoldController> optionalFullscreenUnfoldController,
             Optional<RecentTasksController> recentTasksOptional) {
         if (fullscreenTaskListener.isPresent()) {
             return fullscreenTaskListener.get();
         } else {
-            return new FullscreenTaskListener(syncQueue, optionalFullscreenUnfoldController,
-                    recentTasksOptional);
+            return new FullscreenTaskListener(syncQueue, recentTasksOptional);
         }
     }
 
@@ -314,31 +312,33 @@
     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
     @BindsOptionalOf
     @DynamicOverride
-    abstract FullscreenUnfoldController optionalFullscreenUnfoldController();
+    abstract UnfoldAnimationController optionalUnfoldController();
 
     @WMSingleton
     @Provides
-    static Optional<FullscreenUnfoldController> provideFullscreenUnfoldController(
-            @DynamicOverride Optional<FullscreenUnfoldController> fullscreenUnfoldController,
+    static Optional<UnfoldAnimationController> provideUnfoldController(
+            @DynamicOverride Lazy<Optional<UnfoldAnimationController>>
+                    fullscreenUnfoldController,
             Optional<ShellUnfoldProgressProvider> progressProvider) {
         if (progressProvider.isPresent()
                 && progressProvider.get() != ShellUnfoldProgressProvider.NO_PROVIDER) {
-            return fullscreenUnfoldController;
+            return fullscreenUnfoldController.get();
         }
         return Optional.empty();
     }
 
+    @BindsOptionalOf
+    @DynamicOverride
+    abstract UnfoldTransitionHandler optionalUnfoldTransitionHandler();
+
     @WMSingleton
     @Provides
     static Optional<UnfoldTransitionHandler> provideUnfoldTransitionHandler(
             Optional<ShellUnfoldProgressProvider> progressProvider,
-            TransactionPool transactionPool,
-            Transitions transitions,
-            @ShellMainThread ShellExecutor executor) {
-        if (progressProvider.isPresent()) {
-            return Optional.of(
-                    new UnfoldTransitionHandler(progressProvider.get(), transactionPool, executor,
-                            transitions));
+            @DynamicOverride Lazy<Optional<UnfoldTransitionHandler>> handler) {
+        if (progressProvider.isPresent()
+                && progressProvider.get() != ShellUnfoldProgressProvider.NO_PROVIDER) {
+            return handler.get();
         }
         return Optional.empty();
     }
@@ -350,12 +350,12 @@
     // Workaround for dynamic overriding with a default implementation, see {@link DynamicOverride}
     @BindsOptionalOf
     @DynamicOverride
-    abstract FreeformTaskListener optionalFreeformTaskListener();
+    abstract FreeformTaskListener<?> optionalFreeformTaskListener();
 
     @WMSingleton
     @Provides
-    static Optional<FreeformTaskListener> provideFreeformTaskListener(
-            @DynamicOverride Optional<FreeformTaskListener> freeformTaskListener,
+    static Optional<FreeformTaskListener<?>> provideFreeformTaskListener(
+            @DynamicOverride Optional<FreeformTaskListener<?>> freeformTaskListener,
             Context context) {
         if (FreeformTaskListener.isFreeformEnabled(context)) {
             return freeformTaskListener;
@@ -561,29 +561,6 @@
         return Optional.empty();
     }
 
-    // Legacy split (optional feature)
-
-    @WMSingleton
-    @Provides
-    static Optional<LegacySplitScreen> provideLegacySplitScreen(
-            Optional<LegacySplitScreenController> splitScreenController) {
-        return splitScreenController.map((controller) -> controller.asLegacySplitScreen());
-    }
-
-    @BindsOptionalOf
-    abstract LegacySplitScreenController optionalLegacySplitScreenController();
-
-    // App Pairs (optional feature)
-
-    @WMSingleton
-    @Provides
-    static Optional<AppPairs> provideAppPairs(Optional<AppPairsController> appPairsController) {
-        return appPairsController.map((controller) -> controller.asAppPairs());
-    }
-
-    @BindsOptionalOf
-    abstract AppPairsController optionalAppPairs();
-
     //
     // Starting window
     //
@@ -664,12 +641,11 @@
             KidsModeTaskOrganizer kidsModeTaskOrganizer,
             Optional<BubbleController> bubblesOptional,
             Optional<SplitScreenController> splitScreenOptional,
-            Optional<AppPairsController> appPairsOptional,
             Optional<PipTouchHandler> pipTouchHandlerOptional,
             FullscreenTaskListener fullscreenTaskListener,
-            Optional<FullscreenUnfoldController> appUnfoldTransitionController,
+            Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
-            Optional<FreeformTaskListener> freeformTaskListener,
+            Optional<FreeformTaskListener<?>> freeformTaskListener,
             Optional<RecentTasksController> recentTasksOptional,
             Transitions transitions,
             StartingWindowController startingWindow,
@@ -682,10 +658,9 @@
                 kidsModeTaskOrganizer,
                 bubblesOptional,
                 splitScreenOptional,
-                appPairsOptional,
                 pipTouchHandlerOptional,
                 fullscreenTaskListener,
-                appUnfoldTransitionController,
+                unfoldAnimationController,
                 unfoldTransitionHandler,
                 freeformTaskListener,
                 recentTasksOptional,
@@ -709,17 +684,15 @@
     static ShellCommandHandlerImpl provideShellCommandHandlerImpl(
             ShellTaskOrganizer shellTaskOrganizer,
             KidsModeTaskOrganizer kidsModeTaskOrganizer,
-            Optional<LegacySplitScreenController> legacySplitScreenOptional,
             Optional<SplitScreenController> splitScreenOptional,
             Optional<Pip> pipOptional,
             Optional<OneHandedController> oneHandedOptional,
             Optional<HideDisplayCutoutController> hideDisplayCutout,
-            Optional<AppPairsController> appPairsOptional,
             Optional<RecentTasksController> recentTasksOptional,
             @ShellMainThread ShellExecutor mainExecutor) {
         return new ShellCommandHandlerImpl(shellTaskOrganizer, kidsModeTaskOrganizer,
-                legacySplitScreenOptional, splitScreenOptional, pipOptional, oneHandedOptional,
-                hideDisplayCutout, appPairsOptional, recentTasksOptional, mainExecutor);
+                splitScreenOptional, pipOptional, oneHandedOptional, hideDisplayCutout,
+                recentTasksOptional, mainExecutor);
     }
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index b3799e2..a8c1071 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.dagger;
 
-import android.animation.AnimationHandler;
 import android.content.Context;
 import android.content.pm.LauncherApps;
 import android.os.Handler;
@@ -31,7 +30,6 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.TaskViewTransitions;
 import com.android.wm.shell.WindowManagerShellWrapper;
-import com.android.wm.shell.apppairs.AppPairsController;
 import com.android.wm.shell.bubbles.BubbleController;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
@@ -43,13 +41,10 @@
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.common.annotations.ChoreographerSfVsync;
 import com.android.wm.shell.common.annotations.ShellBackgroundThread;
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.freeform.FreeformTaskListener;
-import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreenController;
 import com.android.wm.shell.onehanded.OneHandedController;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.pip.PipAnimationController;
@@ -67,19 +62,29 @@
 import com.android.wm.shell.pip.PipUiEventLogger;
 import com.android.wm.shell.pip.phone.PhonePipMenuController;
 import com.android.wm.shell.pip.phone.PipController;
+import com.android.wm.shell.pip.phone.PipKeepClearAlgorithm;
 import com.android.wm.shell.pip.phone.PipMotionHelper;
 import com.android.wm.shell.pip.phone.PipTouchHandler;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.splitscreen.SplitScreenController;
-import com.android.wm.shell.splitscreen.StageTaskUnfoldController;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
+import com.android.wm.shell.unfold.UnfoldAnimationController;
 import com.android.wm.shell.unfold.UnfoldBackgroundController;
+import com.android.wm.shell.unfold.UnfoldTransitionHandler;
+import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator;
+import com.android.wm.shell.unfold.animation.SplitTaskUnfoldAnimator;
+import com.android.wm.shell.unfold.animation.UnfoldTaskAnimator;
+import com.android.wm.shell.unfold.qualifier.UnfoldShellTransition;
+import com.android.wm.shell.unfold.qualifier.UnfoldTransition;
+import com.android.wm.shell.windowdecor.CaptionWindowDecorViewModel;
+import com.android.wm.shell.windowdecor.WindowDecorViewModel;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Optional;
 
-import javax.inject.Provider;
-
+import dagger.Binds;
 import dagger.Lazy;
 import dagger.Module;
 import dagger.Provides;
@@ -93,7 +98,7 @@
  * dependencies should go into {@link WMShellBaseModule}.
  */
 @Module(includes = WMShellBaseModule.class)
-public class WMShellModule {
+public abstract class WMShellModule {
 
     //
     // Bubbles
@@ -129,15 +134,36 @@
     }
 
     //
+    // Window decoration
+    //
+
+    @WMSingleton
+    @Provides
+    static WindowDecorViewModel<?> provideWindowDecorViewModel(
+            Context context,
+            @ShellMainThread Handler mainHandler,
+            ShellTaskOrganizer taskOrganizer,
+            DisplayController displayController,
+            SyncTransactionQueue syncQueue) {
+        return new CaptionWindowDecorViewModel(
+                        context,
+                        mainHandler,
+                        taskOrganizer,
+                        displayController,
+                        syncQueue);
+    }
+
+    //
     // Freeform
     //
 
     @WMSingleton
     @Provides
     @DynamicOverride
-    static FreeformTaskListener provideFreeformTaskListener(
+    static FreeformTaskListener<?> provideFreeformTaskListener(
+            WindowDecorViewModel<?> windowDecorViewModel,
             SyncTransactionQueue syncQueue) {
-        return new FreeformTaskListener(syncQueue);
+        return new FreeformTaskListener<>(windowDecorViewModel, syncQueue);
     }
 
     //
@@ -174,37 +200,11 @@
             DisplayImeController displayImeController,
             DisplayInsetsController displayInsetsController, Transitions transitions,
             TransactionPool transactionPool, IconProvider iconProvider,
-            Optional<RecentTasksController> recentTasks,
-            Provider<Optional<StageTaskUnfoldController>> stageTaskUnfoldControllerProvider) {
+            Optional<RecentTasksController> recentTasks) {
         return new SplitScreenController(shellTaskOrganizer, syncQueue, context,
                 rootTaskDisplayAreaOrganizer, mainExecutor, displayController, displayImeController,
                 displayInsetsController, transitions, transactionPool, iconProvider,
-                recentTasks, stageTaskUnfoldControllerProvider);
-    }
-
-    @WMSingleton
-    @Provides
-    static LegacySplitScreenController provideLegacySplitScreen(Context context,
-            DisplayController displayController, SystemWindows systemWindows,
-            DisplayImeController displayImeController, TransactionPool transactionPool,
-            ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue,
-            TaskStackListenerImpl taskStackListener, Transitions transitions,
-            @ShellMainThread ShellExecutor mainExecutor,
-            @ChoreographerSfVsync AnimationHandler sfVsyncAnimationHandler) {
-        return new LegacySplitScreenController(context, displayController, systemWindows,
-                displayImeController, transactionPool, shellTaskOrganizer, syncQueue,
-                taskStackListener, transitions, mainExecutor, sfVsyncAnimationHandler);
-    }
-
-    @WMSingleton
-    @Provides
-    static AppPairsController provideAppPairs(ShellTaskOrganizer shellTaskOrganizer,
-            SyncTransactionQueue syncQueue, DisplayController displayController,
-            @ShellMainThread ShellExecutor mainExecutor,
-            DisplayImeController displayImeController,
-            DisplayInsetsController displayInsetsController) {
-        return new AppPairsController(shellTaskOrganizer, syncQueue, displayController,
-                mainExecutor, displayImeController, displayInsetsController);
+                recentTasks);
     }
 
     //
@@ -215,8 +215,10 @@
     @Provides
     static Optional<Pip> providePip(Context context, DisplayController displayController,
             PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
-            PipBoundsState pipBoundsState, PipMediaController pipMediaController,
+            PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState,
+            PipMotionHelper pipMotionHelper, PipMediaController pipMediaController,
             PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
+            PipTransitionState pipTransitionState,
             PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
             WindowManagerShellWrapper windowManagerShellWrapper,
             TaskStackListenerImpl taskStackListener,
@@ -224,8 +226,9 @@
             Optional<OneHandedController> oneHandedController,
             @ShellMainThread ShellExecutor mainExecutor) {
         return Optional.ofNullable(PipController.create(context, displayController,
-                pipAppOpsListener, pipBoundsAlgorithm, pipBoundsState,
-                pipMediaController, phonePipMenuController, pipTaskOrganizer,
+                pipAppOpsListener, pipBoundsAlgorithm, pipKeepClearAlgorithm, pipBoundsState,
+                pipMotionHelper,
+                pipMediaController, phonePipMenuController, pipTaskOrganizer, pipTransitionState,
                 pipTouchHandler, pipTransitionController, windowManagerShellWrapper,
                 taskStackListener, pipParamsChangedForwarder, oneHandedController, mainExecutor));
     }
@@ -244,6 +247,12 @@
 
     @WMSingleton
     @Provides
+    static PipKeepClearAlgorithm providePipKeepClearAlgorithm() {
+        return new PipKeepClearAlgorithm();
+    }
+
+    @WMSingleton
+    @Provides
     static PipBoundsAlgorithm providesPipBoundsAlgorithm(Context context,
             PipBoundsState pipBoundsState, PipSnapAlgorithm pipSnapAlgorithm) {
         return new PipBoundsAlgorithm(context, pipBoundsState, pipSnapAlgorithm);
@@ -351,40 +360,77 @@
     //
     // Unfold transition
     //
-
     @WMSingleton
     @Provides
     @DynamicOverride
-    static FullscreenUnfoldController provideFullscreenUnfoldController(
-            Context context,
+    static UnfoldAnimationController provideUnfoldAnimationController(
             Optional<ShellUnfoldProgressProvider> progressProvider,
-            Lazy<UnfoldBackgroundController> unfoldBackgroundController,
-            DisplayInsetsController displayInsetsController,
+            TransactionPool transactionPool,
+            @UnfoldTransition SplitTaskUnfoldAnimator splitAnimator,
+            FullscreenUnfoldTaskAnimator fullscreenAnimator,
+            Lazy<Optional<UnfoldTransitionHandler>> unfoldTransitionHandler,
             @ShellMainThread ShellExecutor mainExecutor
     ) {
-        return new FullscreenUnfoldController(context, mainExecutor,
-                unfoldBackgroundController.get(), progressProvider.get(),
+        final List<UnfoldTaskAnimator> animators = new ArrayList<>();
+        animators.add(splitAnimator);
+        animators.add(fullscreenAnimator);
+
+        return new UnfoldAnimationController(
+                        transactionPool,
+                        progressProvider.get(),
+                        animators,
+                        unfoldTransitionHandler,
+                        mainExecutor
+                );
+    }
+
+
+    @Provides
+    static FullscreenUnfoldTaskAnimator provideFullscreenUnfoldTaskAnimator(
+            Context context,
+            UnfoldBackgroundController unfoldBackgroundController,
+            DisplayInsetsController displayInsetsController
+    ) {
+        return new FullscreenUnfoldTaskAnimator(context, unfoldBackgroundController,
                 displayInsetsController);
     }
 
     @Provides
-    static Optional<StageTaskUnfoldController> provideStageTaskUnfoldController(
-            Optional<ShellUnfoldProgressProvider> progressProvider,
+    static SplitTaskUnfoldAnimator provideSplitTaskUnfoldAnimatorBase(
             Context context,
-            TransactionPool transactionPool,
-            Lazy<UnfoldBackgroundController> unfoldBackgroundController,
-            DisplayInsetsController displayInsetsController,
-            @ShellMainThread ShellExecutor mainExecutor
+            UnfoldBackgroundController backgroundController,
+            @ShellMainThread ShellExecutor executor,
+            Lazy<Optional<SplitScreenController>> splitScreenOptional,
+            DisplayInsetsController displayInsetsController
     ) {
-        return progressProvider.map(shellUnfoldTransitionProgressProvider ->
-                new StageTaskUnfoldController(
-                        context,
-                        transactionPool,
-                        shellUnfoldTransitionProgressProvider,
-                        displayInsetsController,
-                        unfoldBackgroundController.get(),
-                        mainExecutor
-                ));
+        return new SplitTaskUnfoldAnimator(context, executor, splitScreenOptional,
+                backgroundController, displayInsetsController);
+    }
+
+    @WMSingleton
+    @UnfoldShellTransition
+    @Binds
+    abstract SplitTaskUnfoldAnimator provideShellSplitTaskUnfoldAnimator(
+            SplitTaskUnfoldAnimator splitTaskUnfoldAnimator);
+
+    @WMSingleton
+    @UnfoldTransition
+    @Binds
+    abstract SplitTaskUnfoldAnimator provideSplitTaskUnfoldAnimator(
+            SplitTaskUnfoldAnimator splitTaskUnfoldAnimator);
+
+    @WMSingleton
+    @Provides
+    @DynamicOverride
+    static UnfoldTransitionHandler provideUnfoldTransitionHandler(
+            Optional<ShellUnfoldProgressProvider> progressProvider,
+            FullscreenUnfoldTaskAnimator animator,
+            @UnfoldShellTransition SplitTaskUnfoldAnimator unfoldAnimator,
+            TransactionPool transactionPool,
+            Transitions transitions,
+            @ShellMainThread ShellExecutor executor) {
+        return new UnfoldTransitionHandler(progressProvider.get(), animator,
+                unfoldAnimator, transactionPool, executor, transitions);
     }
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index 7568310..6373728 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
@@ -67,6 +67,7 @@
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.common.split.SplitLayout;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -75,6 +76,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * The policy for handling drag and drop operations to shell.
@@ -289,18 +291,15 @@
         final ComponentName currentActivity;
         if (!inSplitScreen) {
             currentActivity = mSession.runningTaskInfo != null
-                    ? mSession.runningTaskInfo.baseActivity
+                    ? mSession.runningTaskInfo.baseIntent.getComponent()
                     : null;
         } else {
-            final int nonReplacedSplitPosition = position == SPLIT_POSITION_TOP_OR_LEFT
-                    ? SPLIT_POSITION_BOTTOM_OR_RIGHT
-                    : SPLIT_POSITION_TOP_OR_LEFT;
-            ActivityManager.RunningTaskInfo nonReplacedTaskInfo =
-                    mSplitScreen.getTaskInfo(nonReplacedSplitPosition);
-            currentActivity = nonReplacedTaskInfo.baseActivity;
+            final ActivityManager.RunningTaskInfo nonReplacedTaskInfo =
+                    mSplitScreen.getTaskInfo(SplitLayout.reversePosition(position));
+            currentActivity = nonReplacedTaskInfo.baseIntent.getComponent();
         }
 
-        if (currentActivity.equals(dragIntentActivity)) {
+        if (Objects.equals(currentActivity, dragIntentActivity)) {
             // Only apply MULTIPLE_TASK if we are dragging the same activity
             final Intent fillInIntent = new Intent();
             fillInIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index fef9be3..692e6ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -21,8 +21,6 @@
 
 import android.app.ActivityManager.RunningTaskInfo;
 import android.content.Context;
-import android.graphics.Point;
-import android.graphics.Rect;
 import android.provider.Settings;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -32,26 +30,35 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.windowdecor.WindowDecorViewModel;
 
 import java.io.PrintWriter;
 
 /**
  * {@link ShellTaskOrganizer.TaskListener} for {@link
  * ShellTaskOrganizer#TASK_LISTENER_TYPE_FREEFORM}.
+ *
+ * @param <T> the type of window decoration instance
  */
-public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener {
+public class FreeformTaskListener<T extends AutoCloseable>
+        implements ShellTaskOrganizer.TaskListener {
     private static final String TAG = "FreeformTaskListener";
 
+    private final WindowDecorViewModel<T> mWindowDecorationViewModel;
     private final SyncTransactionQueue mSyncQueue;
 
-    private final SparseArray<State> mTasks = new SparseArray<>();
+    private final SparseArray<State<T>> mTasks = new SparseArray<>();
 
-    private static class State {
+    private static class State<T extends AutoCloseable> {
         RunningTaskInfo mTaskInfo;
         SurfaceControl mLeash;
+        T mWindowDecoration;
     }
 
-    public FreeformTaskListener(SyncTransactionQueue syncQueue) {
+    public FreeformTaskListener(
+            WindowDecorViewModel<T> windowDecorationViewModel,
+            SyncTransactionQueue syncQueue) {
+        mWindowDecorationViewModel = windowDecorationViewModel;
         mSyncQueue = syncQueue;
     }
 
@@ -62,23 +69,17 @@
         }
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Freeform Task Appeared: #%d",
                 taskInfo.taskId);
-        final State state = new State();
+        final State<T> state = new State<>();
         state.mTaskInfo = taskInfo;
         state.mLeash = leash;
+        state.mWindowDecoration =
+                mWindowDecorationViewModel.createWindowDecoration(taskInfo, leash);
         mTasks.put(taskInfo.taskId, state);
-
-        final Rect taskBounds = taskInfo.configuration.windowConfiguration.getBounds();
-        mSyncQueue.runInSync(t -> {
-            Point taskPosition = taskInfo.positionInParent;
-            t.setPosition(leash, taskPosition.x, taskPosition.y)
-                    .setWindowCrop(leash, taskBounds.width(), taskBounds.height())
-                    .show(leash);
-        });
     }
 
     @Override
     public void onTaskVanished(RunningTaskInfo taskInfo) {
-        State state = mTasks.get(taskInfo.taskId);
+        State<T> state = mTasks.get(taskInfo.taskId);
         if (state == null) {
             Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);
             return;
@@ -86,11 +87,17 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Freeform Task Vanished: #%d",
                 taskInfo.taskId);
         mTasks.remove(taskInfo.taskId);
+
+        try {
+            state.mWindowDecoration.close();
+        } catch (Exception e) {
+            Slog.e(TAG, "Failed to release window decoration.", e);
+        }
     }
 
     @Override
     public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
-        State state = mTasks.get(taskInfo.taskId);
+        State<T> state = mTasks.get(taskInfo.taskId);
         if (state == null) {
             throw new RuntimeException(
                     "Task info changed before appearing: #" + taskInfo.taskId);
@@ -98,15 +105,7 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Freeform Task Info Changed: #%d",
                 taskInfo.taskId);
         state.mTaskInfo = taskInfo;
-
-        final Rect taskBounds = taskInfo.configuration.windowConfiguration.getBounds();
-        final SurfaceControl leash = state.mLeash;
-        mSyncQueue.runInSync(t -> {
-            Point taskPosition = taskInfo.positionInParent;
-            t.setPosition(leash, taskPosition.x, taskPosition.y)
-                    .setWindowCrop(leash, taskBounds.width(), taskBounds.height())
-                    .show(leash);
-        });
+        mWindowDecorationViewModel.onTaskInfoChanged(state.mTaskInfo, state.mWindowDecoration);
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 73e6cba..79e363b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -16,17 +16,13 @@
 
 package com.android.wm.shell.fullscreen;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FULLSCREEN;
 import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString;
 
 import android.app.ActivityManager.RunningTaskInfo;
-import android.app.TaskInfo;
 import android.graphics.Point;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.SparseBooleanArray;
 import android.view.SurfaceControl;
 
 import androidx.annotation.NonNull;
@@ -48,22 +44,17 @@
     private static final String TAG = "FullscreenTaskListener";
 
     private final SyncTransactionQueue mSyncQueue;
-    private final FullscreenUnfoldController mFullscreenUnfoldController;
     private final Optional<RecentTasksController> mRecentTasksOptional;
 
     private final SparseArray<TaskData> mDataByTaskId = new SparseArray<>();
-    private final AnimatableTasksListener mAnimatableTasksListener = new AnimatableTasksListener();
 
-    public FullscreenTaskListener(SyncTransactionQueue syncQueue,
-            Optional<FullscreenUnfoldController> unfoldController) {
-        this(syncQueue, unfoldController, Optional.empty());
+    public FullscreenTaskListener(SyncTransactionQueue syncQueue) {
+        this(syncQueue, Optional.empty());
     }
 
     public FullscreenTaskListener(SyncTransactionQueue syncQueue,
-            Optional<FullscreenUnfoldController> unfoldController,
             Optional<RecentTasksController> recentTasks) {
         mSyncQueue = syncQueue;
-        mFullscreenUnfoldController = unfoldController.orElse(null);
         mRecentTasksOptional = recentTasks;
     }
 
@@ -76,6 +67,7 @@
                 taskInfo.taskId);
         final Point positionInParent = taskInfo.positionInParent;
         mDataByTaskId.put(taskInfo.taskId, new TaskData(leash, positionInParent));
+
         if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
         mSyncQueue.runInSync(t -> {
             // Reset several properties back to fullscreen (PiP, for example, leaves all these
@@ -87,7 +79,6 @@
             t.show(leash);
         });
 
-        mAnimatableTasksListener.onTaskAppeared(taskInfo);
         updateRecentsForVisibleFullscreenTask(taskInfo);
     }
 
@@ -95,7 +86,6 @@
     public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
         if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
 
-        mAnimatableTasksListener.onTaskInfoChanged(taskInfo);
         updateRecentsForVisibleFullscreenTask(taskInfo);
 
         final TaskData data = mDataByTaskId.get(taskInfo.taskId);
@@ -115,7 +105,6 @@
             return;
         }
 
-        mAnimatableTasksListener.onTaskVanished(taskInfo);
         mDataByTaskId.remove(taskInfo.taskId);
 
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d",
@@ -173,65 +162,4 @@
             this.positionInParent = positionInParent;
         }
     }
-
-    class AnimatableTasksListener {
-        private final SparseBooleanArray mTaskIds = new SparseBooleanArray();
-
-        public void onTaskAppeared(RunningTaskInfo taskInfo) {
-            final boolean isApplicable = isAnimatable(taskInfo);
-            if (isApplicable) {
-                mTaskIds.put(taskInfo.taskId, true);
-
-                if (mFullscreenUnfoldController != null) {
-                    SurfaceControl leash = mDataByTaskId.get(taskInfo.taskId).surface;
-                    mFullscreenUnfoldController.onTaskAppeared(taskInfo, leash);
-                }
-            }
-        }
-
-        public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
-            final boolean isCurrentlyApplicable = mTaskIds.get(taskInfo.taskId);
-            final boolean isApplicable = isAnimatable(taskInfo);
-
-            if (isCurrentlyApplicable) {
-                if (isApplicable) {
-                    // Still applicable, send update
-                    if (mFullscreenUnfoldController != null) {
-                        mFullscreenUnfoldController.onTaskInfoChanged(taskInfo);
-                    }
-                } else {
-                    // Became inapplicable
-                    if (mFullscreenUnfoldController != null) {
-                        mFullscreenUnfoldController.onTaskVanished(taskInfo);
-                    }
-                    mTaskIds.put(taskInfo.taskId, false);
-                }
-            } else {
-                if (isApplicable) {
-                    // Became applicable
-                    mTaskIds.put(taskInfo.taskId, true);
-
-                    if (mFullscreenUnfoldController != null) {
-                        SurfaceControl leash = mDataByTaskId.get(taskInfo.taskId).surface;
-                        mFullscreenUnfoldController.onTaskAppeared(taskInfo, leash);
-                    }
-                }
-            }
-        }
-
-        public void onTaskVanished(RunningTaskInfo taskInfo) {
-            final boolean isCurrentlyApplicable = mTaskIds.get(taskInfo.taskId);
-            if (isCurrentlyApplicable && mFullscreenUnfoldController != null) {
-                mFullscreenUnfoldController.onTaskVanished(taskInfo);
-            }
-            mTaskIds.put(taskInfo.taskId, false);
-        }
-
-        private boolean isAnimatable(TaskInfo taskInfo) {
-            // Filter all visible tasks that are not launcher tasks
-            // We do not animate launcher as it handles the animation by itself
-            return taskInfo != null && taskInfo.isVisible && taskInfo.getConfiguration()
-                    .windowConfiguration.getActivityType() != ACTIVITY_TYPE_HOME;
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
index b4c87b6..2c8ba09 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
@@ -51,6 +51,7 @@
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.startingsurface.StartingWindowController;
+import com.android.wm.shell.unfold.UnfoldAnimationController;
 
 import java.io.PrintWriter;
 import java.util.List;
@@ -146,9 +147,11 @@
             SyncTransactionQueue syncTransactionQueue,
             DisplayController displayController,
             DisplayInsetsController displayInsetsController,
+            Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<RecentTasksController> recentTasks,
             KidsModeSettingsObserver kidsModeSettingsObserver) {
-        super(taskOrganizerController, mainExecutor, context, /* compatUI= */ null, recentTasks);
+        super(taskOrganizerController, mainExecutor, context, /* compatUI= */ null,
+                unfoldAnimationController, recentTasks);
         mContext = context;
         mMainHandler = mainHandler;
         mSyncQueue = syncTransactionQueue;
@@ -164,8 +167,9 @@
             SyncTransactionQueue syncTransactionQueue,
             DisplayController displayController,
             DisplayInsetsController displayInsetsController,
+            Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<RecentTasksController> recentTasks) {
-        super(mainExecutor, context, /* compatUI= */ null, recentTasks);
+        super(mainExecutor, context, /* compatUI= */ null, unfoldAnimationController, recentTasks);
         mContext = context;
         mMainHandler = mainHandler;
         mSyncQueue = syncTransactionQueue;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java
deleted file mode 100644
index aced072..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.legacysplitscreen;
-
-import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
-import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.annotation.Nullable;
-import android.graphics.Rect;
-import android.util.Slog;
-import android.view.Choreographer;
-import android.view.SurfaceControl;
-import android.window.TaskOrganizer;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
-
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.TransactionPool;
-
-class DividerImeController implements DisplayImeController.ImePositionProcessor {
-    private static final String TAG = "DividerImeController";
-    private static final boolean DEBUG = LegacySplitScreenController.DEBUG;
-
-    private static final float ADJUSTED_NONFOCUS_DIM = 0.3f;
-
-    private final LegacySplitScreenTaskListener mSplits;
-    private final TransactionPool mTransactionPool;
-    private final ShellExecutor mMainExecutor;
-    private final TaskOrganizer mTaskOrganizer;
-
-    /**
-     * These are the y positions of the top of the IME surface when it is hidden and when it is
-     * shown respectively. These are NOT necessarily the top of the visible IME itself.
-     */
-    private int mHiddenTop = 0;
-    private int mShownTop = 0;
-
-    // The following are target states (what we are curretly animating towards).
-    /**
-     * {@code true} if, at the end of the animation, the split task positions should be
-     * adjusted by height of the IME. This happens when the secondary split is the IME target.
-     */
-    private boolean mTargetAdjusted = false;
-    /**
-     * {@code true} if, at the end of the animation, the IME should be shown/visible
-     * regardless of what has focus.
-     */
-    private boolean mTargetShown = false;
-    private float mTargetPrimaryDim = 0.f;
-    private float mTargetSecondaryDim = 0.f;
-
-    // The following are the current (most recent) states set during animation
-    /** {@code true} if the secondary split has IME focus. */
-    private boolean mSecondaryHasFocus = false;
-    /** The dimming currently applied to the primary/secondary splits. */
-    private float mLastPrimaryDim = 0.f;
-    private float mLastSecondaryDim = 0.f;
-    /** The most recent y position of the top of the IME surface */
-    private int mLastAdjustTop = -1;
-
-    // The following are states reached last time an animation fully completed.
-    /** {@code true} if the IME was shown/visible by the last-completed animation. */
-    private boolean mImeWasShown = false;
-    /** {@code true} if the split positions were adjusted by the last-completed animation. */
-    private boolean mAdjusted = false;
-
-    /**
-     * When some aspect of split-screen needs to animate independent from the IME,
-     * this will be non-null and control split animation.
-     */
-    @Nullable
-    private ValueAnimator mAnimation = null;
-
-    private boolean mPaused = true;
-    private boolean mPausedTargetAdjusted = false;
-
-    DividerImeController(LegacySplitScreenTaskListener splits, TransactionPool pool,
-            ShellExecutor mainExecutor, TaskOrganizer taskOrganizer) {
-        mSplits = splits;
-        mTransactionPool = pool;
-        mMainExecutor = mainExecutor;
-        mTaskOrganizer = taskOrganizer;
-    }
-
-    private DividerView getView() {
-        return mSplits.mSplitScreenController.getDividerView();
-    }
-
-    private LegacySplitDisplayLayout getLayout() {
-        return mSplits.mSplitScreenController.getSplitLayout();
-    }
-
-    private boolean isDividerHidden() {
-        final DividerView view = mSplits.mSplitScreenController.getDividerView();
-        return view == null || view.isHidden();
-    }
-
-    private boolean getSecondaryHasFocus(int displayId) {
-        WindowContainerToken imeSplit = mTaskOrganizer.getImeTarget(displayId);
-        return imeSplit != null
-                && (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder());
-    }
-
-    void reset() {
-        mPaused = true;
-        mPausedTargetAdjusted = false;
-        mAnimation = null;
-        mAdjusted = mTargetAdjusted = false;
-        mImeWasShown = mTargetShown = false;
-        mTargetPrimaryDim = mTargetSecondaryDim = mLastPrimaryDim = mLastSecondaryDim = 0.f;
-        mSecondaryHasFocus = false;
-        mLastAdjustTop = -1;
-    }
-
-    private void updateDimTargets() {
-        final boolean splitIsVisible = !getView().isHidden();
-        mTargetPrimaryDim = (mSecondaryHasFocus && mTargetShown && splitIsVisible)
-                ? ADJUSTED_NONFOCUS_DIM : 0.f;
-        mTargetSecondaryDim = (!mSecondaryHasFocus && mTargetShown && splitIsVisible)
-                ? ADJUSTED_NONFOCUS_DIM : 0.f;
-    }
-
-
-    @Override
-    public void onImeControlTargetChanged(int displayId, boolean controlling) {
-        // Restore the split layout when wm-shell is not controlling IME insets anymore.
-        if (!controlling && mTargetShown) {
-            mPaused = false;
-            mTargetAdjusted = mTargetShown = false;
-            mTargetPrimaryDim = mTargetSecondaryDim = 0.f;
-            updateImeAdjustState(true /* force */);
-            startAsyncAnimation();
-        }
-    }
-
-    @Override
-    @ImeAnimationFlags
-    public int onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
-            boolean imeShouldShow, boolean imeIsFloating, SurfaceControl.Transaction t) {
-        if (isDividerHidden()) {
-            return 0;
-        }
-        mHiddenTop = hiddenTop;
-        mShownTop = shownTop;
-        mTargetShown = imeShouldShow;
-        mSecondaryHasFocus = getSecondaryHasFocus(displayId);
-        final boolean targetAdjusted = imeShouldShow && mSecondaryHasFocus
-                && !imeIsFloating && !getLayout().mDisplayLayout.isLandscape()
-                && !mSplits.mSplitScreenController.isMinimized();
-        if (mLastAdjustTop < 0) {
-            mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop;
-        } else if (mLastAdjustTop != (imeShouldShow ? mShownTop : mHiddenTop)) {
-            if (mTargetAdjusted != targetAdjusted && targetAdjusted == mAdjusted) {
-                // Check for an "interruption" of an existing animation. In this case, we
-                // need to fake-flip the last-known state direction so that the animation
-                // completes in the other direction.
-                mAdjusted = mTargetAdjusted;
-            } else if (targetAdjusted && mTargetAdjusted && mAdjusted) {
-                // Already fully adjusted for IME, but IME height has changed; so, force-start
-                // an async animation to the new IME height.
-                mAdjusted = false;
-            }
-        }
-        if (mPaused) {
-            mPausedTargetAdjusted = targetAdjusted;
-            if (DEBUG) Slog.d(TAG, " ime starting but paused " + dumpState());
-            return (targetAdjusted || mAdjusted) ? IME_ANIMATION_NO_ALPHA : 0;
-        }
-        mTargetAdjusted = targetAdjusted;
-        updateDimTargets();
-        if (DEBUG) Slog.d(TAG, " ime starting.  " + dumpState());
-        if (mAnimation != null || (mImeWasShown && imeShouldShow
-                && mTargetAdjusted != mAdjusted)) {
-            // We need to animate adjustment independently of the IME position, so
-            // start our own animation to drive adjustment. This happens when a
-            // different split's editor has gained focus while the IME is still visible.
-            startAsyncAnimation();
-        }
-        updateImeAdjustState();
-
-        return (mTargetAdjusted || mAdjusted) ? IME_ANIMATION_NO_ALPHA : 0;
-    }
-
-    private void updateImeAdjustState() {
-        updateImeAdjustState(false /* force */);
-    }
-
-    private void updateImeAdjustState(boolean force) {
-        if (mAdjusted != mTargetAdjusted || force) {
-            // Reposition the server's secondary split position so that it evaluates
-            // insets properly.
-            WindowContainerTransaction wct = new WindowContainerTransaction();
-            final LegacySplitDisplayLayout splitLayout = getLayout();
-            if (mTargetAdjusted) {
-                splitLayout.updateAdjustedBounds(mShownTop, mHiddenTop, mShownTop);
-                wct.setBounds(mSplits.mSecondary.token, splitLayout.mAdjustedSecondary);
-                // "Freeze" the configuration size so that the app doesn't get a config
-                // or relaunch. This is required because normally nav-bar contributes
-                // to configuration bounds (via nondecorframe).
-                Rect adjustAppBounds = new Rect(mSplits.mSecondary.configuration
-                        .windowConfiguration.getAppBounds());
-                adjustAppBounds.offset(0, splitLayout.mAdjustedSecondary.top
-                        - splitLayout.mSecondary.top);
-                wct.setAppBounds(mSplits.mSecondary.token, adjustAppBounds);
-                wct.setScreenSizeDp(mSplits.mSecondary.token,
-                        mSplits.mSecondary.configuration.screenWidthDp,
-                        mSplits.mSecondary.configuration.screenHeightDp);
-
-                wct.setBounds(mSplits.mPrimary.token, splitLayout.mAdjustedPrimary);
-                adjustAppBounds = new Rect(mSplits.mPrimary.configuration
-                        .windowConfiguration.getAppBounds());
-                adjustAppBounds.offset(0, splitLayout.mAdjustedPrimary.top
-                        - splitLayout.mPrimary.top);
-                wct.setAppBounds(mSplits.mPrimary.token, adjustAppBounds);
-                wct.setScreenSizeDp(mSplits.mPrimary.token,
-                        mSplits.mPrimary.configuration.screenWidthDp,
-                        mSplits.mPrimary.configuration.screenHeightDp);
-            } else {
-                wct.setBounds(mSplits.mSecondary.token, splitLayout.mSecondary);
-                wct.setAppBounds(mSplits.mSecondary.token, null);
-                wct.setScreenSizeDp(mSplits.mSecondary.token,
-                        SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
-                wct.setBounds(mSplits.mPrimary.token, splitLayout.mPrimary);
-                wct.setAppBounds(mSplits.mPrimary.token, null);
-                wct.setScreenSizeDp(mSplits.mPrimary.token,
-                        SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
-            }
-
-            if (!mSplits.mSplitScreenController.getWmProxy().queueSyncTransactionIfWaiting(wct)) {
-                mTaskOrganizer.applyTransaction(wct);
-            }
-        }
-
-        // Update all the adjusted-for-ime states
-        if (!mPaused) {
-            final DividerView view = getView();
-            if (view != null) {
-                view.setAdjustedForIme(mTargetShown, mTargetShown
-                        ? DisplayImeController.ANIMATION_DURATION_SHOW_MS
-                        : DisplayImeController.ANIMATION_DURATION_HIDE_MS);
-            }
-        }
-        mSplits.mSplitScreenController.setAdjustedForIme(mTargetShown && !mPaused);
-    }
-
-    @Override
-    public void onImePositionChanged(int displayId, int imeTop,
-            SurfaceControl.Transaction t) {
-        if (mAnimation != null || isDividerHidden() || mPaused) {
-            // Not synchronized with IME anymore, so return.
-            return;
-        }
-        final float fraction = ((float) imeTop - mHiddenTop) / (mShownTop - mHiddenTop);
-        final float progress = mTargetShown ? fraction : 1.f - fraction;
-        onProgress(progress, t);
-    }
-
-    @Override
-    public void onImeEndPositioning(int displayId, boolean cancelled,
-            SurfaceControl.Transaction t) {
-        if (mAnimation != null || isDividerHidden() || mPaused) {
-            // Not synchronized with IME anymore, so return.
-            return;
-        }
-        onEnd(cancelled, t);
-    }
-
-    private void onProgress(float progress, SurfaceControl.Transaction t) {
-        final DividerView view = getView();
-        if (mTargetAdjusted != mAdjusted && !mPaused) {
-            final LegacySplitDisplayLayout splitLayout = getLayout();
-            final float fraction = mTargetAdjusted ? progress : 1.f - progress;
-            mLastAdjustTop = (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop);
-            splitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop);
-            view.resizeSplitSurfaces(t, splitLayout.mAdjustedPrimary,
-                    splitLayout.mAdjustedSecondary);
-        }
-        final float invProg = 1.f - progress;
-        view.setResizeDimLayer(t, true /* primary */,
-                mLastPrimaryDim * invProg + progress * mTargetPrimaryDim);
-        view.setResizeDimLayer(t, false /* primary */,
-                mLastSecondaryDim * invProg + progress * mTargetSecondaryDim);
-    }
-
-    void setDimsHidden(SurfaceControl.Transaction t, boolean hidden) {
-        final DividerView view = getView();
-        if (hidden) {
-            view.setResizeDimLayer(t, true /* primary */, 0.f /* alpha */);
-            view.setResizeDimLayer(t, false /* primary */, 0.f /* alpha */);
-        } else {
-            updateDimTargets();
-            view.setResizeDimLayer(t, true /* primary */, mTargetPrimaryDim);
-            view.setResizeDimLayer(t, false /* primary */, mTargetSecondaryDim);
-        }
-    }
-
-    private void onEnd(boolean cancelled, SurfaceControl.Transaction t) {
-        if (!cancelled) {
-            onProgress(1.f, t);
-            mAdjusted = mTargetAdjusted;
-            mImeWasShown = mTargetShown;
-            mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop;
-            mLastPrimaryDim = mTargetPrimaryDim;
-            mLastSecondaryDim = mTargetSecondaryDim;
-        }
-    }
-
-    private void startAsyncAnimation() {
-        if (mAnimation != null) {
-            mAnimation.cancel();
-        }
-        mAnimation = ValueAnimator.ofFloat(0.f, 1.f);
-        mAnimation.setDuration(DisplayImeController.ANIMATION_DURATION_SHOW_MS);
-        if (mTargetAdjusted != mAdjusted) {
-            final float fraction =
-                    ((float) mLastAdjustTop - mHiddenTop) / (mShownTop - mHiddenTop);
-            final float progress = mTargetAdjusted ? fraction : 1.f - fraction;
-            mAnimation.setCurrentFraction(progress);
-        }
-
-        mAnimation.addUpdateListener(animation -> {
-            SurfaceControl.Transaction t = mTransactionPool.acquire();
-            float value = (float) animation.getAnimatedValue();
-            onProgress(value, t);
-            t.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
-            t.apply();
-            mTransactionPool.release(t);
-        });
-        mAnimation.setInterpolator(DisplayImeController.INTERPOLATOR);
-        mAnimation.addListener(new AnimatorListenerAdapter() {
-            private boolean mCancel = false;
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                mCancel = true;
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                SurfaceControl.Transaction t = mTransactionPool.acquire();
-                onEnd(mCancel, t);
-                t.apply();
-                mTransactionPool.release(t);
-                mAnimation = null;
-            }
-        });
-        mAnimation.start();
-    }
-
-    private String dumpState() {
-        return "top:" + mHiddenTop + "->" + mShownTop
-                + " adj:" + mAdjusted + "->" + mTargetAdjusted + "(" + mLastAdjustTop + ")"
-                + " shw:" + mImeWasShown + "->" + mTargetShown
-                + " dims:" + mLastPrimaryDim + "," + mLastSecondaryDim
-                + "->" + mTargetPrimaryDim + "," + mTargetSecondaryDim
-                + " shf:" + mSecondaryHasFocus + " desync:" + (mAnimation != null)
-                + " paus:" + mPaused + "[" + mPausedTargetAdjusted + "]";
-    }
-
-    /** Completely aborts/resets adjustment state */
-    public void pause(int displayId) {
-        if (DEBUG) Slog.d(TAG, "ime pause posting " + dumpState());
-        mMainExecutor.execute(() -> {
-            if (DEBUG) Slog.d(TAG, "ime pause run posted " + dumpState());
-            if (mPaused) {
-                return;
-            }
-            mPaused = true;
-            mPausedTargetAdjusted = mTargetAdjusted;
-            mTargetAdjusted = false;
-            mTargetPrimaryDim = mTargetSecondaryDim = 0.f;
-            updateImeAdjustState();
-            startAsyncAnimation();
-            if (mAnimation != null) {
-                mAnimation.end();
-            }
-        });
-    }
-
-    public void resume(int displayId) {
-        if (DEBUG) Slog.d(TAG, "ime resume posting " + dumpState());
-        mMainExecutor.execute(() -> {
-            if (DEBUG) Slog.d(TAG, "ime resume run posted " + dumpState());
-            if (!mPaused) {
-                return;
-            }
-            mPaused = false;
-            mTargetAdjusted = mPausedTargetAdjusted;
-            updateDimTargets();
-            final DividerView view = getView();
-            if ((mTargetAdjusted != mAdjusted) && !mSplits.mSplitScreenController.isMinimized()
-                    && view != null) {
-                // End unminimize animations since they conflict with adjustment animations.
-                view.finishAnimations();
-            }
-            updateImeAdjustState();
-            startAsyncAnimation();
-        });
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
deleted file mode 100644
index 73be283..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
+++ /dev/null
@@ -1,1314 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.wm.shell.legacysplitscreen;
-
-import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
-import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
-import static android.view.WindowManager.DOCKED_RIGHT;
-
-import static com.android.wm.shell.animation.Interpolators.DIM_INTERPOLATOR;
-import static com.android.wm.shell.animation.Interpolators.SLOWDOWN_INTERPOLATOR;
-import static com.android.wm.shell.common.split.DividerView.TOUCH_ANIMATION_DURATION;
-import static com.android.wm.shell.common.split.DividerView.TOUCH_RELEASE_ANIMATION_DURATION;
-
-import android.animation.AnimationHandler;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.graphics.Region.Op;
-import android.hardware.display.DisplayManager;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.Choreographer;
-import android.view.Display;
-import android.view.MotionEvent;
-import android.view.PointerIcon;
-import android.view.SurfaceControl;
-import android.view.SurfaceControl.Transaction;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.View.OnTouchListener;
-import android.view.ViewConfiguration;
-import android.view.ViewTreeObserver.InternalInsetsInfo;
-import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
-import android.widget.FrameLayout;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
-import com.android.internal.policy.DockedDividerUtils;
-import com.android.wm.shell.R;
-import com.android.wm.shell.animation.FlingAnimationUtils;
-import com.android.wm.shell.animation.Interpolators;
-import com.android.wm.shell.common.split.DividerHandleView;
-
-import java.util.function.Consumer;
-
-/**
- * Docked stack divider.
- */
-public class DividerView extends FrameLayout implements OnTouchListener,
-        OnComputeInternalInsetsListener {
-    private static final String TAG = "DividerView";
-    private static final boolean DEBUG = LegacySplitScreenController.DEBUG;
-
-    interface DividerCallbacks {
-        void onDraggingStart();
-        void onDraggingEnd();
-    }
-
-    public static final int INVALID_RECENTS_GROW_TARGET = -1;
-
-    private static final int LOG_VALUE_RESIZE_50_50 = 0;
-    private static final int LOG_VALUE_RESIZE_DOCKED_SMALLER = 1;
-    private static final int LOG_VALUE_RESIZE_DOCKED_LARGER = 2;
-
-    private static final int LOG_VALUE_UNDOCK_MAX_DOCKED = 0;
-    private static final int LOG_VALUE_UNDOCK_MAX_OTHER = 1;
-
-    private static final int TASK_POSITION_SAME = Integer.MAX_VALUE;
-
-    /**
-     * How much the background gets scaled when we are in the minimized dock state.
-     */
-    private static final float MINIMIZE_DOCK_SCALE = 0f;
-    private static final float ADJUSTED_FOR_IME_SCALE = 0.5f;
-
-    private static final Interpolator IME_ADJUST_INTERPOLATOR =
-            new PathInterpolator(0.2f, 0f, 0.1f, 1f);
-
-    private DividerHandleView mHandle;
-    private View mBackground;
-    private MinimizedDockShadow mMinimizedShadow;
-    private int mStartX;
-    private int mStartY;
-    private int mStartPosition;
-    private int mDockSide;
-    private boolean mMoving;
-    private int mTouchSlop;
-    private boolean mBackgroundLifted;
-    private boolean mIsInMinimizeInteraction;
-    SnapTarget mSnapTargetBeforeMinimized;
-
-    private int mDividerInsets;
-    private final Display mDefaultDisplay;
-
-    private int mDividerSize;
-    private int mTouchElevation;
-    private int mLongPressEntraceAnimDuration;
-
-    private final Rect mDockedRect = new Rect();
-    private final Rect mDockedTaskRect = new Rect();
-    private final Rect mOtherTaskRect = new Rect();
-    private final Rect mOtherRect = new Rect();
-    private final Rect mDockedInsetRect = new Rect();
-    private final Rect mOtherInsetRect = new Rect();
-    private final Rect mLastResizeRect = new Rect();
-    private final Rect mTmpRect = new Rect();
-    private LegacySplitScreenController mSplitScreenController;
-    private WindowManagerProxy mWindowManagerProxy;
-    private DividerWindowManager mWindowManager;
-    private VelocityTracker mVelocityTracker;
-    private FlingAnimationUtils mFlingAnimationUtils;
-    private LegacySplitDisplayLayout mSplitLayout;
-    private DividerImeController mImeController;
-    private DividerCallbacks mCallback;
-
-    private AnimationHandler mSfVsyncAnimationHandler;
-    private ValueAnimator mCurrentAnimator;
-    private boolean mEntranceAnimationRunning;
-    private boolean mExitAnimationRunning;
-    private int mExitStartPosition;
-    private boolean mDockedStackMinimized;
-    private boolean mHomeStackResizable;
-    private boolean mAdjustedForIme;
-    private DividerState mState;
-
-    private LegacySplitScreenTaskListener mTiles;
-    boolean mFirstLayout = true;
-    int mDividerPositionX;
-    int mDividerPositionY;
-
-    private final Matrix mTmpMatrix = new Matrix();
-    private final float[] mTmpValues = new float[9];
-
-    // The view is removed or in the process of been removed from the system.
-    private boolean mRemoved;
-
-    // Whether the surface for this view has been hidden regardless of actual visibility. This is
-    // used interact with keyguard.
-    private boolean mSurfaceHidden = false;
-
-    private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() {
-        @Override
-        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
-            super.onInitializeAccessibilityNodeInfo(host, info);
-            final DividerSnapAlgorithm snapAlgorithm = getSnapAlgorithm();
-            if (isHorizontalDivision()) {
-                info.addAction(new AccessibilityAction(R.id.action_move_tl_full,
-                        mContext.getString(R.string.accessibility_action_divider_top_full)));
-                if (snapAlgorithm.isFirstSplitTargetAvailable()) {
-                    info.addAction(new AccessibilityAction(R.id.action_move_tl_70,
-                            mContext.getString(R.string.accessibility_action_divider_top_70)));
-                }
-                if (snapAlgorithm.showMiddleSplitTargetForAccessibility()) {
-                    // Only show the middle target if there are more than 1 split target
-                    info.addAction(new AccessibilityAction(R.id.action_move_tl_50,
-                            mContext.getString(R.string.accessibility_action_divider_top_50)));
-                }
-                if (snapAlgorithm.isLastSplitTargetAvailable()) {
-                    info.addAction(new AccessibilityAction(R.id.action_move_tl_30,
-                            mContext.getString(R.string.accessibility_action_divider_top_30)));
-                }
-                info.addAction(new AccessibilityAction(R.id.action_move_rb_full,
-                        mContext.getString(R.string.accessibility_action_divider_bottom_full)));
-            } else {
-                info.addAction(new AccessibilityAction(R.id.action_move_tl_full,
-                        mContext.getString(R.string.accessibility_action_divider_left_full)));
-                if (snapAlgorithm.isFirstSplitTargetAvailable()) {
-                    info.addAction(new AccessibilityAction(R.id.action_move_tl_70,
-                            mContext.getString(R.string.accessibility_action_divider_left_70)));
-                }
-                if (snapAlgorithm.showMiddleSplitTargetForAccessibility()) {
-                    // Only show the middle target if there are more than 1 split target
-                    info.addAction(new AccessibilityAction(R.id.action_move_tl_50,
-                            mContext.getString(R.string.accessibility_action_divider_left_50)));
-                }
-                if (snapAlgorithm.isLastSplitTargetAvailable()) {
-                    info.addAction(new AccessibilityAction(R.id.action_move_tl_30,
-                            mContext.getString(R.string.accessibility_action_divider_left_30)));
-                }
-                info.addAction(new AccessibilityAction(R.id.action_move_rb_full,
-                        mContext.getString(R.string.accessibility_action_divider_right_full)));
-            }
-        }
-
-        @Override
-        public boolean performAccessibilityAction(View host, int action, Bundle args) {
-            int currentPosition = getCurrentPosition();
-            SnapTarget nextTarget = null;
-            DividerSnapAlgorithm snapAlgorithm = mSplitLayout.getSnapAlgorithm();
-            if (action == R.id.action_move_tl_full) {
-                nextTarget = snapAlgorithm.getDismissEndTarget();
-            } else if (action == R.id.action_move_tl_70) {
-                nextTarget = snapAlgorithm.getLastSplitTarget();
-            } else if (action == R.id.action_move_tl_50) {
-                nextTarget = snapAlgorithm.getMiddleTarget();
-            } else if (action == R.id.action_move_tl_30) {
-                nextTarget = snapAlgorithm.getFirstSplitTarget();
-            } else if (action == R.id.action_move_rb_full) {
-                nextTarget = snapAlgorithm.getDismissStartTarget();
-            }
-            if (nextTarget != null) {
-                startDragging(true /* animate */, false /* touching */);
-                stopDragging(currentPosition, nextTarget, 250, Interpolators.FAST_OUT_SLOW_IN);
-                return true;
-            }
-            return super.performAccessibilityAction(host, action, args);
-        }
-    };
-
-    private final Runnable mResetBackgroundRunnable = new Runnable() {
-        @Override
-        public void run() {
-            resetBackground();
-        }
-    };
-
-    public DividerView(Context context) {
-        this(context, null);
-    }
-
-    public DividerView(Context context, @Nullable AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public DividerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public DividerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-        final DisplayManager displayManager =
-                (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
-        mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
-    }
-
-    public void setAnimationHandler(AnimationHandler sfVsyncAnimationHandler) {
-        mSfVsyncAnimationHandler = sfVsyncAnimationHandler;
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mHandle = findViewById(R.id.docked_divider_handle);
-        mBackground = findViewById(R.id.docked_divider_background);
-        mMinimizedShadow = findViewById(R.id.minimized_dock_shadow);
-        mHandle.setOnTouchListener(this);
-        final int dividerWindowWidth = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.docked_stack_divider_thickness);
-        mDividerInsets = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.docked_stack_divider_insets);
-        mDividerSize = dividerWindowWidth - 2 * mDividerInsets;
-        mTouchElevation = getResources().getDimensionPixelSize(
-                R.dimen.docked_stack_divider_lift_elevation);
-        mLongPressEntraceAnimDuration = getResources().getInteger(
-                R.integer.long_press_dock_anim_duration);
-        mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
-        mFlingAnimationUtils = new FlingAnimationUtils(getResources().getDisplayMetrics(), 0.3f);
-        boolean landscape = getResources().getConfiguration().orientation
-                == Configuration.ORIENTATION_LANDSCAPE;
-        mHandle.setPointerIcon(PointerIcon.getSystemIcon(getContext(),
-                landscape ? TYPE_HORIZONTAL_DOUBLE_ARROW : TYPE_VERTICAL_DOUBLE_ARROW));
-        getViewTreeObserver().addOnComputeInternalInsetsListener(this);
-        mHandle.setAccessibilityDelegate(mHandleDelegate);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        // Save the current target if not minimized once attached to window
-        if (mDockSide != WindowManager.DOCKED_INVALID && !mIsInMinimizeInteraction) {
-            saveSnapTargetBeforeMinimized(mSnapTargetBeforeMinimized);
-        }
-        mFirstLayout = true;
-    }
-
-    void onDividerRemoved() {
-        mRemoved = true;
-        mCallback = null;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        if (mFirstLayout) {
-            // Wait for first layout so that the ViewRootImpl surface has been created.
-            initializeSurfaceState();
-            mFirstLayout = false;
-        }
-        int minimizeLeft = 0;
-        int minimizeTop = 0;
-        if (mDockSide == WindowManager.DOCKED_TOP) {
-            minimizeTop = mBackground.getTop();
-        } else if (mDockSide == WindowManager.DOCKED_LEFT) {
-            minimizeLeft = mBackground.getLeft();
-        } else if (mDockSide == WindowManager.DOCKED_RIGHT) {
-            minimizeLeft = mBackground.getRight() - mMinimizedShadow.getWidth();
-        }
-        mMinimizedShadow.layout(minimizeLeft, minimizeTop,
-                minimizeLeft + mMinimizedShadow.getMeasuredWidth(),
-                minimizeTop + mMinimizedShadow.getMeasuredHeight());
-        if (changed) {
-            notifySplitScreenBoundsChanged();
-        }
-    }
-
-    void injectDependencies(LegacySplitScreenController splitScreenController,
-            DividerWindowManager windowManager, DividerState dividerState,
-            DividerCallbacks callback, LegacySplitScreenTaskListener tiles,
-            LegacySplitDisplayLayout sdl, DividerImeController imeController,
-            WindowManagerProxy wmProxy) {
-        mSplitScreenController = splitScreenController;
-        mWindowManager = windowManager;
-        mState = dividerState;
-        mCallback = callback;
-        mTiles = tiles;
-        mSplitLayout = sdl;
-        mImeController = imeController;
-        mWindowManagerProxy = wmProxy;
-
-        if (mState.mRatioPositionBeforeMinimized == 0) {
-            // Set the middle target as the initial state
-            mSnapTargetBeforeMinimized = mSplitLayout.getSnapAlgorithm().getMiddleTarget();
-        } else {
-            repositionSnapTargetBeforeMinimized();
-        }
-    }
-
-    /** Gets non-minimized secondary bounds of split screen. */
-    public Rect getNonMinimizedSplitScreenSecondaryBounds() {
-        mOtherTaskRect.set(mSplitLayout.mSecondary);
-        return mOtherTaskRect;
-    }
-
-    private boolean inSplitMode() {
-        return getVisibility() == VISIBLE;
-    }
-
-    /** Unlike setVisible, this directly hides the surface without changing view visibility. */
-    void setHidden(boolean hidden) {
-        if (mSurfaceHidden == hidden) {
-            return;
-        }
-        mSurfaceHidden = hidden;
-        post(() -> {
-            final SurfaceControl sc = getWindowSurfaceControl();
-            if (sc == null) {
-                return;
-            }
-            Transaction t = mTiles.getTransaction();
-            if (hidden) {
-                t.hide(sc);
-            } else {
-                t.show(sc);
-            }
-            mImeController.setDimsHidden(t, hidden);
-            t.apply();
-            mTiles.releaseTransaction(t);
-        });
-    }
-
-    boolean isHidden() {
-        return getVisibility() != View.VISIBLE || mSurfaceHidden;
-    }
-
-    /** Starts dragging the divider bar. */
-    public boolean startDragging(boolean animate, boolean touching) {
-        cancelFlingAnimation();
-        if (touching) {
-            mHandle.setTouching(true, animate);
-        }
-        mDockSide = mSplitLayout.getPrimarySplitSide();
-
-        mWindowManagerProxy.setResizing(true);
-        if (touching) {
-            mWindowManager.setSlippery(false);
-            liftBackground();
-        }
-        if (mCallback != null) {
-            mCallback.onDraggingStart();
-        }
-        return inSplitMode();
-    }
-
-    /** Stops dragging the divider bar. */
-    public void stopDragging(int position, float velocity, boolean avoidDismissStart,
-            boolean logMetrics) {
-        mHandle.setTouching(false, true /* animate */);
-        fling(position, velocity, avoidDismissStart, logMetrics);
-        mWindowManager.setSlippery(true);
-        releaseBackground();
-    }
-
-    private void stopDragging(int position, SnapTarget target, long duration,
-            Interpolator interpolator) {
-        stopDragging(position, target, duration, 0 /* startDelay*/, 0 /* endDelay */, interpolator);
-    }
-
-    private void stopDragging(int position, SnapTarget target, long duration,
-            Interpolator interpolator, long endDelay) {
-        stopDragging(position, target, duration, 0 /* startDelay*/, endDelay, interpolator);
-    }
-
-    private void stopDragging(int position, SnapTarget target, long duration, long startDelay,
-            long endDelay, Interpolator interpolator) {
-        mHandle.setTouching(false, true /* animate */);
-        flingTo(position, target, duration, startDelay, endDelay, interpolator);
-        mWindowManager.setSlippery(true);
-        releaseBackground();
-    }
-
-    private void stopDragging() {
-        mHandle.setTouching(false, true /* animate */);
-        mWindowManager.setSlippery(true);
-        mWindowManagerProxy.setResizing(false);
-        releaseBackground();
-    }
-
-    private void updateDockSide() {
-        mDockSide = mSplitLayout.getPrimarySplitSide();
-        mMinimizedShadow.setDockSide(mDockSide);
-    }
-
-    public DividerSnapAlgorithm getSnapAlgorithm() {
-        return mDockedStackMinimized ? mSplitLayout.getMinimizedSnapAlgorithm(mHomeStackResizable)
-                        : mSplitLayout.getSnapAlgorithm();
-    }
-
-    public int getCurrentPosition() {
-        return isHorizontalDivision() ? mDividerPositionY : mDividerPositionX;
-    }
-
-    public boolean isMinimized() {
-        return mDockedStackMinimized;
-    }
-
-    @Override
-    public boolean onTouch(View v, MotionEvent event) {
-        convertToScreenCoordinates(event);
-        final int action = event.getAction() & MotionEvent.ACTION_MASK;
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                mVelocityTracker = VelocityTracker.obtain();
-                mVelocityTracker.addMovement(event);
-                mStartX = (int) event.getX();
-                mStartY = (int) event.getY();
-                boolean result = startDragging(true /* animate */, true /* touching */);
-                if (!result) {
-
-                    // Weren't able to start dragging successfully, so cancel it again.
-                    stopDragging();
-                }
-                mStartPosition = getCurrentPosition();
-                mMoving = false;
-                return result;
-            case MotionEvent.ACTION_MOVE:
-                mVelocityTracker.addMovement(event);
-                int x = (int) event.getX();
-                int y = (int) event.getY();
-                boolean exceededTouchSlop =
-                        isHorizontalDivision() && Math.abs(y - mStartY) > mTouchSlop
-                                || (!isHorizontalDivision() && Math.abs(x - mStartX) > mTouchSlop);
-                if (!mMoving && exceededTouchSlop) {
-                    mStartX = x;
-                    mStartY = y;
-                    mMoving = true;
-                }
-                if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) {
-                    SnapTarget snapTarget = getSnapAlgorithm().calculateSnapTarget(
-                            mStartPosition, 0 /* velocity */, false /* hardDismiss */);
-                    resizeStackSurfaces(calculatePosition(x, y), mStartPosition, snapTarget,
-                            null /* transaction */);
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                if (!mMoving) {
-                    stopDragging();
-                    break;
-                }
-
-                x = (int) event.getRawX();
-                y = (int) event.getRawY();
-                mVelocityTracker.addMovement(event);
-                mVelocityTracker.computeCurrentVelocity(1000);
-                int position = calculatePosition(x, y);
-                stopDragging(position, isHorizontalDivision() ? mVelocityTracker.getYVelocity()
-                        : mVelocityTracker.getXVelocity(), false /* avoidDismissStart */,
-                        true /* log */);
-                mMoving = false;
-                break;
-        }
-        return true;
-    }
-
-    private void logResizeEvent(SnapTarget snapTarget) {
-        if (snapTarget == mSplitLayout.getSnapAlgorithm().getDismissStartTarget()) {
-            MetricsLogger.action(
-                    mContext, MetricsEvent.ACTION_WINDOW_UNDOCK_MAX, dockSideTopLeft(mDockSide)
-                            ? LOG_VALUE_UNDOCK_MAX_OTHER
-                            : LOG_VALUE_UNDOCK_MAX_DOCKED);
-        } else if (snapTarget == mSplitLayout.getSnapAlgorithm().getDismissEndTarget()) {
-            MetricsLogger.action(
-                    mContext, MetricsEvent.ACTION_WINDOW_UNDOCK_MAX, dockSideBottomRight(mDockSide)
-                            ? LOG_VALUE_UNDOCK_MAX_OTHER
-                            : LOG_VALUE_UNDOCK_MAX_DOCKED);
-        } else if (snapTarget == mSplitLayout.getSnapAlgorithm().getMiddleTarget()) {
-            MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_RESIZE,
-                    LOG_VALUE_RESIZE_50_50);
-        } else if (snapTarget == mSplitLayout.getSnapAlgorithm().getFirstSplitTarget()) {
-            MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_RESIZE,
-                    dockSideTopLeft(mDockSide)
-                            ? LOG_VALUE_RESIZE_DOCKED_SMALLER
-                            : LOG_VALUE_RESIZE_DOCKED_LARGER);
-        } else if (snapTarget == mSplitLayout.getSnapAlgorithm().getLastSplitTarget()) {
-            MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_RESIZE,
-                    dockSideTopLeft(mDockSide)
-                            ? LOG_VALUE_RESIZE_DOCKED_LARGER
-                            : LOG_VALUE_RESIZE_DOCKED_SMALLER);
-        }
-    }
-
-    private void convertToScreenCoordinates(MotionEvent event) {
-        event.setLocation(event.getRawX(), event.getRawY());
-    }
-
-    private void fling(int position, float velocity, boolean avoidDismissStart,
-            boolean logMetrics) {
-        DividerSnapAlgorithm currentSnapAlgorithm = getSnapAlgorithm();
-        SnapTarget snapTarget = currentSnapAlgorithm.calculateSnapTarget(position, velocity);
-        if (avoidDismissStart && snapTarget == currentSnapAlgorithm.getDismissStartTarget()) {
-            snapTarget = currentSnapAlgorithm.getFirstSplitTarget();
-        }
-        if (logMetrics) {
-            logResizeEvent(snapTarget);
-        }
-        ValueAnimator anim = getFlingAnimator(position, snapTarget, 0 /* endDelay */);
-        mFlingAnimationUtils.apply(anim, position, snapTarget.position, velocity);
-        anim.start();
-    }
-
-    private void flingTo(int position, SnapTarget target, long duration, long startDelay,
-            long endDelay, Interpolator interpolator) {
-        ValueAnimator anim = getFlingAnimator(position, target, endDelay);
-        anim.setDuration(duration);
-        anim.setStartDelay(startDelay);
-        anim.setInterpolator(interpolator);
-        anim.start();
-    }
-
-    private ValueAnimator getFlingAnimator(int position, final SnapTarget snapTarget,
-            final long endDelay) {
-        if (mCurrentAnimator != null) {
-            cancelFlingAnimation();
-            updateDockSide();
-        }
-        if (DEBUG) Slog.d(TAG, "Getting fling " + position + "->" + snapTarget.position);
-        final boolean taskPositionSameAtEnd = snapTarget.flag == SnapTarget.FLAG_NONE;
-        ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position);
-        anim.addUpdateListener(animation -> resizeStackSurfaces((int) animation.getAnimatedValue(),
-                taskPositionSameAtEnd && animation.getAnimatedFraction() == 1f
-                        ? TASK_POSITION_SAME
-                        : snapTarget.taskPosition,
-                snapTarget, null /* transaction */));
-        Consumer<Boolean> endAction = cancelled -> {
-            if (DEBUG) Slog.d(TAG, "End Fling " + cancelled + " min:" + mIsInMinimizeInteraction);
-            final boolean wasMinimizeInteraction = mIsInMinimizeInteraction;
-            // Reset minimized divider position after unminimized state animation finishes.
-            if (!cancelled && !mDockedStackMinimized && mIsInMinimizeInteraction) {
-                mIsInMinimizeInteraction = false;
-            }
-            boolean dismissed = commitSnapFlags(snapTarget);
-            mWindowManagerProxy.setResizing(false);
-            updateDockSide();
-            mCurrentAnimator = null;
-            mEntranceAnimationRunning = false;
-            mExitAnimationRunning = false;
-            if (!dismissed && !wasMinimizeInteraction) {
-                mWindowManagerProxy.applyResizeSplits(snapTarget.position, mSplitLayout);
-            }
-            if (mCallback != null) {
-                mCallback.onDraggingEnd();
-            }
-
-            // Record last snap target the divider moved to
-            if (!mIsInMinimizeInteraction) {
-                // The last snapTarget position can be negative when the last divider position was
-                // offscreen. In that case, save the middle (default) SnapTarget so calculating next
-                // position isn't negative.
-                final SnapTarget saveTarget;
-                if (snapTarget.position < 0) {
-                    saveTarget = mSplitLayout.getSnapAlgorithm().getMiddleTarget();
-                } else {
-                    saveTarget = snapTarget;
-                }
-                final DividerSnapAlgorithm snapAlgo = mSplitLayout.getSnapAlgorithm();
-                if (saveTarget.position != snapAlgo.getDismissEndTarget().position
-                        && saveTarget.position != snapAlgo.getDismissStartTarget().position) {
-                    saveSnapTargetBeforeMinimized(saveTarget);
-                }
-            }
-            notifySplitScreenBoundsChanged();
-        };
-        anim.addListener(new AnimatorListenerAdapter() {
-
-            private boolean mCancelled;
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                mCancelled = true;
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                long delay = 0;
-                if (endDelay != 0) {
-                    delay = endDelay;
-                } else if (mCancelled) {
-                    delay = 0;
-                }
-                if (delay == 0) {
-                    endAction.accept(mCancelled);
-                } else {
-                    final Boolean cancelled = mCancelled;
-                    if (DEBUG) Slog.d(TAG, "Posting endFling " + cancelled + " d:" + delay + "ms");
-                    getHandler().postDelayed(() -> endAction.accept(cancelled), delay);
-                }
-            }
-        });
-        mCurrentAnimator = anim;
-        mCurrentAnimator.setAnimationHandler(mSfVsyncAnimationHandler);
-        return anim;
-    }
-
-    private void notifySplitScreenBoundsChanged() {
-        if (mSplitLayout.mPrimary == null || mSplitLayout.mSecondary == null) {
-            return;
-        }
-        mOtherTaskRect.set(mSplitLayout.mSecondary);
-
-        mTmpRect.set(mHandle.getLeft(), mHandle.getTop(), mHandle.getRight(), mHandle.getBottom());
-        if (isHorizontalDivision()) {
-            mTmpRect.offsetTo(mHandle.getLeft(), mDividerPositionY);
-        } else {
-            mTmpRect.offsetTo(mDividerPositionX, mHandle.getTop());
-        }
-        mWindowManagerProxy.setTouchRegion(mTmpRect);
-
-        mTmpRect.set(mSplitLayout.mDisplayLayout.stableInsets());
-        switch (mSplitLayout.getPrimarySplitSide()) {
-            case WindowManager.DOCKED_LEFT:
-                mTmpRect.left = 0;
-                break;
-            case WindowManager.DOCKED_RIGHT:
-                mTmpRect.right = 0;
-                break;
-            case WindowManager.DOCKED_TOP:
-                mTmpRect.top = 0;
-                break;
-        }
-        mSplitScreenController.notifyBoundsChanged(mOtherTaskRect, mTmpRect);
-    }
-
-    private void cancelFlingAnimation() {
-        if (mCurrentAnimator != null) {
-            mCurrentAnimator.cancel();
-        }
-    }
-
-    private boolean commitSnapFlags(SnapTarget target) {
-        if (target.flag == SnapTarget.FLAG_NONE) {
-            return false;
-        }
-        final boolean dismissOrMaximize;
-        if (target.flag == SnapTarget.FLAG_DISMISS_START) {
-            dismissOrMaximize = mDockSide == WindowManager.DOCKED_LEFT
-                    || mDockSide == WindowManager.DOCKED_TOP;
-        } else {
-            dismissOrMaximize = mDockSide == WindowManager.DOCKED_RIGHT
-                    || mDockSide == WindowManager.DOCKED_BOTTOM;
-        }
-        mWindowManagerProxy.dismissOrMaximizeDocked(mTiles, mSplitLayout, dismissOrMaximize);
-        Transaction t = mTiles.getTransaction();
-        setResizeDimLayer(t, true /* primary */, 0f);
-        setResizeDimLayer(t, false /* primary */, 0f);
-        t.apply();
-        mTiles.releaseTransaction(t);
-        return true;
-    }
-
-    private void liftBackground() {
-        if (mBackgroundLifted) {
-            return;
-        }
-        if (isHorizontalDivision()) {
-            mBackground.animate().scaleY(1.4f);
-        } else {
-            mBackground.animate().scaleX(1.4f);
-        }
-        mBackground.animate()
-                .setInterpolator(Interpolators.TOUCH_RESPONSE)
-                .setDuration(TOUCH_ANIMATION_DURATION)
-                .translationZ(mTouchElevation)
-                .start();
-
-        // Lift handle as well so it doesn't get behind the background, even though it doesn't
-        // cast shadow.
-        mHandle.animate()
-                .setInterpolator(Interpolators.TOUCH_RESPONSE)
-                .setDuration(TOUCH_ANIMATION_DURATION)
-                .translationZ(mTouchElevation)
-                .start();
-        mBackgroundLifted = true;
-    }
-
-    private void releaseBackground() {
-        if (!mBackgroundLifted) {
-            return;
-        }
-        mBackground.animate()
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .setDuration(TOUCH_RELEASE_ANIMATION_DURATION)
-                .translationZ(0)
-                .scaleX(1f)
-                .scaleY(1f)
-                .start();
-        mHandle.animate()
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .setDuration(TOUCH_RELEASE_ANIMATION_DURATION)
-                .translationZ(0)
-                .start();
-        mBackgroundLifted = false;
-    }
-
-    private void initializeSurfaceState() {
-        int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
-        // Recalculate the split-layout's internal tile bounds
-        mSplitLayout.resizeSplits(midPos);
-        Transaction t = mTiles.getTransaction();
-        if (mDockedStackMinimized) {
-            int position = mSplitLayout.getMinimizedSnapAlgorithm(mHomeStackResizable)
-                    .getMiddleTarget().position;
-            calculateBoundsForPosition(position, mDockSide, mDockedRect);
-            calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
-                    mOtherRect);
-            mDividerPositionX = mDividerPositionY = position;
-            resizeSplitSurfaces(t, mDockedRect, mSplitLayout.mPrimary,
-                    mOtherRect, mSplitLayout.mSecondary);
-        } else {
-            resizeSplitSurfaces(t, mSplitLayout.mPrimary, null,
-                    mSplitLayout.mSecondary, null);
-        }
-        setResizeDimLayer(t, true /* primary */, 0.f /* alpha */);
-        setResizeDimLayer(t, false /* secondary */, 0.f /* alpha */);
-        t.apply();
-        mTiles.releaseTransaction(t);
-
-        // Get the actually-visible bar dimensions (relative to full window). This is a thin
-        // bar going through the center.
-        final Rect dividerBar = isHorizontalDivision()
-                ? new Rect(0, mDividerInsets, mSplitLayout.mDisplayLayout.width(),
-                mDividerInsets + mDividerSize)
-                : new Rect(mDividerInsets, 0, mDividerInsets + mDividerSize,
-                mSplitLayout.mDisplayLayout.height());
-        final Region touchRegion = new Region(dividerBar);
-        // Add in the "draggable" portion. While not visible, this is an expanded area that the
-        // user can interact with.
-        touchRegion.union(new Rect(mHandle.getLeft(), mHandle.getTop(),
-                mHandle.getRight(), mHandle.getBottom()));
-        mWindowManager.setTouchRegion(touchRegion);
-    }
-
-    void setMinimizedDockStack(boolean minimized, boolean isHomeStackResizable,
-            Transaction t) {
-        mHomeStackResizable = isHomeStackResizable;
-        updateDockSide();
-        if (!minimized) {
-            resetBackground();
-        }
-        mMinimizedShadow.setAlpha(minimized ? 1f : 0f);
-        if (mDockedStackMinimized != minimized) {
-            mDockedStackMinimized = minimized;
-            if (mSplitLayout.mDisplayLayout.rotation() != mDefaultDisplay.getRotation()) {
-                // Splitscreen to minimize is about to starts after rotating landscape to seascape,
-                // update display info and snap algorithm targets
-                repositionSnapTargetBeforeMinimized();
-            }
-            if (mIsInMinimizeInteraction != minimized || mCurrentAnimator != null) {
-                cancelFlingAnimation();
-                if (minimized) {
-                    // Relayout to recalculate the divider shadow when minimizing
-                    requestLayout();
-                    mIsInMinimizeInteraction = true;
-                    resizeStackSurfaces(mSplitLayout.getMinimizedSnapAlgorithm(mHomeStackResizable)
-                            .getMiddleTarget(), t);
-                } else {
-                    resizeStackSurfaces(mSnapTargetBeforeMinimized, t);
-                    mIsInMinimizeInteraction = false;
-                }
-            }
-        }
-    }
-
-    void enterSplitMode(boolean isHomeStackResizable) {
-        setHidden(false);
-
-        SnapTarget miniMid =
-                mSplitLayout.getMinimizedSnapAlgorithm(isHomeStackResizable).getMiddleTarget();
-        if (mDockedStackMinimized) {
-            mDividerPositionY = mDividerPositionX = miniMid.position;
-        }
-    }
-
-    /**
-     * Tries to grab a surface control from ViewRootImpl. If this isn't available for some reason
-     * (ie. the window isn't ready yet), it will get the surfacecontrol that the WindowlessWM has
-     * assigned to it.
-     */
-    private SurfaceControl getWindowSurfaceControl() {
-        return mWindowManager.mSystemWindows.getViewSurface(this);
-    }
-
-    void exitSplitMode() {
-        // The view is going to be removed right after this function involved, updates the surface
-        // in the current thread instead of posting it to the view's UI thread.
-        final SurfaceControl sc = getWindowSurfaceControl();
-        if (sc == null) {
-            return;
-        }
-        Transaction t = mTiles.getTransaction();
-        t.hide(sc);
-        mImeController.setDimsHidden(t, true);
-        t.apply();
-        mTiles.releaseTransaction(t);
-
-        // Reset tile bounds
-        int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
-        mWindowManagerProxy.applyResizeSplits(midPos, mSplitLayout);
-    }
-
-    void setMinimizedDockStack(boolean minimized, long animDuration,
-            boolean isHomeStackResizable) {
-        if (DEBUG) Slog.d(TAG, "setMinDock: " + mDockedStackMinimized + "->" + minimized);
-        mHomeStackResizable = isHomeStackResizable;
-        updateDockSide();
-        if (mDockedStackMinimized != minimized) {
-            mIsInMinimizeInteraction = true;
-            mDockedStackMinimized = minimized;
-            stopDragging(minimized
-                            ? mSnapTargetBeforeMinimized.position
-                            : getCurrentPosition(),
-                    minimized
-                            ? mSplitLayout.getMinimizedSnapAlgorithm(mHomeStackResizable)
-                                    .getMiddleTarget()
-                            : mSnapTargetBeforeMinimized,
-                    animDuration, Interpolators.FAST_OUT_SLOW_IN, 0);
-            setAdjustedForIme(false, animDuration);
-        }
-        if (!minimized) {
-            mBackground.animate().withEndAction(mResetBackgroundRunnable);
-        }
-        mBackground.animate()
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .setDuration(animDuration)
-                .start();
-    }
-
-    // Needed to end any currently playing animations when they might compete with other anims
-    // (specifically, IME adjust animation immediately after leaving minimized). Someday maybe
-    // these can be unified, but not today.
-    void finishAnimations() {
-        if (mCurrentAnimator != null) {
-            mCurrentAnimator.end();
-        }
-    }
-
-    void setAdjustedForIme(boolean adjustedForIme, long animDuration) {
-        if (mAdjustedForIme == adjustedForIme) {
-            return;
-        }
-        updateDockSide();
-        mHandle.animate()
-                .setInterpolator(IME_ADJUST_INTERPOLATOR)
-                .setDuration(animDuration)
-                .alpha(adjustedForIme ? 0f : 1f)
-                .start();
-        if (mDockSide == WindowManager.DOCKED_TOP) {
-            mBackground.setPivotY(0);
-            mBackground.animate()
-                    .scaleY(adjustedForIme ? ADJUSTED_FOR_IME_SCALE : 1f);
-        }
-        if (!adjustedForIme) {
-            mBackground.animate().withEndAction(mResetBackgroundRunnable);
-        }
-        mBackground.animate()
-                .setInterpolator(IME_ADJUST_INTERPOLATOR)
-                .setDuration(animDuration)
-                .start();
-        mAdjustedForIme = adjustedForIme;
-    }
-
-    private void saveSnapTargetBeforeMinimized(SnapTarget target) {
-        mSnapTargetBeforeMinimized = target;
-        mState.mRatioPositionBeforeMinimized = (float) target.position
-                / (isHorizontalDivision() ? mSplitLayout.mDisplayLayout.height()
-                        : mSplitLayout.mDisplayLayout.width());
-    }
-
-    private void resetBackground() {
-        mBackground.setPivotX(mBackground.getWidth() / 2);
-        mBackground.setPivotY(mBackground.getHeight() / 2);
-        mBackground.setScaleX(1f);
-        mBackground.setScaleY(1f);
-        mMinimizedShadow.setAlpha(0f);
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-    }
-
-    private void repositionSnapTargetBeforeMinimized() {
-        int position = (int) (mState.mRatioPositionBeforeMinimized
-                * (isHorizontalDivision() ? mSplitLayout.mDisplayLayout.height()
-                        : mSplitLayout.mDisplayLayout.width()));
-
-        // Set the snap target before minimized but do not save until divider is attached and not
-        // minimized because it does not know its minimized state yet.
-        mSnapTargetBeforeMinimized =
-                mSplitLayout.getSnapAlgorithm().calculateNonDismissingSnapTarget(position);
-    }
-
-    private int calculatePosition(int touchX, int touchY) {
-        return isHorizontalDivision() ? calculateYPosition(touchY) : calculateXPosition(touchX);
-    }
-
-    public boolean isHorizontalDivision() {
-        return getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
-    }
-
-    private int calculateXPosition(int touchX) {
-        return mStartPosition + touchX - mStartX;
-    }
-
-    private int calculateYPosition(int touchY) {
-        return mStartPosition + touchY - mStartY;
-    }
-
-    private void alignTopLeft(Rect containingRect, Rect rect) {
-        int width = rect.width();
-        int height = rect.height();
-        rect.set(containingRect.left, containingRect.top,
-                containingRect.left + width, containingRect.top + height);
-    }
-
-    private void alignBottomRight(Rect containingRect, Rect rect) {
-        int width = rect.width();
-        int height = rect.height();
-        rect.set(containingRect.right - width, containingRect.bottom - height,
-                containingRect.right, containingRect.bottom);
-    }
-
-    private void calculateBoundsForPosition(int position, int dockSide, Rect outRect) {
-        DockedDividerUtils.calculateBoundsForPosition(position, dockSide, outRect,
-                mSplitLayout.mDisplayLayout.width(), mSplitLayout.mDisplayLayout.height(),
-                mDividerSize);
-    }
-
-    private void resizeStackSurfaces(SnapTarget taskSnapTarget, Transaction t) {
-        resizeStackSurfaces(taskSnapTarget.position, taskSnapTarget.position, taskSnapTarget, t);
-    }
-
-    void resizeSplitSurfaces(Transaction t, Rect dockedRect, Rect otherRect) {
-        resizeSplitSurfaces(t, dockedRect, null, otherRect, null);
-    }
-
-    private void resizeSplitSurfaces(Transaction t, Rect dockedRect, Rect dockedTaskRect,
-            Rect otherRect, Rect otherTaskRect) {
-        dockedTaskRect = dockedTaskRect == null ? dockedRect : dockedTaskRect;
-        otherTaskRect = otherTaskRect == null ? otherRect : otherTaskRect;
-
-        mDividerPositionX = mSplitLayout.getPrimarySplitSide() == DOCKED_RIGHT
-                ? otherRect.right : dockedRect.right;
-        mDividerPositionY = dockedRect.bottom;
-
-        if (DEBUG) {
-            Slog.d(TAG, "Resizing split surfaces: " + dockedRect + " " + dockedTaskRect
-                    + " " + otherRect + " " + otherTaskRect);
-        }
-
-        t.setPosition(mTiles.mPrimarySurface, dockedTaskRect.left, dockedTaskRect.top);
-        Rect crop = new Rect(dockedRect);
-        crop.offsetTo(-Math.min(dockedTaskRect.left - dockedRect.left, 0),
-                -Math.min(dockedTaskRect.top - dockedRect.top, 0));
-        t.setWindowCrop(mTiles.mPrimarySurface, crop);
-        t.setPosition(mTiles.mSecondarySurface, otherTaskRect.left, otherTaskRect.top);
-        crop.set(otherRect);
-        crop.offsetTo(-(otherTaskRect.left - otherRect.left),
-                -(otherTaskRect.top - otherRect.top));
-        t.setWindowCrop(mTiles.mSecondarySurface, crop);
-        final SurfaceControl dividerCtrl = getWindowSurfaceControl();
-        if (dividerCtrl != null) {
-            if (isHorizontalDivision()) {
-                t.setPosition(dividerCtrl, 0, mDividerPositionY - mDividerInsets);
-            } else {
-                t.setPosition(dividerCtrl, mDividerPositionX - mDividerInsets, 0);
-            }
-        }
-    }
-
-    void setResizeDimLayer(Transaction t, boolean primary, float alpha) {
-        SurfaceControl dim = primary ? mTiles.mPrimaryDim : mTiles.mSecondaryDim;
-        if (alpha <= 0.001f) {
-            t.hide(dim);
-        } else {
-            t.setAlpha(dim, alpha);
-            t.show(dim);
-        }
-    }
-
-    void resizeStackSurfaces(int position, int taskPosition, SnapTarget taskSnapTarget,
-            Transaction transaction) {
-        if (mRemoved) {
-            // This divider view has been removed so shouldn't have any additional influence.
-            return;
-        }
-        calculateBoundsForPosition(position, mDockSide, mDockedRect);
-        calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
-                mOtherRect);
-
-        if (mDockedRect.equals(mLastResizeRect) && !mEntranceAnimationRunning) {
-            return;
-        }
-
-        // Make sure shadows are updated
-        if (mBackground.getZ() > 0f) {
-            mBackground.invalidate();
-        }
-
-        final boolean ownTransaction = transaction == null;
-        final Transaction t = ownTransaction ? mTiles.getTransaction() : transaction;
-        mLastResizeRect.set(mDockedRect);
-        if (mIsInMinimizeInteraction) {
-            calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, mDockSide,
-                    mDockedTaskRect);
-            calculateBoundsForPosition(mSnapTargetBeforeMinimized.position,
-                    DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
-
-            // Move a right-docked-app to line up with the divider while dragging it
-            if (mDockSide == DOCKED_RIGHT) {
-                mDockedTaskRect.offset(Math.max(position, -mDividerSize)
-                        - mDockedTaskRect.left + mDividerSize, 0);
-            }
-            resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect, mOtherTaskRect);
-            if (ownTransaction) {
-                t.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
-                t.apply();
-                mTiles.releaseTransaction(t);
-            }
-            return;
-        }
-
-        if (mEntranceAnimationRunning && taskPosition != TASK_POSITION_SAME) {
-            calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect);
-
-            // Move a docked app if from the right in position with the divider up to insets
-            if (mDockSide == DOCKED_RIGHT) {
-                mDockedTaskRect.offset(Math.max(position, -mDividerSize)
-                        - mDockedTaskRect.left + mDividerSize, 0);
-            }
-            calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide),
-                    mOtherTaskRect);
-            resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect, mOtherTaskRect);
-        } else if (mExitAnimationRunning && taskPosition != TASK_POSITION_SAME) {
-            calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect);
-            mDockedInsetRect.set(mDockedTaskRect);
-            calculateBoundsForPosition(mExitStartPosition,
-                    DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect);
-            mOtherInsetRect.set(mOtherTaskRect);
-            applyExitAnimationParallax(mOtherTaskRect, position);
-
-            // Move a right-docked-app to line up with the divider while dragging it
-            if (mDockSide == DOCKED_RIGHT) {
-                mDockedTaskRect.offset(position + mDividerSize, 0);
-            }
-            resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect, mOtherTaskRect);
-        } else if (taskPosition != TASK_POSITION_SAME) {
-            calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide),
-                    mOtherRect);
-            int dockSideInverted = DockedDividerUtils.invertDockSide(mDockSide);
-            int taskPositionDocked =
-                    restrictDismissingTaskPosition(taskPosition, mDockSide, taskSnapTarget);
-            int taskPositionOther =
-                    restrictDismissingTaskPosition(taskPosition, dockSideInverted, taskSnapTarget);
-            calculateBoundsForPosition(taskPositionDocked, mDockSide, mDockedTaskRect);
-            calculateBoundsForPosition(taskPositionOther, dockSideInverted, mOtherTaskRect);
-            mTmpRect.set(0, 0, mSplitLayout.mDisplayLayout.width(),
-                    mSplitLayout.mDisplayLayout.height());
-            alignTopLeft(mDockedRect, mDockedTaskRect);
-            alignTopLeft(mOtherRect, mOtherTaskRect);
-            mDockedInsetRect.set(mDockedTaskRect);
-            mOtherInsetRect.set(mOtherTaskRect);
-            if (dockSideTopLeft(mDockSide)) {
-                alignTopLeft(mTmpRect, mDockedInsetRect);
-                alignBottomRight(mTmpRect, mOtherInsetRect);
-            } else {
-                alignBottomRight(mTmpRect, mDockedInsetRect);
-                alignTopLeft(mTmpRect, mOtherInsetRect);
-            }
-            applyDismissingParallax(mDockedTaskRect, mDockSide, taskSnapTarget, position,
-                    taskPositionDocked);
-            applyDismissingParallax(mOtherTaskRect, dockSideInverted, taskSnapTarget, position,
-                    taskPositionOther);
-            resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect, mOtherTaskRect);
-        } else {
-            resizeSplitSurfaces(t, mDockedRect, null, mOtherRect, null);
-        }
-        SnapTarget closestDismissTarget = getSnapAlgorithm().getClosestDismissTarget(position);
-        float dimFraction = getDimFraction(position, closestDismissTarget);
-        setResizeDimLayer(t, isDismissTargetPrimary(closestDismissTarget), dimFraction);
-        if (ownTransaction) {
-            t.apply();
-            mTiles.releaseTransaction(t);
-        }
-    }
-
-    private void applyExitAnimationParallax(Rect taskRect, int position) {
-        if (mDockSide == WindowManager.DOCKED_TOP) {
-            taskRect.offset(0, (int) ((position - mExitStartPosition) * 0.25f));
-        } else if (mDockSide == WindowManager.DOCKED_LEFT) {
-            taskRect.offset((int) ((position - mExitStartPosition) * 0.25f), 0);
-        } else if (mDockSide == WindowManager.DOCKED_RIGHT) {
-            taskRect.offset((int) ((mExitStartPosition - position) * 0.25f), 0);
-        }
-    }
-
-    private float getDimFraction(int position, SnapTarget dismissTarget) {
-        if (mEntranceAnimationRunning) {
-            return 0f;
-        }
-        float fraction = getSnapAlgorithm().calculateDismissingFraction(position);
-        fraction = Math.max(0, Math.min(fraction, 1f));
-        fraction = DIM_INTERPOLATOR.getInterpolation(fraction);
-        return fraction;
-    }
-
-    /**
-     * When the snap target is dismissing one side, make sure that the dismissing side doesn't get
-     * 0 size.
-     */
-    private int restrictDismissingTaskPosition(int taskPosition, int dockSide,
-            SnapTarget snapTarget) {
-        if (snapTarget.flag == SnapTarget.FLAG_DISMISS_START && dockSideTopLeft(dockSide)) {
-            return Math.max(mSplitLayout.getSnapAlgorithm().getFirstSplitTarget().position,
-                    mStartPosition);
-        } else if (snapTarget.flag == SnapTarget.FLAG_DISMISS_END
-                && dockSideBottomRight(dockSide)) {
-            return Math.min(mSplitLayout.getSnapAlgorithm().getLastSplitTarget().position,
-                    mStartPosition);
-        } else {
-            return taskPosition;
-        }
-    }
-
-    /**
-     * Applies a parallax to the task when dismissing.
-     */
-    private void applyDismissingParallax(Rect taskRect, int dockSide, SnapTarget snapTarget,
-            int position, int taskPosition) {
-        float fraction = Math.min(1, Math.max(0,
-                mSplitLayout.getSnapAlgorithm().calculateDismissingFraction(position)));
-        SnapTarget dismissTarget = null;
-        SnapTarget splitTarget = null;
-        int start = 0;
-        if (position <= mSplitLayout.getSnapAlgorithm().getLastSplitTarget().position
-                && dockSideTopLeft(dockSide)) {
-            dismissTarget = mSplitLayout.getSnapAlgorithm().getDismissStartTarget();
-            splitTarget = mSplitLayout.getSnapAlgorithm().getFirstSplitTarget();
-            start = taskPosition;
-        } else if (position >= mSplitLayout.getSnapAlgorithm().getLastSplitTarget().position
-                && dockSideBottomRight(dockSide)) {
-            dismissTarget = mSplitLayout.getSnapAlgorithm().getDismissEndTarget();
-            splitTarget = mSplitLayout.getSnapAlgorithm().getLastSplitTarget();
-            start = splitTarget.position;
-        }
-        if (dismissTarget != null && fraction > 0f
-                && isDismissing(splitTarget, position, dockSide)) {
-            fraction = calculateParallaxDismissingFraction(fraction, dockSide);
-            int offsetPosition = (int) (start + fraction
-                    * (dismissTarget.position - splitTarget.position));
-            int width = taskRect.width();
-            int height = taskRect.height();
-            switch (dockSide) {
-                case WindowManager.DOCKED_LEFT:
-                    taskRect.left = offsetPosition - width;
-                    taskRect.right = offsetPosition;
-                    break;
-                case WindowManager.DOCKED_RIGHT:
-                    taskRect.left = offsetPosition + mDividerSize;
-                    taskRect.right = offsetPosition + width + mDividerSize;
-                    break;
-                case WindowManager.DOCKED_TOP:
-                    taskRect.top = offsetPosition - height;
-                    taskRect.bottom = offsetPosition;
-                    break;
-                case WindowManager.DOCKED_BOTTOM:
-                    taskRect.top = offsetPosition + mDividerSize;
-                    taskRect.bottom = offsetPosition + height + mDividerSize;
-                    break;
-            }
-        }
-    }
-
-    /**
-     * @return for a specified {@code fraction}, this returns an adjusted value that simulates a
-     *         slowing down parallax effect
-     */
-    private static float calculateParallaxDismissingFraction(float fraction, int dockSide) {
-        float result = SLOWDOWN_INTERPOLATOR.getInterpolation(fraction) / 3.5f;
-
-        // Less parallax at the top, just because.
-        if (dockSide == WindowManager.DOCKED_TOP) {
-            result /= 2f;
-        }
-        return result;
-    }
-
-    private static boolean isDismissing(SnapTarget snapTarget, int position, int dockSide) {
-        if (dockSide == WindowManager.DOCKED_TOP || dockSide == WindowManager.DOCKED_LEFT) {
-            return position < snapTarget.position;
-        } else {
-            return position > snapTarget.position;
-        }
-    }
-
-    private boolean isDismissTargetPrimary(SnapTarget dismissTarget) {
-        return (dismissTarget.flag == SnapTarget.FLAG_DISMISS_START && dockSideTopLeft(mDockSide))
-                || (dismissTarget.flag == SnapTarget.FLAG_DISMISS_END
-                        && dockSideBottomRight(mDockSide));
-    }
-
-    /**
-     * @return true if and only if {@code dockSide} is top or left
-     */
-    private static boolean dockSideTopLeft(int dockSide) {
-        return dockSide == WindowManager.DOCKED_TOP || dockSide == WindowManager.DOCKED_LEFT;
-    }
-
-    /**
-     * @return true if and only if {@code dockSide} is bottom or right
-     */
-    private static boolean dockSideBottomRight(int dockSide) {
-        return dockSide == WindowManager.DOCKED_BOTTOM || dockSide == WindowManager.DOCKED_RIGHT;
-    }
-
-    @Override
-    public void onComputeInternalInsets(InternalInsetsInfo inoutInfo) {
-        inoutInfo.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
-        inoutInfo.touchableRegion.set(mHandle.getLeft(), mHandle.getTop(), mHandle.getRight(),
-                mHandle.getBottom());
-        inoutInfo.touchableRegion.op(mBackground.getLeft(), mBackground.getTop(),
-                mBackground.getRight(), mBackground.getBottom(), Op.UNION);
-    }
-
-    void onUndockingTask() {
-        int dockSide = mSplitLayout.getPrimarySplitSide();
-        if (inSplitMode()) {
-            startDragging(false /* animate */, false /* touching */);
-            SnapTarget target = dockSideTopLeft(dockSide)
-                    ? mSplitLayout.getSnapAlgorithm().getDismissEndTarget()
-                    : mSplitLayout.getSnapAlgorithm().getDismissStartTarget();
-
-            // Don't start immediately - give a little bit time to settle the drag resize change.
-            mExitAnimationRunning = true;
-            mExitStartPosition = getCurrentPosition();
-            stopDragging(mExitStartPosition, target, 336 /* duration */, 100 /* startDelay */,
-                    0 /* endDelay */, Interpolators.FAST_OUT_SLOW_IN);
-        }
-    }
-
-    private int calculatePositionForInsetBounds() {
-        mSplitLayout.mDisplayLayout.getStableBounds(mTmpRect);
-        return DockedDividerUtils.calculatePositionForBounds(mTmpRect, mDockSide, mDividerSize);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerWindowManager.java
deleted file mode 100644
index 2c3ae68..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerWindowManager.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.wm.shell.legacysplitscreen;
-
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
-import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
-import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.SHELL_ROOT_LAYER_DIVIDER;
-
-import android.graphics.PixelFormat;
-import android.graphics.Region;
-import android.os.Binder;
-import android.view.View;
-import android.view.WindowManager;
-
-import com.android.wm.shell.common.SystemWindows;
-
-/**
- * Manages the window parameters of the docked stack divider.
- */
-final class DividerWindowManager {
-
-    private static final String WINDOW_TITLE = "DockedStackDivider";
-
-    final SystemWindows mSystemWindows;
-    private WindowManager.LayoutParams mLp;
-    private View mView;
-
-    DividerWindowManager(SystemWindows systemWindows) {
-        mSystemWindows = systemWindows;
-    }
-
-    /** Add a divider view */
-    void add(View view, int width, int height, int displayId) {
-        mLp = new WindowManager.LayoutParams(
-                width, height, TYPE_DOCK_DIVIDER,
-                FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL
-                        | FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY,
-                PixelFormat.TRANSLUCENT);
-        mLp.token = new Binder();
-        mLp.setTitle(WINDOW_TITLE);
-        mLp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
-        mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-        view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
-                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
-                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
-        mSystemWindows.addView(view, mLp, displayId, SHELL_ROOT_LAYER_DIVIDER);
-        mView = view;
-    }
-
-    void remove() {
-        if (mView != null) {
-            mSystemWindows.removeView(mView);
-        }
-        mView = null;
-    }
-
-    void setSlippery(boolean slippery) {
-        boolean changed = false;
-        if (slippery && (mLp.flags & FLAG_SLIPPERY) == 0) {
-            mLp.flags |= FLAG_SLIPPERY;
-            changed = true;
-        } else if (!slippery && (mLp.flags & FLAG_SLIPPERY) != 0) {
-            mLp.flags &= ~FLAG_SLIPPERY;
-            changed = true;
-        }
-        if (changed) {
-            mSystemWindows.updateViewLayout(mView, mLp);
-        }
-    }
-
-    void setTouchable(boolean touchable) {
-        if (mView == null) {
-            return;
-        }
-        boolean changed = false;
-        if (!touchable && (mLp.flags & FLAG_NOT_TOUCHABLE) == 0) {
-            mLp.flags |= FLAG_NOT_TOUCHABLE;
-            changed = true;
-        } else if (touchable && (mLp.flags & FLAG_NOT_TOUCHABLE) != 0) {
-            mLp.flags &= ~FLAG_NOT_TOUCHABLE;
-            changed = true;
-        }
-        if (changed) {
-            mSystemWindows.updateViewLayout(mView, mLp);
-        }
-    }
-
-    /** Sets the touch region to `touchRegion`. Use null to unset.*/
-    void setTouchRegion(Region touchRegion) {
-        if (mView == null) {
-            return;
-        }
-        mSystemWindows.setTouchableRegion(mView, touchRegion);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/ForcedResizableInfoActivity.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/ForcedResizableInfoActivity.java
deleted file mode 100644
index 4fe28e6..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/ForcedResizableInfoActivity.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.legacysplitscreen;
-
-import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
-import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
-
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.os.Bundle;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnTouchListener;
-import android.widget.TextView;
-
-import com.android.wm.shell.R;
-
-/**
- * Translucent activity that gets started on top of a task in multi-window to inform the user that
- * we forced the activity below to be resizable.
- *
- * Note: This activity runs on the main thread of the process hosting the Shell lib.
- */
-public class ForcedResizableInfoActivity extends Activity implements OnTouchListener {
-
-    public static final String EXTRA_FORCED_RESIZEABLE_REASON = "extra_forced_resizeable_reason";
-
-    private static final long DISMISS_DELAY = 2500;
-
-    private final Runnable mFinishRunnable = new Runnable() {
-        @Override
-        public void run() {
-            finish();
-        }
-    };
-
-    @Override
-    protected void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.forced_resizable_activity);
-        TextView tv = findViewById(com.android.internal.R.id.message);
-        int reason = getIntent().getIntExtra(EXTRA_FORCED_RESIZEABLE_REASON, -1);
-        String text;
-        switch (reason) {
-            case FORCED_RESIZEABLE_REASON_SPLIT_SCREEN:
-                text = getString(R.string.dock_forced_resizable);
-                break;
-            case FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY:
-                text = getString(R.string.forced_resizable_secondary_display);
-                break;
-            default:
-                throw new IllegalArgumentException("Unexpected forced resizeable reason: "
-                        + reason);
-        }
-        tv.setText(text);
-        getWindow().setTitle(text);
-        getWindow().getDecorView().setOnTouchListener(this);
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-        getWindow().getDecorView().postDelayed(mFinishRunnable, DISMISS_DELAY);
-    }
-
-    @Override
-    protected void onStop() {
-        super.onStop();
-        finish();
-    }
-
-    @Override
-    public boolean onTouch(View v, MotionEvent event) {
-        finish();
-        return true;
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        finish();
-        return true;
-    }
-
-    @Override
-    public void finish() {
-        super.finish();
-        overridePendingTransition(0, R.anim.forced_resizable_exit);
-    }
-
-    @Override
-    public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
-        // Do nothing
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/ForcedResizableInfoActivityController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/ForcedResizableInfoActivityController.java
deleted file mode 100644
index 139544f9..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/ForcedResizableInfoActivityController.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.legacysplitscreen;
-
-
-import static com.android.wm.shell.legacysplitscreen.ForcedResizableInfoActivity.EXTRA_FORCED_RESIZEABLE_REASON;
-
-import android.app.ActivityOptions;
-import android.content.Context;
-import android.content.Intent;
-import android.os.UserHandle;
-import android.util.ArraySet;
-import android.widget.Toast;
-
-import com.android.wm.shell.R;
-import com.android.wm.shell.common.ShellExecutor;
-
-import java.util.function.Consumer;
-
-/**
- * Controller that decides when to show the {@link ForcedResizableInfoActivity}.
- */
-final class ForcedResizableInfoActivityController implements DividerView.DividerCallbacks {
-
-    private static final String SELF_PACKAGE_NAME = "com.android.systemui";
-
-    private static final int TIMEOUT = 1000;
-    private final Context mContext;
-    private final ShellExecutor mMainExecutor;
-    private final ArraySet<PendingTaskRecord> mPendingTasks = new ArraySet<>();
-    private final ArraySet<String> mPackagesShownInSession = new ArraySet<>();
-    private boolean mDividerDragging;
-
-    private final Runnable mTimeoutRunnable = this::showPending;
-
-    private final Consumer<Boolean> mDockedStackExistsListener = exists -> {
-        if (!exists) {
-            mPackagesShownInSession.clear();
-        }
-    };
-
-    /** Record of force resized task that's pending to be handled. */
-    private class PendingTaskRecord {
-        int mTaskId;
-        /**
-         * {@link android.app.ITaskStackListener#FORCED_RESIZEABLE_REASON_SPLIT_SCREEN} or
-         * {@link android.app.ITaskStackListener#FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY}
-         */
-        int mReason;
-
-        PendingTaskRecord(int taskId, int reason) {
-            this.mTaskId = taskId;
-            this.mReason = reason;
-        }
-    }
-
-    ForcedResizableInfoActivityController(Context context,
-            LegacySplitScreenController splitScreenController,
-            ShellExecutor mainExecutor) {
-        mContext = context;
-        mMainExecutor = mainExecutor;
-        splitScreenController.registerInSplitScreenListener(mDockedStackExistsListener);
-    }
-
-    @Override
-    public void onDraggingStart() {
-        mDividerDragging = true;
-        mMainExecutor.removeCallbacks(mTimeoutRunnable);
-    }
-
-    @Override
-    public void onDraggingEnd() {
-        mDividerDragging = false;
-        showPending();
-    }
-
-    void onAppTransitionFinished() {
-        if (!mDividerDragging) {
-            showPending();
-        }
-    }
-
-    void activityForcedResizable(String packageName, int taskId, int reason) {
-        if (debounce(packageName)) {
-            return;
-        }
-        mPendingTasks.add(new PendingTaskRecord(taskId, reason));
-        postTimeout();
-    }
-
-    void activityDismissingSplitScreen() {
-        Toast.makeText(mContext, R.string.dock_non_resizeble_failed_to_dock_text,
-                Toast.LENGTH_SHORT).show();
-    }
-
-    void activityLaunchOnSecondaryDisplayFailed() {
-        Toast.makeText(mContext, R.string.activity_launch_on_secondary_display_failed_text,
-                Toast.LENGTH_SHORT).show();
-    }
-
-    private void showPending() {
-        mMainExecutor.removeCallbacks(mTimeoutRunnable);
-        for (int i = mPendingTasks.size() - 1; i >= 0; i--) {
-            PendingTaskRecord pendingRecord = mPendingTasks.valueAt(i);
-            Intent intent = new Intent(mContext, ForcedResizableInfoActivity.class);
-            ActivityOptions options = ActivityOptions.makeBasic();
-            options.setLaunchTaskId(pendingRecord.mTaskId);
-            // Set as task overlay and allow to resume, so that when an app enters split-screen and
-            // becomes paused, the overlay will still be shown.
-            options.setTaskOverlay(true, true /* canResume */);
-            intent.putExtra(EXTRA_FORCED_RESIZEABLE_REASON, pendingRecord.mReason);
-            mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
-        }
-        mPendingTasks.clear();
-    }
-
-    private void postTimeout() {
-        mMainExecutor.removeCallbacks(mTimeoutRunnable);
-        mMainExecutor.executeDelayed(mTimeoutRunnable, TIMEOUT);
-    }
-
-    private boolean debounce(String packageName) {
-        if (packageName == null) {
-            return false;
-        }
-
-        // We launch ForcedResizableInfoActivity into a task that was forced resizable, so that
-        // triggers another notification. So ignore our own activity.
-        if (SELF_PACKAGE_NAME.equals(packageName)) {
-            return true;
-        }
-        boolean debounce = mPackagesShownInSession.contains(packageName);
-        mPackagesShownInSession.add(packageName);
-        return debounce;
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitDisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitDisplayLayout.java
deleted file mode 100644
index f201634..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitDisplayLayout.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.legacysplitscreen;
-
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
-import static android.util.RotationUtils.rotateBounds;
-import static android.view.WindowManager.DOCKED_BOTTOM;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.DOCKED_LEFT;
-import static android.view.WindowManager.DOCKED_RIGHT;
-import static android.view.WindowManager.DOCKED_TOP;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.util.TypedValue;
-import android.window.WindowContainerTransaction;
-
-import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.internal.policy.DockedDividerUtils;
-import com.android.wm.shell.common.DisplayLayout;
-
-/**
- * Handles split-screen related internal display layout. In general, this represents the
- * WM-facing understanding of the splits.
- */
-public class LegacySplitDisplayLayout {
-    /** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to
-     * restrict IME adjustment so that a min portion of top stack remains visible.*/
-    private static final float ADJUSTED_STACK_FRACTION_MIN = 0.3f;
-
-    private static final int DIVIDER_WIDTH_INACTIVE_DP = 4;
-
-    LegacySplitScreenTaskListener mTiles;
-    DisplayLayout mDisplayLayout;
-    Context mContext;
-
-    // Lazy stuff
-    boolean mResourcesValid = false;
-    int mDividerSize;
-    int mDividerSizeInactive;
-    private DividerSnapAlgorithm mSnapAlgorithm = null;
-    private DividerSnapAlgorithm mMinimizedSnapAlgorithm = null;
-    Rect mPrimary = null;
-    Rect mSecondary = null;
-    Rect mAdjustedPrimary = null;
-    Rect mAdjustedSecondary = null;
-    final Rect mTmpBounds = new Rect();
-
-    public LegacySplitDisplayLayout(Context ctx, DisplayLayout dl,
-            LegacySplitScreenTaskListener taskTiles) {
-        mTiles = taskTiles;
-        mDisplayLayout = dl;
-        mContext = ctx;
-    }
-
-    void rotateTo(int newRotation) {
-        mDisplayLayout.rotateTo(mContext.getResources(), newRotation);
-        final Configuration config = new Configuration();
-        config.unset();
-        config.orientation = mDisplayLayout.getOrientation();
-        Rect tmpRect = new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height());
-        tmpRect.inset(mDisplayLayout.nonDecorInsets());
-        config.windowConfiguration.setAppBounds(tmpRect);
-        tmpRect.set(0, 0, mDisplayLayout.width(), mDisplayLayout.height());
-        tmpRect.inset(mDisplayLayout.stableInsets());
-        config.screenWidthDp = (int) (tmpRect.width() / mDisplayLayout.density());
-        config.screenHeightDp = (int) (tmpRect.height() / mDisplayLayout.density());
-        mContext = mContext.createConfigurationContext(config);
-        mSnapAlgorithm = null;
-        mMinimizedSnapAlgorithm = null;
-        mResourcesValid = false;
-    }
-
-    private void updateResources() {
-        if (mResourcesValid) {
-            return;
-        }
-        mResourcesValid = true;
-        Resources res = mContext.getResources();
-        mDividerSize = DockedDividerUtils.getDividerSize(res,
-                DockedDividerUtils.getDividerInsets(res));
-        mDividerSizeInactive = (int) TypedValue.applyDimension(
-                TypedValue.COMPLEX_UNIT_DIP, DIVIDER_WIDTH_INACTIVE_DP, res.getDisplayMetrics());
-    }
-
-    int getPrimarySplitSide() {
-        switch (mDisplayLayout.getNavigationBarPosition(mContext.getResources())) {
-            case DisplayLayout.NAV_BAR_BOTTOM:
-                return mDisplayLayout.isLandscape() ? DOCKED_LEFT : DOCKED_TOP;
-            case DisplayLayout.NAV_BAR_LEFT:
-                return DOCKED_RIGHT;
-            case DisplayLayout.NAV_BAR_RIGHT:
-                return DOCKED_LEFT;
-            default:
-                return DOCKED_INVALID;
-        }
-    }
-
-    DividerSnapAlgorithm getSnapAlgorithm() {
-        if (mSnapAlgorithm == null) {
-            updateResources();
-            boolean isHorizontalDivision = !mDisplayLayout.isLandscape();
-            mSnapAlgorithm = new DividerSnapAlgorithm(mContext.getResources(),
-                    mDisplayLayout.width(), mDisplayLayout.height(), mDividerSize,
-                    isHorizontalDivision, mDisplayLayout.stableInsets(), getPrimarySplitSide());
-        }
-        return mSnapAlgorithm;
-    }
-
-    DividerSnapAlgorithm getMinimizedSnapAlgorithm(boolean homeStackResizable) {
-        if (mMinimizedSnapAlgorithm == null) {
-            updateResources();
-            boolean isHorizontalDivision = !mDisplayLayout.isLandscape();
-            mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(mContext.getResources(),
-                    mDisplayLayout.width(), mDisplayLayout.height(), mDividerSize,
-                    isHorizontalDivision, mDisplayLayout.stableInsets(), getPrimarySplitSide(),
-                    true /* isMinimized */, homeStackResizable);
-        }
-        return mMinimizedSnapAlgorithm;
-    }
-
-    /**
-     * Resize primary bounds and secondary bounds by divider position.
-     *
-     * @param position divider position.
-     * @return true if calculated bounds changed.
-     */
-    boolean resizeSplits(int position) {
-        mPrimary = mPrimary == null ? new Rect() : mPrimary;
-        mSecondary = mSecondary == null ? new Rect() : mSecondary;
-        int dockSide = getPrimarySplitSide();
-        boolean boundsChanged;
-
-        mTmpBounds.set(mPrimary);
-        DockedDividerUtils.calculateBoundsForPosition(position, dockSide, mPrimary,
-                mDisplayLayout.width(), mDisplayLayout.height(), mDividerSize);
-        boundsChanged = !mPrimary.equals(mTmpBounds);
-
-        mTmpBounds.set(mSecondary);
-        DockedDividerUtils.calculateBoundsForPosition(position,
-                DockedDividerUtils.invertDockSide(dockSide), mSecondary, mDisplayLayout.width(),
-                mDisplayLayout.height(), mDividerSize);
-        boundsChanged |= !mSecondary.equals(mTmpBounds);
-        return boundsChanged;
-    }
-
-    void resizeSplits(int position, WindowContainerTransaction t) {
-        if (resizeSplits(position)) {
-            t.setBounds(mTiles.mPrimary.token, mPrimary);
-            t.setBounds(mTiles.mSecondary.token, mSecondary);
-
-            t.setSmallestScreenWidthDp(mTiles.mPrimary.token,
-                    getSmallestWidthDpForBounds(mContext, mDisplayLayout, mPrimary));
-            t.setSmallestScreenWidthDp(mTiles.mSecondary.token,
-                    getSmallestWidthDpForBounds(mContext, mDisplayLayout, mSecondary));
-        }
-    }
-
-    Rect calcResizableMinimizedHomeStackBounds() {
-        DividerSnapAlgorithm.SnapTarget miniMid =
-                getMinimizedSnapAlgorithm(true /* resizable */).getMiddleTarget();
-        Rect homeBounds = new Rect();
-        DockedDividerUtils.calculateBoundsForPosition(miniMid.position,
-                DockedDividerUtils.invertDockSide(getPrimarySplitSide()), homeBounds,
-                mDisplayLayout.width(), mDisplayLayout.height(), mDividerSize);
-        return homeBounds;
-    }
-
-    /**
-     * Updates the adjustment depending on it's current state.
-     */
-    void updateAdjustedBounds(int currImeTop, int hiddenTop, int shownTop) {
-        adjustForIME(mDisplayLayout, currImeTop, hiddenTop, shownTop, mDividerSize,
-                mDividerSizeInactive, mPrimary, mSecondary);
-    }
-
-    /** Assumes top/bottom split. Splits are not adjusted for left/right splits. */
-    private void adjustForIME(DisplayLayout dl, int currImeTop, int hiddenTop, int shownTop,
-            int dividerWidth, int dividerWidthInactive, Rect primaryBounds, Rect secondaryBounds) {
-        if (mAdjustedPrimary == null) {
-            mAdjustedPrimary = new Rect();
-            mAdjustedSecondary = new Rect();
-        }
-
-        final Rect displayStableRect = new Rect();
-        dl.getStableBounds(displayStableRect);
-
-        final float shownFraction = ((float) (currImeTop - hiddenTop)) / (shownTop - hiddenTop);
-        final int currDividerWidth =
-                (int) (dividerWidthInactive * shownFraction + dividerWidth * (1.f - shownFraction));
-
-        // Calculate the highest we can move the bottom of the top stack to keep 30% visible.
-        final int minTopStackBottom = displayStableRect.top
-                + (int) ((mPrimary.bottom - displayStableRect.top) * ADJUSTED_STACK_FRACTION_MIN);
-        // Based on that, calculate the maximum amount we'll allow the ime to shift things.
-        final int maxOffset = mPrimary.bottom - minTopStackBottom;
-        // Calculate how much we would shift things without limits (basically the height of ime).
-        final int desiredOffset = hiddenTop - shownTop;
-        // Calculate an "adjustedTop" which is the currImeTop but restricted by our constraints.
-        // We want an effect where the adjustment only occurs during the "highest" portion of the
-        // ime animation. This is done by shifting the adjustment values by the difference in
-        // offsets (effectively playing the whole adjustment animation some fixed amount of pixels
-        // below the ime top).
-        final int topCorrection = Math.max(0, desiredOffset - maxOffset);
-        final int adjustedTop = currImeTop + topCorrection;
-        // The actual yOffset is the distance between adjustedTop and the bottom of the display.
-        // Since our adjustedTop values are playing "below" the ime, we clamp at 0 so we only
-        // see adjustment upward.
-        final int yOffset = Math.max(0, dl.height() - adjustedTop);
-
-        // TOP
-        // Reduce the offset by an additional small amount to squish the divider bar.
-        mAdjustedPrimary.set(primaryBounds);
-        mAdjustedPrimary.offset(0, -yOffset + (dividerWidth - currDividerWidth));
-
-        // BOTTOM
-        mAdjustedSecondary.set(secondaryBounds);
-        mAdjustedSecondary.offset(0, -yOffset);
-    }
-
-    static int getSmallestWidthDpForBounds(@NonNull Context context, DisplayLayout dl,
-            Rect bounds) {
-        int dividerSize = DockedDividerUtils.getDividerSize(context.getResources(),
-                DockedDividerUtils.getDividerInsets(context.getResources()));
-
-        int minWidth = Integer.MAX_VALUE;
-
-        // Go through all screen orientations and find the orientation in which the task has the
-        // smallest width.
-        Rect tmpRect = new Rect();
-        Rect rotatedDisplayRect = new Rect();
-        Rect displayRect = new Rect(0, 0, dl.width(), dl.height());
-
-        DisplayLayout tmpDL = new DisplayLayout();
-        for (int rotation = 0; rotation < 4; rotation++) {
-            tmpDL.set(dl);
-            tmpDL.rotateTo(context.getResources(), rotation);
-            DividerSnapAlgorithm snap = initSnapAlgorithmForRotation(context, tmpDL, dividerSize);
-
-            tmpRect.set(bounds);
-            rotateBounds(tmpRect, displayRect, dl.rotation(), rotation);
-            rotatedDisplayRect.set(0, 0, tmpDL.width(), tmpDL.height());
-            final int dockSide = getPrimarySplitSide(tmpRect, rotatedDisplayRect,
-                    tmpDL.getOrientation());
-            final int position = DockedDividerUtils.calculatePositionForBounds(tmpRect, dockSide,
-                    dividerSize);
-
-            final int snappedPosition =
-                    snap.calculateNonDismissingSnapTarget(position).position;
-            DockedDividerUtils.calculateBoundsForPosition(snappedPosition, dockSide, tmpRect,
-                    tmpDL.width(), tmpDL.height(), dividerSize);
-            Rect insettedDisplay = new Rect(rotatedDisplayRect);
-            insettedDisplay.inset(tmpDL.stableInsets());
-            tmpRect.intersect(insettedDisplay);
-            minWidth = Math.min(tmpRect.width(), minWidth);
-        }
-        return (int) (minWidth / dl.density());
-    }
-
-    static DividerSnapAlgorithm initSnapAlgorithmForRotation(Context context, DisplayLayout dl,
-            int dividerSize) {
-        final Configuration config = new Configuration();
-        config.unset();
-        config.orientation = dl.getOrientation();
-        Rect tmpRect = new Rect(0, 0, dl.width(), dl.height());
-        tmpRect.inset(dl.nonDecorInsets());
-        config.windowConfiguration.setAppBounds(tmpRect);
-        tmpRect.set(0, 0, dl.width(), dl.height());
-        tmpRect.inset(dl.stableInsets());
-        config.screenWidthDp = (int) (tmpRect.width() / dl.density());
-        config.screenHeightDp = (int) (tmpRect.height() / dl.density());
-        final Context rotationContext = context.createConfigurationContext(config);
-        return new DividerSnapAlgorithm(
-                rotationContext.getResources(), dl.width(), dl.height(), dividerSize,
-                config.orientation == ORIENTATION_PORTRAIT, dl.stableInsets());
-    }
-
-    /**
-     * Get the current primary-split side. Determined by its location of {@param bounds} within
-     * {@param displayRect} but if both are the same, it will try to dock to each side and determine
-     * if allowed in its respected {@param orientation}.
-     *
-     * @param bounds bounds of the primary split task to get which side is docked
-     * @param displayRect bounds of the display that contains the primary split task
-     * @param orientation the origination of device
-     * @return current primary-split side
-     */
-    static int getPrimarySplitSide(Rect bounds, Rect displayRect, int orientation) {
-        if (orientation == ORIENTATION_PORTRAIT) {
-            // Portrait mode, docked either at the top or the bottom.
-            final int diff = (displayRect.bottom - bounds.bottom) - (bounds.top - displayRect.top);
-            if (diff < 0) {
-                return DOCKED_BOTTOM;
-            } else {
-                // Top is default
-                return DOCKED_TOP;
-            }
-        } else if (orientation == ORIENTATION_LANDSCAPE) {
-            // Landscape mode, docked either on the left or on the right.
-            final int diff = (displayRect.right - bounds.right) - (bounds.left - displayRect.left);
-            if (diff < 0) {
-                return DOCKED_RIGHT;
-            }
-            return DOCKED_LEFT;
-        }
-        return DOCKED_INVALID;
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreen.java
deleted file mode 100644
index 499a9c5..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreen.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.legacysplitscreen;
-
-import android.graphics.Rect;
-import android.window.WindowContainerToken;
-
-import com.android.wm.shell.common.annotations.ExternalThread;
-
-import java.io.PrintWriter;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-
-/**
- * Interface to engage split screen feature.
- */
-@ExternalThread
-public interface LegacySplitScreen {
-    /** Called when keyguard showing state changed. */
-    void onKeyguardVisibilityChanged(boolean isShowing);
-
-    /** Returns {@link DividerView}. */
-    DividerView getDividerView();
-
-    /** Returns {@code true} if one of the split screen is in minimized mode. */
-    boolean isMinimized();
-
-    /** Returns {@code true} if the home stack is resizable. */
-    boolean isHomeStackResizable();
-
-    /** Returns {@code true} if the divider is visible. */
-    boolean isDividerVisible();
-
-    /** Switch to minimized state if appropriate. */
-    void setMinimized(boolean minimized);
-
-    /** Called when there's a task undocking. */
-    void onUndockingTask();
-
-    /** Called when app transition finished. */
-    void onAppTransitionFinished();
-
-    /** Dumps current status of Split Screen. */
-    void dump(PrintWriter pw);
-
-    /** Registers listener that gets called whenever the existence of the divider changes. */
-    void registerInSplitScreenListener(Consumer<Boolean> listener);
-
-    /** Unregisters listener that gets called whenever the existence of the divider changes. */
-    void unregisterInSplitScreenListener(Consumer<Boolean> listener);
-
-    /** Registers listener that gets called whenever the split screen bounds changes. */
-    void registerBoundsChangeListener(BiConsumer<Rect, Rect> listener);
-
-    /** @return the container token for the secondary split root task. */
-    WindowContainerToken getSecondaryRoot();
-
-    /**
-     * Splits the primary task if feasible, this is to preserve legacy way to toggle split screen.
-     * Like triggering split screen through long pressing recents app button or through
-     * {@link android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN}.
-     *
-     * @return {@code true} if it successes to split the primary task.
-     */
-    boolean splitPrimaryTask();
-
-    /**
-     * Exits the split to make the primary task fullscreen.
-     */
-    void dismissSplitToPrimaryTask();
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
deleted file mode 100644
index 67e487d..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.legacysplitscreen;
-
-import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import android.animation.AnimationHandler;
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityTaskManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.os.RemoteException;
-import android.provider.Settings;
-import android.util.Slog;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.Toast;
-import android.window.TaskOrganizer;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
-
-import com.android.internal.policy.DividerSnapAlgorithm;
-import com.android.wm.shell.R;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.DisplayChangeController;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.DisplayLayout;
-import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.common.SystemWindows;
-import com.android.wm.shell.common.TaskStackListenerCallback;
-import com.android.wm.shell.common.TaskStackListenerImpl;
-import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.transition.Transitions;
-
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-
-/**
- * Controls split screen feature.
- */
-public class LegacySplitScreenController implements DisplayController.OnDisplaysChangedListener {
-    static final boolean DEBUG = false;
-
-    private static final String TAG = "SplitScreenCtrl";
-    private static final int DEFAULT_APP_TRANSITION_DURATION = 336;
-
-    private final Context mContext;
-    private final DisplayChangeController.OnDisplayChangingListener mRotationController;
-    private final DisplayController mDisplayController;
-    private final DisplayImeController mImeController;
-    private final DividerImeController mImePositionProcessor;
-    private final DividerState mDividerState = new DividerState();
-    private final ForcedResizableInfoActivityController mForcedResizableController;
-    private final ShellExecutor mMainExecutor;
-    private final AnimationHandler mSfVsyncAnimationHandler;
-    private final LegacySplitScreenTaskListener mSplits;
-    private final SystemWindows mSystemWindows;
-    final TransactionPool mTransactionPool;
-    private final WindowManagerProxy mWindowManagerProxy;
-    private final TaskOrganizer mTaskOrganizer;
-    private final SplitScreenImpl mImpl = new SplitScreenImpl();
-
-    private final CopyOnWriteArrayList<WeakReference<Consumer<Boolean>>> mDockedStackExistsListeners
-            = new CopyOnWriteArrayList<>();
-    private final ArrayList<WeakReference<BiConsumer<Rect, Rect>>> mBoundsChangedListeners =
-            new ArrayList<>();
-
-
-    private DividerWindowManager mWindowManager;
-    private DividerView mView;
-
-    // Keeps track of real-time split geometry including snap positions and ime adjustments
-    private LegacySplitDisplayLayout mSplitLayout;
-
-    // Transient: this contains the layout calculated for a new rotation requested by WM. This is
-    // kept around so that we can wait for a matching configuration change and then use the exact
-    // layout that we sent back to WM.
-    private LegacySplitDisplayLayout mRotateSplitLayout;
-
-    private boolean mIsKeyguardShowing;
-    private boolean mVisible = false;
-    private volatile boolean mMinimized = false;
-    private volatile boolean mAdjustedForIme = false;
-    private boolean mHomeStackResizable = false;
-
-    public LegacySplitScreenController(Context context,
-            DisplayController displayController, SystemWindows systemWindows,
-            DisplayImeController imeController, TransactionPool transactionPool,
-            ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue,
-            TaskStackListenerImpl taskStackListener, Transitions transitions,
-            ShellExecutor mainExecutor, AnimationHandler sfVsyncAnimationHandler) {
-        mContext = context;
-        mDisplayController = displayController;
-        mSystemWindows = systemWindows;
-        mImeController = imeController;
-        mMainExecutor = mainExecutor;
-        mSfVsyncAnimationHandler = sfVsyncAnimationHandler;
-        mForcedResizableController = new ForcedResizableInfoActivityController(context, this,
-                mainExecutor);
-        mTransactionPool = transactionPool;
-        mWindowManagerProxy = new WindowManagerProxy(syncQueue, shellTaskOrganizer);
-        mTaskOrganizer = shellTaskOrganizer;
-        mSplits = new LegacySplitScreenTaskListener(this, shellTaskOrganizer, transitions,
-                syncQueue);
-        mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mMainExecutor,
-                shellTaskOrganizer);
-        mRotationController =
-                (display, fromRotation, toRotation, wct) -> {
-                    if (!mSplits.isSplitScreenSupported() || mWindowManagerProxy == null) {
-                        return;
-                    }
-                    WindowContainerTransaction t = new WindowContainerTransaction();
-                    DisplayLayout displayLayout =
-                            new DisplayLayout(mDisplayController.getDisplayLayout(display));
-                    LegacySplitDisplayLayout sdl =
-                            new LegacySplitDisplayLayout(mContext, displayLayout, mSplits);
-                    sdl.rotateTo(toRotation);
-                    mRotateSplitLayout = sdl;
-                    // snap resets to middle target when not minimized and rotation changed.
-                    final int position = mMinimized ? mView.mSnapTargetBeforeMinimized.position
-                            : sdl.getSnapAlgorithm().getMiddleTarget().position;
-                    DividerSnapAlgorithm snap = sdl.getSnapAlgorithm();
-                    final DividerSnapAlgorithm.SnapTarget target =
-                            snap.calculateNonDismissingSnapTarget(position);
-                    sdl.resizeSplits(target.position, t);
-
-                    if (isSplitActive() && mHomeStackResizable) {
-                        mWindowManagerProxy
-                                .applyHomeTasksMinimized(sdl, mSplits.mSecondary.token, t);
-                    }
-                    if (mWindowManagerProxy.queueSyncTransactionIfWaiting(t)) {
-                        // Because sync transactions are serialized, its possible for an "older"
-                        // bounds-change to get applied after a screen rotation. In that case, we
-                        // want to actually defer on that rather than apply immediately. Of course,
-                        // this means that the bounds may not change until after the rotation so
-                        // the user might see some artifacts. This should be rare.
-                        Slog.w(TAG, "Screen rotated while other operations were pending, this may"
-                                + " result in some graphical artifacts.");
-                    } else {
-                        wct.merge(t, true /* transfer */);
-                    }
-                };
-
-        mWindowManager = new DividerWindowManager(mSystemWindows);
-
-        // No need to listen to display window container or create root tasks if the device is not
-        // using legacy split screen.
-        if (!context.getResources().getBoolean(com.android.internal.R.bool.config_useLegacySplit)) {
-            return;
-        }
-
-
-        mDisplayController.addDisplayWindowListener(this);
-        // Don't initialize the divider or anything until we get the default display.
-
-        taskStackListener.addListener(
-                new TaskStackListenerCallback() {
-                    @Override
-                    public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
-                            boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
-                        if (!wasVisible || task.getWindowingMode()
-                                != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                                || !mSplits.isSplitScreenSupported()) {
-                            return;
-                        }
-
-                        if (isMinimized()) {
-                            onUndockingTask();
-                        }
-                    }
-
-                    @Override
-                    public void onActivityForcedResizable(String packageName, int taskId,
-                            int reason) {
-                        mForcedResizableController.activityForcedResizable(packageName, taskId,
-                                reason);
-                    }
-
-                    @Override
-                    public void onActivityDismissingDockedStack() {
-                        mForcedResizableController.activityDismissingSplitScreen();
-                    }
-
-                    @Override
-                    public void onActivityLaunchOnSecondaryDisplayFailed() {
-                        mForcedResizableController.activityLaunchOnSecondaryDisplayFailed();
-                    }
-                });
-    }
-    
-    public LegacySplitScreen asLegacySplitScreen() {
-        return mImpl;
-    }
-
-    public void onSplitScreenSupported() {
-        // Set starting tile bounds based on middle target
-        final WindowContainerTransaction tct = new WindowContainerTransaction();
-        int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
-        mSplitLayout.resizeSplits(midPos, tct);
-        mTaskOrganizer.applyTransaction(tct);
-    }
-
-    public void onKeyguardVisibilityChanged(boolean showing) {
-        if (!isSplitActive() || mView == null) {
-            return;
-        }
-        mView.setHidden(showing);
-        mIsKeyguardShowing = showing;
-    }
-
-    @Override
-    public void onDisplayAdded(int displayId) {
-        if (displayId != DEFAULT_DISPLAY) {
-            return;
-        }
-        mSplitLayout = new LegacySplitDisplayLayout(mDisplayController.getDisplayContext(displayId),
-                mDisplayController.getDisplayLayout(displayId), mSplits);
-        mImeController.addPositionProcessor(mImePositionProcessor);
-        mDisplayController.addDisplayChangingController(mRotationController);
-        if (!ActivityTaskManager.supportsSplitScreenMultiWindow(mContext)) {
-            removeDivider();
-            return;
-        }
-        try {
-            mSplits.init();
-        } catch (Exception e) {
-            Slog.e(TAG, "Failed to register docked stack listener", e);
-            removeDivider();
-            return;
-        }
-    }
-
-    @Override
-    public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
-        if (displayId != DEFAULT_DISPLAY || !mSplits.isSplitScreenSupported()) {
-            return;
-        }
-        mSplitLayout = new LegacySplitDisplayLayout(mDisplayController.getDisplayContext(displayId),
-                mDisplayController.getDisplayLayout(displayId), mSplits);
-        if (mRotateSplitLayout == null) {
-            int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
-            final WindowContainerTransaction tct = new WindowContainerTransaction();
-            mSplitLayout.resizeSplits(midPos, tct);
-            mTaskOrganizer.applyTransaction(tct);
-        } else if (mSplitLayout.mDisplayLayout.rotation()
-                == mRotateSplitLayout.mDisplayLayout.rotation()) {
-            mSplitLayout.mPrimary = new Rect(mRotateSplitLayout.mPrimary);
-            mSplitLayout.mSecondary = new Rect(mRotateSplitLayout.mSecondary);
-            mRotateSplitLayout = null;
-        }
-        if (isSplitActive()) {
-            update(newConfig);
-        }
-    }
-
-    public boolean isMinimized() {
-        return mMinimized;
-    }
-
-    public boolean isHomeStackResizable() {
-        return mHomeStackResizable;
-    }
-
-    public DividerView getDividerView() {
-        return mView;
-    }
-
-    public boolean isDividerVisible() {
-        return mView != null && mView.getVisibility() == View.VISIBLE;
-    }
-
-    /**
-     * This indicates that at-least one of the splits has content. This differs from
-     * isDividerVisible because the divider is only visible once *everything* is in split mode
-     * while this only cares if some things are (eg. while entering/exiting as well).
-     */
-    public boolean isSplitActive() {
-        return mSplits.mPrimary != null && mSplits.mSecondary != null
-                && (mSplits.mPrimary.topActivityType != ACTIVITY_TYPE_UNDEFINED
-                || mSplits.mSecondary.topActivityType != ACTIVITY_TYPE_UNDEFINED);
-    }
-
-    public void addDivider(Configuration configuration) {
-        Context dctx = mDisplayController.getDisplayContext(mContext.getDisplayId());
-        mView = (DividerView)
-                LayoutInflater.from(dctx).inflate(R.layout.docked_stack_divider, null);
-        mView.setAnimationHandler(mSfVsyncAnimationHandler);
-        DisplayLayout displayLayout = mDisplayController.getDisplayLayout(mContext.getDisplayId());
-        mView.injectDependencies(this, mWindowManager, mDividerState, mForcedResizableController,
-                mSplits, mSplitLayout, mImePositionProcessor, mWindowManagerProxy);
-        mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
-        mView.setMinimizedDockStack(mMinimized, mHomeStackResizable, null /* transaction */);
-        final int size = dctx.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.docked_stack_divider_thickness);
-        final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE;
-        final int width = landscape ? size : displayLayout.width();
-        final int height = landscape ? displayLayout.height() : size;
-        mWindowManager.add(mView, width, height, mContext.getDisplayId());
-    }
-
-    public void removeDivider() {
-        if (mView != null) {
-            mView.onDividerRemoved();
-        }
-        mWindowManager.remove();
-    }
-
-    public void update(Configuration configuration) {
-        final boolean isDividerHidden = mView != null && mIsKeyguardShowing;
-
-        removeDivider();
-        addDivider(configuration);
-
-        if (mMinimized) {
-            mView.setMinimizedDockStack(true, mHomeStackResizable, null /* transaction */);
-            updateTouchable();
-        }
-        mView.setHidden(isDividerHidden);
-    }
-
-    public void onTaskVanished() {
-        removeDivider();
-    }
-
-    public void updateVisibility(final boolean visible) {
-        if (DEBUG) Slog.d(TAG, "Updating visibility " + mVisible + "->" + visible);
-        if (mVisible != visible) {
-            mVisible = visible;
-            mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
-
-            if (visible) {
-                mView.enterSplitMode(mHomeStackResizable);
-                // Update state because animations won't finish.
-                mWindowManagerProxy.runInSync(
-                        t -> mView.setMinimizedDockStack(mMinimized, mHomeStackResizable, t));
-
-            } else {
-                mView.exitSplitMode();
-                mWindowManagerProxy.runInSync(
-                        t -> mView.setMinimizedDockStack(false, mHomeStackResizable, t));
-            }
-            // Notify existence listeners
-            synchronized (mDockedStackExistsListeners) {
-                mDockedStackExistsListeners.removeIf(wf -> {
-                    Consumer<Boolean> l = wf.get();
-                    if (l != null) l.accept(visible);
-                    return l == null;
-                });
-            }
-        }
-    }
-
-    public void setMinimized(final boolean minimized) {
-        if (DEBUG) Slog.d(TAG, "posting ext setMinimized " + minimized + " vis:" + mVisible);
-        mMainExecutor.execute(() -> {
-            if (DEBUG) Slog.d(TAG, "run posted ext setMinimized " + minimized + " vis:" + mVisible);
-            if (!mVisible) {
-                return;
-            }
-            setHomeMinimized(minimized);
-        });
-    }
-
-    public void setHomeMinimized(final boolean minimized) {
-        if (DEBUG) {
-            Slog.d(TAG, "setHomeMinimized  min:" + mMinimized + "->" + minimized + " hrsz:"
-                    + mHomeStackResizable + " split:" + isDividerVisible());
-        }
-        WindowContainerTransaction wct = new WindowContainerTransaction();
-        final boolean minimizedChanged = mMinimized != minimized;
-        // Update minimized state
-        if (minimizedChanged) {
-            mMinimized = minimized;
-        }
-        // Always set this because we could be entering split when mMinimized is already true
-        wct.setFocusable(mSplits.mPrimary.token, !mMinimized);
-
-        // Sync state to DividerView if it exists.
-        if (mView != null) {
-            final int displayId = mView.getDisplay() != null
-                    ? mView.getDisplay().getDisplayId() : DEFAULT_DISPLAY;
-            // pause ime here (before updateMinimizedDockedStack)
-            if (mMinimized) {
-                mImePositionProcessor.pause(displayId);
-            }
-            if (minimizedChanged) {
-                // This conflicts with IME adjustment, so only call it when things change.
-                mView.setMinimizedDockStack(minimized, getAnimDuration(), mHomeStackResizable);
-            }
-            if (!mMinimized) {
-                // afterwards so it can end any animations started in view
-                mImePositionProcessor.resume(displayId);
-            }
-        }
-        updateTouchable();
-
-        // If we are only setting focusability, a sync transaction isn't necessary (in fact it
-        // can interrupt other animations), so see if it can be submitted on pending instead.
-        if (!mWindowManagerProxy.queueSyncTransactionIfWaiting(wct)) {
-            mTaskOrganizer.applyTransaction(wct);
-        }
-    }
-
-    public void setAdjustedForIme(boolean adjustedForIme) {
-        if (mAdjustedForIme == adjustedForIme) {
-            return;
-        }
-        mAdjustedForIme = adjustedForIme;
-        updateTouchable();
-    }
-
-    public void updateTouchable() {
-        mWindowManager.setTouchable(!mAdjustedForIme);
-    }
-
-    public void onUndockingTask() {
-        if (mView != null) {
-            mView.onUndockingTask();
-        }
-    }
-
-    public void onAppTransitionFinished() {
-        if (mView == null) {
-            return;
-        }
-        mForcedResizableController.onAppTransitionFinished();
-    }
-
-    public void dump(PrintWriter pw) {
-        pw.print("  mVisible="); pw.println(mVisible);
-        pw.print("  mMinimized="); pw.println(mMinimized);
-        pw.print("  mAdjustedForIme="); pw.println(mAdjustedForIme);
-    }
-
-    public long getAnimDuration() {
-        float transitionScale = Settings.Global.getFloat(mContext.getContentResolver(),
-                Settings.Global.TRANSITION_ANIMATION_SCALE,
-                mContext.getResources().getFloat(
-                        com.android.internal.R.dimen
-                                .config_appTransitionAnimationDurationScaleDefault));
-        final long transitionDuration = DEFAULT_APP_TRANSITION_DURATION;
-        return (long) (transitionDuration * transitionScale);
-    }
-
-    public void registerInSplitScreenListener(Consumer<Boolean> listener) {
-        listener.accept(isDividerVisible());
-        synchronized (mDockedStackExistsListeners) {
-            mDockedStackExistsListeners.add(new WeakReference<>(listener));
-        }
-    }
-
-    public void unregisterInSplitScreenListener(Consumer<Boolean> listener) {
-        synchronized (mDockedStackExistsListeners) {
-            for (int i = mDockedStackExistsListeners.size() - 1; i >= 0; i--) {
-                if (mDockedStackExistsListeners.get(i) == listener) {
-                    mDockedStackExistsListeners.remove(i);
-                }
-            }
-        }
-    }
-
-    public void registerBoundsChangeListener(BiConsumer<Rect, Rect> listener) {
-        synchronized (mBoundsChangedListeners) {
-            mBoundsChangedListeners.add(new WeakReference<>(listener));
-        }
-    }
-
-    public boolean splitPrimaryTask() {
-        try {
-            if (ActivityTaskManager.getService().getLockTaskModeState() == LOCK_TASK_MODE_PINNED) {
-                return false;
-            }
-        } catch (RemoteException e) {
-            return false;
-        }
-        if (isSplitActive() || mSplits.mPrimary == null) {
-            return false;
-        }
-
-        // Try fetching the top running task.
-        final List<RunningTaskInfo> runningTasks =
-                ActivityTaskManager.getInstance().getTasks(1 /* maxNum */);
-        if (runningTasks == null || runningTasks.isEmpty()) {
-            return false;
-        }
-        // Note: The set of running tasks from the system is ordered by recency.
-        final RunningTaskInfo topRunningTask = runningTasks.get(0);
-        final int activityType = topRunningTask.getActivityType();
-        if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) {
-            return false;
-        }
-
-        if (!topRunningTask.supportsSplitScreenMultiWindow) {
-            Toast.makeText(mContext, R.string.dock_non_resizeble_failed_to_dock_text,
-                    Toast.LENGTH_SHORT).show();
-            return false;
-        }
-
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        // Clear out current windowing mode before reparenting to split task.
-        wct.setWindowingMode(topRunningTask.token, WINDOWING_MODE_UNDEFINED);
-        wct.reparent(topRunningTask.token, mSplits.mPrimary.token, true /* onTop */);
-        mWindowManagerProxy.applySyncTransaction(wct);
-        return true;
-    }
-
-    public void dismissSplitToPrimaryTask() {
-        startDismissSplit(true /* toPrimaryTask */);
-    }
-
-    /** Notifies the bounds of split screen changed. */
-    public void notifyBoundsChanged(Rect secondaryWindowBounds, Rect secondaryWindowInsets) {
-        synchronized (mBoundsChangedListeners) {
-            mBoundsChangedListeners.removeIf(wf -> {
-                BiConsumer<Rect, Rect> l = wf.get();
-                if (l != null) l.accept(secondaryWindowBounds, secondaryWindowInsets);
-                return l == null;
-            });
-        }
-    }
-
-    public void startEnterSplit() {
-        update(mDisplayController.getDisplayContext(
-                mContext.getDisplayId()).getResources().getConfiguration());
-        // Set resizable directly here because applyEnterSplit already resizes home stack.
-        mHomeStackResizable = mWindowManagerProxy.applyEnterSplit(mSplits,
-                mRotateSplitLayout != null ? mRotateSplitLayout : mSplitLayout);
-    }
-
-    public void prepareEnterSplitTransition(WindowContainerTransaction outWct) {
-        // Set resizable directly here because buildEnterSplit already resizes home stack.
-        mHomeStackResizable = mWindowManagerProxy.buildEnterSplit(outWct, mSplits,
-                mRotateSplitLayout != null ? mRotateSplitLayout : mSplitLayout);
-    }
-
-    public void finishEnterSplitTransition(boolean minimized) {
-        update(mDisplayController.getDisplayContext(
-                mContext.getDisplayId()).getResources().getConfiguration());
-        if (minimized) {
-            ensureMinimizedSplit();
-        } else {
-            ensureNormalSplit();
-        }
-    }
-
-    public void startDismissSplit(boolean toPrimaryTask) {
-        startDismissSplit(toPrimaryTask, false /* snapped */);
-    }
-
-    public void startDismissSplit(boolean toPrimaryTask, boolean snapped) {
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            mSplits.getSplitTransitions().dismissSplit(
-                    mSplits, mSplitLayout, !toPrimaryTask, snapped);
-        } else {
-            mWindowManagerProxy.applyDismissSplit(mSplits, mSplitLayout, !toPrimaryTask);
-            onDismissSplit();
-        }
-    }
-
-    public void onDismissSplit() {
-        updateVisibility(false /* visible */);
-        mMinimized = false;
-        // Resets divider bar position to undefined, so new divider bar will apply default position
-        // next time entering split mode.
-        mDividerState.mRatioPositionBeforeMinimized = 0;
-        removeDivider();
-        mImePositionProcessor.reset();
-    }
-
-    public void ensureMinimizedSplit() {
-        setHomeMinimized(true /* minimized */);
-        if (mView != null && !isDividerVisible()) {
-            // Wasn't in split-mode yet, so enter now.
-            if (DEBUG) {
-                Slog.d(TAG, " entering split mode with minimized=true");
-            }
-            updateVisibility(true /* visible */);
-        }
-    }
-
-    public void ensureNormalSplit() {
-        setHomeMinimized(false /* minimized */);
-        if (mView != null && !isDividerVisible()) {
-            // Wasn't in split-mode, so enter now.
-            if (DEBUG) {
-                Slog.d(TAG, " enter split mode unminimized ");
-            }
-            updateVisibility(true /* visible */);
-        }
-    }
-
-    public LegacySplitDisplayLayout getSplitLayout() {
-        return mSplitLayout;
-    }
-
-    public WindowManagerProxy getWmProxy() {
-        return mWindowManagerProxy;
-    }
-
-    public WindowContainerToken getSecondaryRoot() {
-        if (mSplits == null || mSplits.mSecondary == null) {
-            return null;
-        }
-        return mSplits.mSecondary.token;
-    }
-
-    private class SplitScreenImpl implements LegacySplitScreen {
-        @Override
-        public boolean isMinimized() {
-            return mMinimized;
-        }
-
-        @Override
-        public boolean isHomeStackResizable() {
-            return mHomeStackResizable;
-        }
-
-        /**
-         * TODO: Remove usage from outside the shell.
-         */
-        @Override
-        public DividerView getDividerView() {
-            return LegacySplitScreenController.this.getDividerView();
-        }
-
-        @Override
-        public boolean isDividerVisible() {
-            boolean[] result = new boolean[1];
-            try {
-                mMainExecutor.executeBlocking(() -> {
-                    result[0] = LegacySplitScreenController.this.isDividerVisible();
-                });
-            } catch (InterruptedException e) {
-                Slog.e(TAG, "Failed to get divider visible");
-            }
-            return result[0];
-        }
-
-        @Override
-        public void onKeyguardVisibilityChanged(boolean isShowing) {
-            mMainExecutor.execute(() -> {
-                LegacySplitScreenController.this.onKeyguardVisibilityChanged(isShowing);
-            });
-        }
-
-        @Override
-        public void setMinimized(boolean minimized) {
-            mMainExecutor.execute(() -> {
-                LegacySplitScreenController.this.setMinimized(minimized);
-            });
-        }
-
-        @Override
-        public void onUndockingTask() {
-            mMainExecutor.execute(() -> {
-                LegacySplitScreenController.this.onUndockingTask();
-            });
-        }
-
-        @Override
-        public void onAppTransitionFinished() {
-            mMainExecutor.execute(() -> {
-                LegacySplitScreenController.this.onAppTransitionFinished();
-            });
-        }
-
-        @Override
-        public void registerInSplitScreenListener(Consumer<Boolean> listener) {
-            mMainExecutor.execute(() -> {
-                LegacySplitScreenController.this.registerInSplitScreenListener(listener);
-            });
-        }
-
-        @Override
-        public void unregisterInSplitScreenListener(Consumer<Boolean> listener) {
-            mMainExecutor.execute(() -> {
-                LegacySplitScreenController.this.unregisterInSplitScreenListener(listener);
-            });
-        }
-
-        @Override
-        public void registerBoundsChangeListener(BiConsumer<Rect, Rect> listener) {
-            mMainExecutor.execute(() -> {
-                LegacySplitScreenController.this.registerBoundsChangeListener(listener);
-            });
-        }
-
-        @Override
-        public WindowContainerToken getSecondaryRoot() {
-            WindowContainerToken[] result = new WindowContainerToken[1];
-            try {
-                mMainExecutor.executeBlocking(() -> {
-                    result[0] = LegacySplitScreenController.this.getSecondaryRoot();
-                });
-            } catch (InterruptedException e) {
-                Slog.e(TAG, "Failed to get secondary root");
-            }
-            return result[0];
-        }
-
-        @Override
-        public boolean splitPrimaryTask() {
-            boolean[] result = new boolean[1];
-            try {
-                mMainExecutor.executeBlocking(() -> {
-                    result[0] = LegacySplitScreenController.this.splitPrimaryTask();
-                });
-            } catch (InterruptedException e) {
-                Slog.e(TAG, "Failed to split primary task");
-            }
-            return result[0];
-        }
-
-        @Override
-        public void dismissSplitToPrimaryTask() {
-            mMainExecutor.execute(() -> {
-                LegacySplitScreenController.this.dismissSplitToPrimaryTask();
-            });
-        }
-
-        @Override
-        public void dump(PrintWriter pw) {
-            try {
-                mMainExecutor.executeBlocking(() -> {
-                    LegacySplitScreenController.this.dump(pw);
-                });
-            } catch (InterruptedException e) {
-                Slog.e(TAG, "Failed to dump LegacySplitScreenController in 2s");
-            }
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
deleted file mode 100644
index d2f42c3..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.legacysplitscreen;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
-
-import android.app.ActivityManager.RunningTaskInfo;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.SurfaceControl;
-import android.view.SurfaceSession;
-import android.window.TaskOrganizer;
-
-import androidx.annotation.NonNull;
-
-import com.android.internal.protolog.common.ProtoLog;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.SurfaceUtils;
-import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.transition.Transitions;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-class LegacySplitScreenTaskListener implements ShellTaskOrganizer.TaskListener {
-    private static final String TAG = LegacySplitScreenTaskListener.class.getSimpleName();
-    private static final boolean DEBUG = LegacySplitScreenController.DEBUG;
-
-    private final ShellTaskOrganizer mTaskOrganizer;
-    private final SyncTransactionQueue mSyncQueue;
-    private final SparseArray<SurfaceControl> mLeashByTaskId = new SparseArray<>();
-
-    // TODO(shell-transitions): Remove when switched to shell-transitions.
-    private final SparseArray<Point> mPositionByTaskId = new SparseArray<>();
-
-    RunningTaskInfo mPrimary;
-    RunningTaskInfo mSecondary;
-    SurfaceControl mPrimarySurface;
-    SurfaceControl mSecondarySurface;
-    SurfaceControl mPrimaryDim;
-    SurfaceControl mSecondaryDim;
-    Rect mHomeBounds = new Rect();
-    final LegacySplitScreenController mSplitScreenController;
-    private boolean mSplitScreenSupported = false;
-
-    final SurfaceSession mSurfaceSession = new SurfaceSession();
-
-    private final LegacySplitScreenTransitions mSplitTransitions;
-
-    LegacySplitScreenTaskListener(LegacySplitScreenController splitScreenController,
-            ShellTaskOrganizer shellTaskOrganizer,
-            Transitions transitions,
-            SyncTransactionQueue syncQueue) {
-        mSplitScreenController = splitScreenController;
-        mTaskOrganizer = shellTaskOrganizer;
-        mSplitTransitions = new LegacySplitScreenTransitions(splitScreenController.mTransactionPool,
-                transitions, mSplitScreenController, this);
-        transitions.addHandler(mSplitTransitions);
-        mSyncQueue = syncQueue;
-    }
-
-    void init() {
-        synchronized (this) {
-            try {
-                mTaskOrganizer.createRootTask(
-                        DEFAULT_DISPLAY, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, this);
-                mTaskOrganizer.createRootTask(
-                        DEFAULT_DISPLAY, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, this);
-            } catch (Exception e) {
-                // teardown to prevent callbacks
-                mTaskOrganizer.removeListener(this);
-                throw e;
-            }
-        }
-    }
-
-    boolean isSplitScreenSupported() {
-        return mSplitScreenSupported;
-    }
-
-    SurfaceControl.Transaction getTransaction() {
-        return mSplitScreenController.mTransactionPool.acquire();
-    }
-
-    void releaseTransaction(SurfaceControl.Transaction t) {
-        mSplitScreenController.mTransactionPool.release(t);
-    }
-
-    TaskOrganizer getTaskOrganizer() {
-        return mTaskOrganizer;
-    }
-
-    LegacySplitScreenTransitions getSplitTransitions() {
-        return mSplitTransitions;
-    }
-
-    @Override
-    public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
-        synchronized (this) {
-            if (taskInfo.hasParentTask()) {
-                handleChildTaskAppeared(taskInfo, leash);
-                return;
-            }
-
-            final int winMode = taskInfo.getWindowingMode();
-            if (winMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
-                ProtoLog.v(WM_SHELL_TASK_ORG,
-                        "%s onTaskAppeared Primary taskId=%d", TAG, taskInfo.taskId);
-                mPrimary = taskInfo;
-                mPrimarySurface = leash;
-            } else if (winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
-                ProtoLog.v(WM_SHELL_TASK_ORG,
-                        "%s onTaskAppeared Secondary taskId=%d", TAG, taskInfo.taskId);
-                mSecondary = taskInfo;
-                mSecondarySurface = leash;
-            } else {
-                ProtoLog.v(WM_SHELL_TASK_ORG, "%s onTaskAppeared unknown taskId=%d winMode=%d",
-                        TAG, taskInfo.taskId, winMode);
-            }
-
-            if (!mSplitScreenSupported && mPrimarySurface != null && mSecondarySurface != null) {
-                mSplitScreenSupported = true;
-                mSplitScreenController.onSplitScreenSupported();
-                ProtoLog.v(WM_SHELL_TASK_ORG, "%s onTaskAppeared Supported", TAG);
-
-                // Initialize dim surfaces:
-                SurfaceControl.Transaction t = getTransaction();
-                mPrimaryDim = SurfaceUtils.makeDimLayer(
-                        t, mPrimarySurface, "Primary Divider Dim", mSurfaceSession);
-                mSecondaryDim = SurfaceUtils.makeDimLayer(
-                        t, mSecondarySurface, "Secondary Divider Dim", mSurfaceSession);
-                t.apply();
-                releaseTransaction(t);
-            }
-        }
-    }
-
-    @Override
-    public void onTaskVanished(RunningTaskInfo taskInfo) {
-        synchronized (this) {
-            mPositionByTaskId.remove(taskInfo.taskId);
-            if (taskInfo.hasParentTask()) {
-                mLeashByTaskId.remove(taskInfo.taskId);
-                return;
-            }
-
-            final boolean isPrimaryTask = mPrimary != null
-                    && taskInfo.token.equals(mPrimary.token);
-            final boolean isSecondaryTask = mSecondary != null
-                    && taskInfo.token.equals(mSecondary.token);
-
-            if (mSplitScreenSupported && (isPrimaryTask || isSecondaryTask)) {
-                mSplitScreenSupported = false;
-
-                SurfaceControl.Transaction t = getTransaction();
-                t.remove(mPrimaryDim);
-                t.remove(mSecondaryDim);
-                t.remove(mPrimarySurface);
-                t.remove(mSecondarySurface);
-                t.apply();
-                releaseTransaction(t);
-
-                mSplitScreenController.onTaskVanished();
-            }
-        }
-    }
-
-    @Override
-    public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
-        if (taskInfo.displayId != DEFAULT_DISPLAY) {
-            return;
-        }
-        synchronized (this) {
-            if (!taskInfo.supportsMultiWindow) {
-                if (mSplitScreenController.isDividerVisible()) {
-                    // Dismiss the split screen if the task no longer supports multi window.
-                    if (taskInfo.taskId == mPrimary.taskId
-                            || taskInfo.parentTaskId == mPrimary.taskId) {
-                        // If the primary is focused, dismiss to primary.
-                        mSplitScreenController
-                                .startDismissSplit(taskInfo.isFocused /* toPrimaryTask */);
-                    } else {
-                        // If the secondary is not focused, dismiss to primary.
-                        mSplitScreenController
-                                .startDismissSplit(!taskInfo.isFocused /* toPrimaryTask */);
-                    }
-                }
-                return;
-            }
-            if (taskInfo.hasParentTask()) {
-                // changed messages are noisy since it reports on every ensureVisibility. This
-                // conflicts with legacy app-transitions which "swaps" the position to a
-                // leash. For now, only update when position actually changes to avoid
-                // poorly-timed duplicate calls.
-                if (taskInfo.positionInParent.equals(mPositionByTaskId.get(taskInfo.taskId))) {
-                    return;
-                }
-                handleChildTaskChanged(taskInfo);
-            } else {
-                handleTaskInfoChanged(taskInfo);
-            }
-            mPositionByTaskId.put(taskInfo.taskId, new Point(taskInfo.positionInParent));
-        }
-    }
-
-    private void handleChildTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
-        mLeashByTaskId.put(taskInfo.taskId, leash);
-        mPositionByTaskId.put(taskInfo.taskId, new Point(taskInfo.positionInParent));
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
-        updateChildTaskSurface(taskInfo, leash, true /* firstAppeared */);
-    }
-
-    private void handleChildTaskChanged(RunningTaskInfo taskInfo) {
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
-        final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);
-        updateChildTaskSurface(taskInfo, leash, false /* firstAppeared */);
-    }
-
-    private void updateChildTaskSurface(
-            RunningTaskInfo taskInfo, SurfaceControl leash, boolean firstAppeared) {
-        final Point taskPositionInParent = taskInfo.positionInParent;
-        mSyncQueue.runInSync(t -> {
-            t.setWindowCrop(leash, null);
-            t.setPosition(leash, taskPositionInParent.x, taskPositionInParent.y);
-            if (firstAppeared && !Transitions.ENABLE_SHELL_TRANSITIONS) {
-                t.setAlpha(leash, 1f);
-                t.setMatrix(leash, 1, 0, 0, 1);
-                t.show(leash);
-            }
-        });
-    }
-
-    /**
-     * This is effectively a finite state machine which moves between the various split-screen
-     * presentations based on the contents of the split regions.
-     */
-    private void handleTaskInfoChanged(RunningTaskInfo info) {
-        if (!mSplitScreenSupported) {
-            // This shouldn't happen; but apparently there is a chance that SysUI crashes without
-            // system server receiving binder-death (or maybe it receives binder-death too late?).
-            // In this situation, when sys-ui restarts, the split root-tasks will still exist so
-            // there is a small window of time during init() where WM might send messages here
-            // before init() fails. So, avoid a cycle of crashes by returning early.
-            Log.e(TAG, "Got handleTaskInfoChanged when not initialized: " + info);
-            return;
-        }
-        final boolean secondaryImpliedMinimize = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
-                || (mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS
-                        && mSplitScreenController.isHomeStackResizable());
-        final boolean primaryWasEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
-        final boolean secondaryWasEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
-        if (info.token.asBinder() == mPrimary.token.asBinder()) {
-            mPrimary = info;
-        } else if (info.token.asBinder() == mSecondary.token.asBinder()) {
-            mSecondary = info;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "onTaskInfoChanged " + mPrimary + "  " + mSecondary);
-        }
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
-        final boolean primaryIsEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
-        final boolean secondaryIsEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
-        final boolean secondaryImpliesMinimize = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
-                || (mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS
-                        && mSplitScreenController.isHomeStackResizable());
-        if (primaryIsEmpty == primaryWasEmpty && secondaryWasEmpty == secondaryIsEmpty
-                && secondaryImpliedMinimize == secondaryImpliesMinimize) {
-            // No relevant changes
-            return;
-        }
-        if (primaryIsEmpty || secondaryIsEmpty) {
-            // At-least one of the splits is empty which means we are currently transitioning
-            // into or out-of split-screen mode.
-            if (DEBUG) {
-                Log.d(TAG, " at-least one split empty " + mPrimary.topActivityType
-                        + "  " + mSecondary.topActivityType);
-            }
-            if (mSplitScreenController.isDividerVisible()) {
-                // Was in split-mode, which means we are leaving split, so continue that.
-                // This happens when the stack in the primary-split is dismissed.
-                if (DEBUG) {
-                    Log.d(TAG, "    was in split, so this means leave it "
-                            + mPrimary.topActivityType + "  " + mSecondary.topActivityType);
-                }
-                mSplitScreenController.startDismissSplit(false /* toPrimaryTask */);
-            } else if (!primaryIsEmpty && primaryWasEmpty && secondaryWasEmpty) {
-                // Wasn't in split-mode (both were empty), but now that the primary split is
-                // populated, we should fully enter split by moving everything else into secondary.
-                // This just tells window-manager to reparent things, the UI will respond
-                // when it gets new task info for the secondary split.
-                if (DEBUG) {
-                    Log.d(TAG, "   was not in split, but primary is populated, so enter it");
-                }
-                mSplitScreenController.startEnterSplit();
-            }
-        } else if (secondaryImpliesMinimize) {
-            // Workaround for b/172686383, we can't rely on the sync bounds change transaction for
-            // the home task to finish before the last updateChildTaskSurface() call even if it's
-            // queued on the sync transaction queue, so ensure that the home task surface is updated
-            // again before we minimize
-            final ArrayList<RunningTaskInfo> tasks = new ArrayList<>();
-            mSplitScreenController.getWmProxy().getHomeAndRecentsTasks(tasks,
-                    mSplitScreenController.getSecondaryRoot());
-            for (int i = 0; i < tasks.size(); i++) {
-                final RunningTaskInfo taskInfo = tasks.get(i);
-                final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);
-                if (leash != null) {
-                    updateChildTaskSurface(taskInfo, leash, false /* firstAppeared */);
-                }
-            }
-
-            // Both splits are populated but the secondary split has a home/recents stack on top,
-            // so enter minimized mode.
-            mSplitScreenController.ensureMinimizedSplit();
-        } else {
-            // Both splits are populated by normal activities, so make sure we aren't minimized.
-            mSplitScreenController.ensureNormalSplit();
-        }
-    }
-
-    @Override
-    public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
-        b.setParent(findTaskSurface(taskId));
-    }
-
-    @Override
-    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
-            SurfaceControl.Transaction t) {
-        t.reparent(sc, findTaskSurface(taskId));
-    }
-
-    private SurfaceControl findTaskSurface(int taskId) {
-        if (!mLeashByTaskId.contains(taskId)) {
-            throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
-        }
-        return mLeashByTaskId.get(taskId);
-    }
-
-    @Override
-    public void dump(@NonNull PrintWriter pw, String prefix) {
-        final String innerPrefix = prefix + "  ";
-        final String childPrefix = innerPrefix + "  ";
-        pw.println(prefix + this);
-        pw.println(innerPrefix + "mSplitScreenSupported=" + mSplitScreenSupported);
-        if (mPrimary != null) pw.println(innerPrefix + "mPrimary.taskId=" + mPrimary.taskId);
-        if (mSecondary != null) pw.println(innerPrefix + "mSecondary.taskId=" + mSecondary.taskId);
-    }
-
-    @Override
-    public String toString() {
-        return TAG;
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java
deleted file mode 100644
index b1fa2ac..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.legacysplitscreen;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.view.WindowManager.TRANSIT_CHANGE;
-import static android.view.WindowManager.TRANSIT_CLOSE;
-import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM;
-import static android.view.WindowManager.TRANSIT_OPEN;
-import static android.view.WindowManager.TRANSIT_TO_BACK;
-import static android.view.WindowManager.TRANSIT_TO_FRONT;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.app.WindowConfiguration;
-import android.graphics.Rect;
-import android.os.IBinder;
-import android.view.SurfaceControl;
-import android.view.WindowManager;
-import android.window.TransitionInfo;
-import android.window.TransitionRequestInfo;
-import android.window.WindowContainerTransaction;
-
-import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.common.annotations.ExternalThread;
-import com.android.wm.shell.transition.Transitions;
-
-import java.util.ArrayList;
-
-/** Plays transition animations for split-screen */
-public class LegacySplitScreenTransitions implements Transitions.TransitionHandler {
-    private static final String TAG = "SplitScreenTransitions";
-
-    public static final int TRANSIT_SPLIT_DISMISS_SNAP = TRANSIT_FIRST_CUSTOM + 10;
-
-    private final TransactionPool mTransactionPool;
-    private final Transitions mTransitions;
-    private final LegacySplitScreenController mSplitScreen;
-    private final LegacySplitScreenTaskListener mListener;
-
-    private IBinder mPendingDismiss = null;
-    private boolean mDismissFromSnap = false;
-    private IBinder mPendingEnter = null;
-    private IBinder mAnimatingTransition = null;
-
-    /** Keeps track of currently running animations */
-    private final ArrayList<Animator> mAnimations = new ArrayList<>();
-
-    private Transitions.TransitionFinishCallback mFinishCallback = null;
-    private SurfaceControl.Transaction mFinishTransaction;
-
-    LegacySplitScreenTransitions(@NonNull TransactionPool pool, @NonNull Transitions transitions,
-            @NonNull LegacySplitScreenController splitScreen,
-            @NonNull LegacySplitScreenTaskListener listener) {
-        mTransactionPool = pool;
-        mTransitions = transitions;
-        mSplitScreen = splitScreen;
-        mListener = listener;
-    }
-
-    @Override
-    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
-            @Nullable TransitionRequestInfo request) {
-        WindowContainerTransaction out = null;
-        final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
-        final @WindowManager.TransitionType int type = request.getType();
-        if (mSplitScreen.isDividerVisible()) {
-            // try to handle everything while in split-screen
-            out = new WindowContainerTransaction();
-            if (triggerTask != null) {
-                final boolean shouldDismiss =
-                        // if we close the primary-docked task, then leave split-screen since there
-                        // is nothing behind it.
-                        ((type == TRANSIT_CLOSE || type == TRANSIT_TO_BACK)
-                                && triggerTask.parentTaskId == mListener.mPrimary.taskId)
-                        // if an activity that is not supported in multi window mode is launched,
-                        // we also need to leave split-screen.
-                        || ((type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT)
-                                && !triggerTask.supportsMultiWindow);
-                // In both cases, dismiss the primary
-                if (shouldDismiss) {
-                    WindowManagerProxy.buildDismissSplit(out, mListener,
-                            mSplitScreen.getSplitLayout(), true /* dismiss */);
-                    if (type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT) {
-                        out.reorder(triggerTask.token, true /* onTop */);
-                    }
-                    mPendingDismiss = transition;
-                }
-            }
-        } else if (triggerTask != null) {
-            // Not in split mode, so look for an open with a trigger task.
-            if ((type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT)
-                    && triggerTask.configuration.windowConfiguration.getWindowingMode()
-                        == WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
-                out = new WindowContainerTransaction();
-                mSplitScreen.prepareEnterSplitTransition(out);
-                mPendingEnter = transition;
-            }
-        }
-        return out;
-    }
-
-    // TODO(shell-transitions): real animations
-    private void startExampleAnimation(@NonNull SurfaceControl leash, boolean show) {
-        final float end = show ? 1.f : 0.f;
-        final float start = 1.f - end;
-        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-        final ValueAnimator va = ValueAnimator.ofFloat(start, end);
-        va.setDuration(500);
-        va.addUpdateListener(animation -> {
-            float fraction = animation.getAnimatedFraction();
-            transaction.setAlpha(leash, start * (1.f - fraction) + end * fraction);
-            transaction.apply();
-        });
-        final Runnable finisher = () -> {
-            transaction.setAlpha(leash, end);
-            transaction.apply();
-            mTransactionPool.release(transaction);
-            mTransitions.getMainExecutor().execute(() -> {
-                mAnimations.remove(va);
-                onFinish();
-            });
-        };
-        va.addListener(new Animator.AnimatorListener() {
-            @Override
-            public void onAnimationStart(Animator animation) { }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                finisher.run();
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                finisher.run();
-            }
-
-            @Override
-            public void onAnimationRepeat(Animator animation) { }
-        });
-        mAnimations.add(va);
-        mTransitions.getAnimExecutor().execute(va::start);
-    }
-
-    // TODO(shell-transitions): real animations
-    private void startExampleResizeAnimation(@NonNull SurfaceControl leash,
-            @NonNull Rect startBounds, @NonNull Rect endBounds) {
-        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-        final ValueAnimator va = ValueAnimator.ofFloat(0.f, 1.f);
-        va.setDuration(500);
-        va.addUpdateListener(animation -> {
-            float fraction = animation.getAnimatedFraction();
-            transaction.setWindowCrop(leash,
-                    (int) (startBounds.width() * (1.f - fraction) + endBounds.width() * fraction),
-                    (int) (startBounds.height() * (1.f - fraction)
-                            + endBounds.height() * fraction));
-            transaction.setPosition(leash,
-                    startBounds.left * (1.f - fraction) + endBounds.left * fraction,
-                    startBounds.top * (1.f - fraction) + endBounds.top * fraction);
-            transaction.apply();
-        });
-        final Runnable finisher = () -> {
-            transaction.setWindowCrop(leash, 0, 0);
-            transaction.setPosition(leash, endBounds.left, endBounds.top);
-            transaction.apply();
-            mTransactionPool.release(transaction);
-            mTransitions.getMainExecutor().execute(() -> {
-                mAnimations.remove(va);
-                onFinish();
-            });
-        };
-        va.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                finisher.run();
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                finisher.run();
-            }
-        });
-        mAnimations.add(va);
-        mTransitions.getAnimExecutor().execute(va::start);
-    }
-
-    @Override
-    public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
-            @NonNull SurfaceControl.Transaction startTransaction,
-            @NonNull SurfaceControl.Transaction finishTransaction,
-            @NonNull Transitions.TransitionFinishCallback finishCallback) {
-        if (transition != mPendingDismiss && transition != mPendingEnter) {
-            // If we're not in split-mode, just abort
-            if (!mSplitScreen.isDividerVisible()) return false;
-            // Check to see if HOME is involved
-            for (int i = info.getChanges().size() - 1; i >= 0; --i) {
-                final TransitionInfo.Change change = info.getChanges().get(i);
-                if (change.getTaskInfo() == null
-                        || change.getTaskInfo().getActivityType() != ACTIVITY_TYPE_HOME) continue;
-                if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) {
-                    mSplitScreen.ensureMinimizedSplit();
-                } else if (change.getMode() == TRANSIT_CLOSE
-                        || change.getMode() == TRANSIT_TO_BACK) {
-                    mSplitScreen.ensureNormalSplit();
-                }
-            }
-            // Use normal animations.
-            return false;
-        }
-
-        mFinishCallback = finishCallback;
-        mFinishTransaction = mTransactionPool.acquire();
-        mAnimatingTransition = transition;
-
-        // Play fade animations
-        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
-            final TransitionInfo.Change change = info.getChanges().get(i);
-            final SurfaceControl leash = change.getLeash();
-            final int mode = info.getChanges().get(i).getMode();
-
-            if (mode == TRANSIT_CHANGE) {
-                if (change.getParent() != null) {
-                    // This is probably reparented, so we want the parent to be immediately visible
-                    final TransitionInfo.Change parentChange = info.getChange(change.getParent());
-                    startTransaction.show(parentChange.getLeash());
-                    startTransaction.setAlpha(parentChange.getLeash(), 1.f);
-                    // and then animate this layer outside the parent (since, for example, this is
-                    // the home task animating from fullscreen to part-screen).
-                    startTransaction.reparent(leash, info.getRootLeash());
-                    startTransaction.setLayer(leash, info.getChanges().size() - i);
-                    // build the finish reparent/reposition
-                    mFinishTransaction.reparent(leash, parentChange.getLeash());
-                    mFinishTransaction.setPosition(leash,
-                            change.getEndRelOffset().x, change.getEndRelOffset().y);
-                }
-                // TODO(shell-transitions): screenshot here
-                final Rect startBounds = new Rect(change.getStartAbsBounds());
-                final boolean isHome = change.getTaskInfo() != null
-                        && change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_HOME;
-                if (mPendingDismiss == transition && mDismissFromSnap && !isHome) {
-                    // Home is special since it doesn't move during fling. Everything else, though,
-                    // when dismissing from snap, the top/left is at 0,0.
-                    startBounds.offsetTo(0, 0);
-                }
-                final Rect endBounds = new Rect(change.getEndAbsBounds());
-                startBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y);
-                endBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y);
-                startExampleResizeAnimation(leash, startBounds, endBounds);
-            }
-            if (change.getParent() != null) {
-                continue;
-            }
-
-            if (transition == mPendingEnter
-                    && mListener.mPrimary.token.equals(change.getContainer())
-                    || mListener.mSecondary.token.equals(change.getContainer())) {
-                startTransaction.setWindowCrop(leash, change.getStartAbsBounds().width(),
-                        change.getStartAbsBounds().height());
-                if (mListener.mPrimary.token.equals(change.getContainer())) {
-                    // Move layer to top since we want it above the oversized home task during
-                    // animation even though home task is on top in hierarchy.
-                    startTransaction.setLayer(leash, info.getChanges().size() + 1);
-                }
-            }
-            boolean isOpening = Transitions.isOpeningType(info.getType());
-            if (isOpening && (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
-                // fade in
-                startExampleAnimation(leash, true /* show */);
-            } else if (!isOpening && (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK)) {
-                // fade out
-                if (transition == mPendingDismiss && mDismissFromSnap) {
-                    // Dismissing via snap-to-top/bottom means that the dismissed task is already
-                    // not-visible (usually cropped to oblivion) so immediately set its alpha to 0
-                    // and don't animate it so it doesn't pop-in when reparented.
-                    startTransaction.setAlpha(leash, 0.f);
-                } else {
-                    startExampleAnimation(leash, false /* show */);
-                }
-            }
-        }
-        if (transition == mPendingEnter) {
-            // If entering, check if we should enter into minimized or normal split
-            boolean homeIsVisible = false;
-            for (int i = info.getChanges().size() - 1; i >= 0; --i) {
-                final TransitionInfo.Change change = info.getChanges().get(i);
-                if (change.getTaskInfo() == null
-                        || change.getTaskInfo().getActivityType() != ACTIVITY_TYPE_HOME) {
-                    continue;
-                }
-                homeIsVisible = change.getMode() == TRANSIT_OPEN
-                        || change.getMode() == TRANSIT_TO_FRONT
-                        || change.getMode() == TRANSIT_CHANGE;
-                break;
-            }
-            mSplitScreen.finishEnterSplitTransition(homeIsVisible);
-        }
-        startTransaction.apply();
-        onFinish();
-        return true;
-    }
-
-    @ExternalThread
-    void dismissSplit(LegacySplitScreenTaskListener tiles, LegacySplitDisplayLayout layout,
-            boolean dismissOrMaximize, boolean snapped) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        WindowManagerProxy.buildDismissSplit(wct, tiles, layout, dismissOrMaximize);
-        mTransitions.getMainExecutor().execute(() -> {
-            mDismissFromSnap = snapped;
-            mPendingDismiss = mTransitions.startTransition(TRANSIT_SPLIT_DISMISS_SNAP, wct, this);
-        });
-    }
-
-    private void onFinish() {
-        if (!mAnimations.isEmpty()) return;
-        mFinishTransaction.apply();
-        mTransactionPool.release(mFinishTransaction);
-        mFinishTransaction = null;
-        mFinishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
-        mFinishCallback = null;
-        if (mAnimatingTransition == mPendingEnter) {
-            mPendingEnter = null;
-        }
-        if (mAnimatingTransition == mPendingDismiss) {
-            mSplitScreen.onDismissSplit();
-            mPendingDismiss = null;
-        }
-        mDismissFromSnap = false;
-        mAnimatingTransition = null;
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/MinimizedDockShadow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/MinimizedDockShadow.java
deleted file mode 100644
index 1e9223c..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/MinimizedDockShadow.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.legacysplitscreen;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.LinearGradient;
-import android.graphics.Paint;
-import android.graphics.Shader;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.WindowManager;
-
-import com.android.wm.shell.R;
-
-/**
- * Shadow for the minimized dock state on homescreen.
- */
-public class MinimizedDockShadow extends View {
-
-    private final Paint mShadowPaint = new Paint();
-
-    private int mDockSide = WindowManager.DOCKED_INVALID;
-
-    public MinimizedDockShadow(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    void setDockSide(int dockSide) {
-        if (dockSide != mDockSide) {
-            mDockSide = dockSide;
-            updatePaint(getLeft(), getTop(), getRight(), getBottom());
-            invalidate();
-        }
-    }
-
-    private void updatePaint(int left, int top, int right, int bottom) {
-        int startColor = mContext.getResources().getColor(
-                R.color.minimize_dock_shadow_start, null);
-        int endColor = mContext.getResources().getColor(
-                R.color.minimize_dock_shadow_end, null);
-        final int middleColor = Color.argb(
-                (Color.alpha(startColor) + Color.alpha(endColor)) / 2, 0, 0, 0);
-        final int quarter = Color.argb(
-                (int) (Color.alpha(startColor) * 0.25f + Color.alpha(endColor) * 0.75f),
-                0, 0, 0);
-        if (mDockSide == WindowManager.DOCKED_TOP) {
-            mShadowPaint.setShader(new LinearGradient(
-                    0, 0, 0, bottom - top,
-                    new int[] { startColor, middleColor, quarter, endColor },
-                    new float[] { 0f, 0.35f, 0.6f, 1f }, Shader.TileMode.CLAMP));
-        } else if (mDockSide == WindowManager.DOCKED_LEFT) {
-            mShadowPaint.setShader(new LinearGradient(
-                    0, 0, right - left, 0,
-                    new int[] { startColor, middleColor, quarter, endColor },
-                    new float[] { 0f, 0.35f, 0.6f, 1f }, Shader.TileMode.CLAMP));
-        } else if (mDockSide == WindowManager.DOCKED_RIGHT) {
-            mShadowPaint.setShader(new LinearGradient(
-                    right - left, 0, 0, 0,
-                    new int[] { startColor, middleColor, quarter, endColor },
-                    new float[] { 0f, 0.35f, 0.6f, 1f }, Shader.TileMode.CLAMP));
-        }
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        if (changed) {
-            updatePaint(left, top, right, bottom);
-            invalidate();
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        canvas.drawRect(0, 0, getWidth(), getHeight(), mShadowPaint);
-    }
-
-    @Override
-    public boolean hasOverlappingRendering() {
-        return false;
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java
deleted file mode 100644
index e42e43b..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.wm.shell.legacysplitscreen;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import android.annotation.NonNull;
-import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
-import android.graphics.Rect;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.Display;
-import android.view.SurfaceControl;
-import android.view.WindowManagerGlobal;
-import android.window.TaskOrganizer;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.ArrayUtils;
-import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.transition.Transitions;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Proxy to simplify calls into window manager/activity manager
- */
-class WindowManagerProxy {
-
-    private static final String TAG = "WindowManagerProxy";
-    private static final int[] HOME_AND_RECENTS = {ACTIVITY_TYPE_HOME, ACTIVITY_TYPE_RECENTS};
-    private static final int[] CONTROLLED_ACTIVITY_TYPES = {
-            ACTIVITY_TYPE_STANDARD,
-            ACTIVITY_TYPE_HOME,
-            ACTIVITY_TYPE_RECENTS,
-            ACTIVITY_TYPE_UNDEFINED
-    };
-    private static final int[] CONTROLLED_WINDOWING_MODES = {
-            WINDOWING_MODE_FULLSCREEN,
-            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
-            WINDOWING_MODE_UNDEFINED
-    };
-
-    @GuardedBy("mDockedRect")
-    private final Rect mDockedRect = new Rect();
-
-    private final Rect mTmpRect1 = new Rect();
-
-    @GuardedBy("mDockedRect")
-    private final Rect mTouchableRegion = new Rect();
-
-    private final SyncTransactionQueue mSyncTransactionQueue;
-    private final TaskOrganizer mTaskOrganizer;
-
-    WindowManagerProxy(SyncTransactionQueue syncQueue, TaskOrganizer taskOrganizer) {
-        mSyncTransactionQueue = syncQueue;
-        mTaskOrganizer = taskOrganizer;
-    }
-
-    void dismissOrMaximizeDocked(final LegacySplitScreenTaskListener tiles,
-            LegacySplitDisplayLayout layout, final boolean dismissOrMaximize) {
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            tiles.mSplitScreenController.startDismissSplit(!dismissOrMaximize, true /* snapped */);
-        } else {
-            applyDismissSplit(tiles, layout, dismissOrMaximize);
-        }
-    }
-
-    public void setResizing(final boolean resizing) {
-        try {
-            ActivityTaskManager.getService().setSplitScreenResizing(resizing);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Error calling setDockedStackResizing: " + e);
-        }
-    }
-
-    /** Sets a touch region */
-    public void setTouchRegion(Rect region) {
-        try {
-            synchronized (mDockedRect) {
-                mTouchableRegion.set(region);
-            }
-            WindowManagerGlobal.getWindowManagerService().setDockedTaskDividerTouchRegion(
-                    mTouchableRegion);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to set touchable region: " + e);
-        }
-    }
-
-    void applyResizeSplits(int position, LegacySplitDisplayLayout splitLayout) {
-        WindowContainerTransaction t = new WindowContainerTransaction();
-        splitLayout.resizeSplits(position, t);
-        applySyncTransaction(t);
-    }
-
-    boolean getHomeAndRecentsTasks(List<ActivityManager.RunningTaskInfo> out,
-            WindowContainerToken parent) {
-        boolean resizable = false;
-        List<ActivityManager.RunningTaskInfo> rootTasks = parent == null
-                ? mTaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS)
-                : mTaskOrganizer.getChildTasks(parent, HOME_AND_RECENTS);
-        for (int i = 0, n = rootTasks.size(); i < n; ++i) {
-            final ActivityManager.RunningTaskInfo ti = rootTasks.get(i);
-            out.add(ti);
-            if (ti.topActivityType == ACTIVITY_TYPE_HOME) {
-                resizable = ti.isResizeable;
-            }
-        }
-        return resizable;
-    }
-
-    /**
-     * Assign a fixed override-bounds to home tasks that reflect their geometry while the primary
-     * split is minimized. This actually "sticks out" of the secondary split area, but when in
-     * minimized mode, the secondary split gets a 'negative' crop to expose it.
-     */
-    boolean applyHomeTasksMinimized(LegacySplitDisplayLayout layout, WindowContainerToken parent,
-            @NonNull WindowContainerTransaction wct) {
-        // Resize the home/recents stacks to the larger minimized-state size
-        final Rect homeBounds;
-        final ArrayList<ActivityManager.RunningTaskInfo> homeStacks = new ArrayList<>();
-        boolean isHomeResizable = getHomeAndRecentsTasks(homeStacks, parent);
-        if (isHomeResizable) {
-            homeBounds = layout.calcResizableMinimizedHomeStackBounds();
-        } else {
-            // home is not resizable, so lock it to its inherent orientation size.
-            homeBounds = new Rect(0, 0, 0, 0);
-            for (int i = homeStacks.size() - 1; i >= 0; --i) {
-                if (homeStacks.get(i).topActivityType == ACTIVITY_TYPE_HOME) {
-                    final int orient = homeStacks.get(i).configuration.orientation;
-                    final boolean displayLandscape = layout.mDisplayLayout.isLandscape();
-                    final boolean isLandscape = orient == ORIENTATION_LANDSCAPE
-                            || (orient == ORIENTATION_UNDEFINED && displayLandscape);
-                    homeBounds.right = isLandscape == displayLandscape
-                            ? layout.mDisplayLayout.width() : layout.mDisplayLayout.height();
-                    homeBounds.bottom = isLandscape == displayLandscape
-                            ? layout.mDisplayLayout.height() : layout.mDisplayLayout.width();
-                    break;
-                }
-            }
-        }
-        for (int i = homeStacks.size() - 1; i >= 0; --i) {
-            // For non-resizable homes, the minimized size is actually the fullscreen-size. As a
-            // result, we don't minimize for recents since it only shows half-size screenshots.
-            if (!isHomeResizable) {
-                if (homeStacks.get(i).topActivityType == ACTIVITY_TYPE_RECENTS) {
-                    continue;
-                }
-                wct.setWindowingMode(homeStacks.get(i).token, WINDOWING_MODE_FULLSCREEN);
-            }
-            wct.setBounds(homeStacks.get(i).token, homeBounds);
-        }
-        layout.mTiles.mHomeBounds.set(homeBounds);
-        return isHomeResizable;
-    }
-
-    /** @see #buildEnterSplit */
-    boolean applyEnterSplit(LegacySplitScreenTaskListener tiles, LegacySplitDisplayLayout layout) {
-        // Set launchtile first so that any stack created after
-        // getAllRootTaskInfos and before reparent (even if unlikely) are placed
-        // correctly.
-        WindowContainerTransaction wct = new WindowContainerTransaction();
-        wct.setLaunchRoot(tiles.mSecondary.token, CONTROLLED_WINDOWING_MODES,
-                CONTROLLED_ACTIVITY_TYPES);
-        final boolean isHomeResizable = buildEnterSplit(wct, tiles, layout);
-        applySyncTransaction(wct);
-        return isHomeResizable;
-    }
-
-    /**
-     * Finishes entering split-screen by reparenting all FULLSCREEN tasks into the secondary split.
-     * This assumes there is already something in the primary split since that is usually what
-     * triggers a call to this. In the same transaction, this overrides the home task bounds via
-     * {@link #applyHomeTasksMinimized}.
-     *
-     * @return whether the home stack is resizable
-     */
-    boolean buildEnterSplit(WindowContainerTransaction outWct, LegacySplitScreenTaskListener tiles,
-            LegacySplitDisplayLayout layout) {
-        List<ActivityManager.RunningTaskInfo> rootTasks =
-                mTaskOrganizer.getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */);
-        if (rootTasks.isEmpty()) {
-            return false;
-        }
-        ActivityManager.RunningTaskInfo topHomeTask = null;
-        for (int i = rootTasks.size() - 1; i >= 0; --i) {
-            final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i);
-            // Check whether the task can be moved to split secondary.
-            if (!rootTask.supportsMultiWindow && rootTask.topActivityType != ACTIVITY_TYPE_HOME) {
-                continue;
-            }
-            // Only move split controlling tasks to split secondary.
-            final int windowingMode = rootTask.getWindowingMode();
-            if (!ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, windowingMode)
-                    || !ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, rootTask.getActivityType())
-                    // Excludes split screen secondary due to it's the root we're reparenting to.
-                    || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
-                continue;
-            }
-            // Since this iterates from bottom to top, update topHomeTask for every fullscreen task
-            // so it will be left with the status of the top one.
-            topHomeTask = isHomeOrRecentTask(rootTask) ? rootTask : null;
-            outWct.reparent(rootTask.token, tiles.mSecondary.token, true /* onTop */);
-        }
-        // Move the secondary split-forward.
-        outWct.reorder(tiles.mSecondary.token, true /* onTop */);
-        boolean isHomeResizable = applyHomeTasksMinimized(layout, null /* parent */,
-                outWct);
-        if (topHomeTask != null && !Transitions.ENABLE_SHELL_TRANSITIONS) {
-            // Translate/update-crop of secondary out-of-band with sync transaction -- Until BALST
-            // is enabled, this temporarily syncs the home surface position with offset until
-            // sync transaction finishes.
-            outWct.setBoundsChangeTransaction(topHomeTask.token, tiles.mHomeBounds);
-        }
-        return isHomeResizable;
-    }
-
-    static boolean isHomeOrRecentTask(ActivityManager.RunningTaskInfo ti) {
-        final int atype = ti.getActivityType();
-        return atype == ACTIVITY_TYPE_HOME || atype == ACTIVITY_TYPE_RECENTS;
-    }
-
-    /** @see #buildDismissSplit */
-    void applyDismissSplit(LegacySplitScreenTaskListener tiles, LegacySplitDisplayLayout layout,
-            boolean dismissOrMaximize) {
-        // TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished
-        //                 plus specific APIs to clean this up.
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        // Set launch root first so that any task created after getChildContainers and
-        // before reparent (pretty unlikely) are put into fullscreen.
-        wct.setLaunchRoot(tiles.mSecondary.token, null, null);
-        buildDismissSplit(wct, tiles, layout, dismissOrMaximize);
-        applySyncTransaction(wct);
-    }
-
-    /**
-     * Reparents all tile members back to their display and resets home task override bounds.
-     * @param dismissOrMaximize When {@code true} this resolves the split by closing the primary
-     *                          split (thus resulting in the top of the secondary split becoming
-     *                          fullscreen. {@code false} resolves the other way.
-     */
-    static void buildDismissSplit(WindowContainerTransaction outWct,
-            LegacySplitScreenTaskListener tiles, LegacySplitDisplayLayout layout,
-            boolean dismissOrMaximize) {
-        // TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished
-        //                 plus specific APIs to clean this up.
-        final TaskOrganizer taskOrg = tiles.getTaskOrganizer();
-        List<ActivityManager.RunningTaskInfo> primaryChildren =
-                taskOrg.getChildTasks(tiles.mPrimary.token, null /* activityTypes */);
-        List<ActivityManager.RunningTaskInfo> secondaryChildren =
-                taskOrg.getChildTasks(tiles.mSecondary.token, null /* activityTypes */);
-        // In some cases (eg. non-resizable is launched), system-server will leave split-screen.
-        // as a result, the above will not capture any tasks; yet, we need to clean-up the
-        // home task bounds.
-        List<ActivityManager.RunningTaskInfo> freeHomeAndRecents =
-                taskOrg.getRootTasks(DEFAULT_DISPLAY, HOME_AND_RECENTS);
-        // Filter out the root split tasks
-        freeHomeAndRecents.removeIf(p -> p.token.equals(tiles.mSecondary.token)
-                || p.token.equals(tiles.mPrimary.token));
-
-        if (primaryChildren.isEmpty() && secondaryChildren.isEmpty()
-                && freeHomeAndRecents.isEmpty()) {
-            return;
-        }
-        if (dismissOrMaximize) {
-            // Dismissing, so move all primary split tasks first
-            for (int i = primaryChildren.size() - 1; i >= 0; --i) {
-                outWct.reparent(primaryChildren.get(i).token, null /* parent */,
-                        true /* onTop */);
-            }
-            boolean homeOnTop = false;
-            // Don't need to worry about home tasks because they are already in the "proper"
-            // order within the secondary split.
-            for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
-                final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
-                outWct.reparent(ti.token, null /* parent */, true /* onTop */);
-                if (isHomeOrRecentTask(ti)) {
-                    outWct.setBounds(ti.token, null);
-                    outWct.setWindowingMode(ti.token, WINDOWING_MODE_UNDEFINED);
-                    if (i == 0) {
-                        homeOnTop = true;
-                    }
-                }
-            }
-            if (homeOnTop && !Transitions.ENABLE_SHELL_TRANSITIONS) {
-                // Translate/update-crop of secondary out-of-band with sync transaction -- instead
-                // play this in sync with new home-app frame because until BALST is enabled this
-                // shows up on screen before the syncTransaction returns.
-                // We only have access to the secondary root surface, though, so in order to
-                // position things properly, we have to take into account the existing negative
-                // offset/crop of the minimized-home task.
-                final boolean landscape = layout.mDisplayLayout.isLandscape();
-                final int posX = landscape ? layout.mSecondary.left - tiles.mHomeBounds.left
-                        : layout.mSecondary.left;
-                final int posY = landscape ? layout.mSecondary.top
-                        : layout.mSecondary.top - tiles.mHomeBounds.top;
-                final SurfaceControl.Transaction sft = new SurfaceControl.Transaction();
-                sft.setPosition(tiles.mSecondarySurface, posX, posY);
-                final Rect crop = new Rect(0, 0, layout.mDisplayLayout.width(),
-                        layout.mDisplayLayout.height());
-                crop.offset(-posX, -posY);
-                sft.setWindowCrop(tiles.mSecondarySurface, crop);
-                outWct.setBoundsChangeTransaction(tiles.mSecondary.token, sft);
-            }
-        } else {
-            // Maximize, so move non-home secondary split first
-            for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
-                if (isHomeOrRecentTask(secondaryChildren.get(i))) {
-                    continue;
-                }
-                outWct.reparent(secondaryChildren.get(i).token, null /* parent */,
-                        true /* onTop */);
-            }
-            // Find and place home tasks in-between. This simulates the fact that there was
-            // nothing behind the primary split's tasks.
-            for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
-                final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
-                if (isHomeOrRecentTask(ti)) {
-                    outWct.reparent(ti.token, null /* parent */, true /* onTop */);
-                    // reset bounds and mode too
-                    outWct.setBounds(ti.token, null);
-                    outWct.setWindowingMode(ti.token, WINDOWING_MODE_UNDEFINED);
-                }
-            }
-            for (int i = primaryChildren.size() - 1; i >= 0; --i) {
-                outWct.reparent(primaryChildren.get(i).token, null /* parent */,
-                        true /* onTop */);
-            }
-        }
-        for (int i = freeHomeAndRecents.size() - 1; i >= 0; --i) {
-            outWct.setBounds(freeHomeAndRecents.get(i).token, null);
-            outWct.setWindowingMode(freeHomeAndRecents.get(i).token, WINDOWING_MODE_UNDEFINED);
-        }
-        // Reset focusable to true
-        outWct.setFocusable(tiles.mPrimary.token, true /* focusable */);
-    }
-
-    /**
-     * Utility to apply a sync transaction serially with other sync transactions.
-     *
-     * @see SyncTransactionQueue#queue
-     */
-    void applySyncTransaction(WindowContainerTransaction wct) {
-        mSyncTransactionQueue.queue(wct);
-    }
-
-    /**
-     * @see SyncTransactionQueue#queueIfWaiting
-     */
-    boolean queueSyncTransactionIfWaiting(WindowContainerTransaction wct) {
-        return mSyncTransactionQueue.queueIfWaiting(wct);
-    }
-
-    /**
-     * @see SyncTransactionQueue#runInSync
-     */
-    void runInSync(SyncTransactionQueue.TransactionRunnable runnable) {
-        mSyncTransactionQueue.runInSync(runnable);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index 179b725..1d8ac2b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -39,6 +39,7 @@
 import android.util.Slog;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
+import android.window.DisplayAreaInfo;
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.NonNull;
@@ -659,11 +660,11 @@
     }
 
     /**
-     * Handles rotation based on OnDisplayChangingListener callback
+     * Handles display change based on OnDisplayChangingListener callback
      */
     @Override
-    public void onRotateDisplay(int displayId, int fromRotation, int toRotation,
-            WindowContainerTransaction wct) {
+    public void onDisplayChange(int displayId, int fromRotation, int toRotation,
+            DisplayAreaInfo newDisplayAreaInfo, WindowContainerTransaction wct) {
         if (!isInitialized()) {
             return;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
index 3b3091a..bbc47e4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
@@ -86,12 +86,12 @@
     }
 
     /**
-     * Registers the pinned stack animation listener.
+     * Set the callback when {@link PipTaskOrganizer#isInPip()} state is changed.
      *
-     * @param callback The callback of pinned stack animation.
+     * @param callback The callback accepts the result of {@link PipTaskOrganizer#isInPip()}
+     *                 when it's changed.
      */
-    default void setPinnedStackAnimationListener(Consumer<Boolean> callback) {
-    }
+    default void setOnIsInPipStateChangedListener(Consumer<Boolean> callback) {}
 
     /**
      * Set the pinned stack with {@link PipAnimationController.AnimationType}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 4eba169..cf2734c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -591,7 +591,7 @@
                         final Rect insets = computeInsets(fraction);
                         getSurfaceTransactionHelper().scaleAndCrop(tx, leash,
                                 sourceHintRect, initialSourceValue, bounds, insets,
-                                isInPipDirection);
+                                isInPipDirection, fraction);
                         if (shouldApplyCornerRadius()) {
                             final Rect sourceBounds = new Rect(initialContainerRect);
                             sourceBounds.inset(insets);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
index a017a26..c0bc108 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
@@ -104,7 +104,7 @@
     public PipSurfaceTransactionHelper scaleAndCrop(SurfaceControl.Transaction tx,
             SurfaceControl leash, Rect sourceRectHint,
             Rect sourceBounds, Rect destinationBounds, Rect insets,
-            boolean isInPipDirection) {
+            boolean isInPipDirection, float fraction) {
         mTmpDestinationRect.set(sourceBounds);
         // Similar to {@link #scale}, we want to position the surface relative to the screen
         // coordinates so offset the bounds to 0,0
@@ -116,9 +116,13 @@
         if (isInPipDirection
                 && sourceRectHint != null && sourceRectHint.width() < sourceBounds.width()) {
             // scale by sourceRectHint if it's not edge-to-edge, for entering PiP transition only.
-            scale = sourceBounds.width() <= sourceBounds.height()
+            final float endScale = sourceBounds.width() <= sourceBounds.height()
                     ? (float) destinationBounds.width() / sourceRectHint.width()
                     : (float) destinationBounds.height() / sourceRectHint.height();
+            final float startScale = sourceBounds.width() <= sourceBounds.height()
+                    ? (float) destinationBounds.width() / sourceBounds.width()
+                    : (float) destinationBounds.height() / sourceBounds.height();
+            scale = (1 - fraction) * startScale + fraction * endScale;
         } else {
             scale = sourceBounds.width() <= sourceBounds.height()
                     ? (float) destinationBounds.width() / sourceBounds.width()
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 e624de6..22b0ccb 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
@@ -297,6 +297,10 @@
         displayController.addDisplayWindowListener(this);
     }
 
+    public PipTransitionController getTransitionController() {
+        return mPipTransitionController;
+    }
+
     public Rect getCurrentOrAnimatingBounds() {
         PipAnimationController.PipTransitionAnimator animator =
                 mPipAnimationController.getCurrentAnimator();
@@ -458,7 +462,8 @@
         }
 
         // Cancel the existing animator if there is any.
-        cancelCurrentAnimator();
+        // TODO(b/232439933): this is disabled temporarily to unblock b/234502692.
+        // cancelCurrentAnimator();
 
         // Set the exiting state first so if there is fixed rotation later, the running animation
         // won't be interrupted by alpha animation for existing PiP.
@@ -937,7 +942,7 @@
         // Re-set the PIP bounds to none.
         mPipBoundsState.setBounds(new Rect());
         mPipUiEventLoggerLogger.setTaskInfo(null);
-        mPipMenuController.detach();
+        mMainExecutor.executeDelayed(() -> mPipMenuController.detach(), 0);
 
         if (info.displayId != Display.DEFAULT_DISPLAY && mOnDisplayIdChangeCallback != null) {
             mOnDisplayIdChangeCallback.accept(Display.DEFAULT_DISPLAY);
@@ -1467,6 +1472,11 @@
                     "%s: Abort animation, invalid leash", TAG);
             return null;
         }
+        if (isInPipDirection(direction)
+                && !isSourceRectHintValidForEnterPip(sourceHintRect, destinationBounds)) {
+            // The given source rect hint is too small for enter PiP animation, reset it to null.
+            sourceHintRect = null;
+        }
         final int rotationDelta = mWaitForFixedRotation
                 ? deltaRotation(mCurrentRotation, mNextRotation)
                 : Surface.ROTATION_0;
@@ -1541,6 +1551,20 @@
     }
 
     /**
+     * This is a situation in which the source rect hint on at least one axis is smaller
+     * than the destination bounds, which represents a problem because we would have to scale
+     * up that axis to fit the bounds. So instead, just fallback to the non-source hint
+     * animation in this case.
+     *
+     * @return {@code false} if the given source is too small to use for the entering animation.
+     */
+    private boolean isSourceRectHintValidForEnterPip(Rect sourceRectHint, Rect destinationBounds) {
+        return sourceRectHint != null
+                && sourceRectHint.width() > destinationBounds.width()
+                && sourceRectHint.height() > destinationBounds.height();
+    }
+
+    /**
      * Sync with {@link SplitScreenController} on destination bounds if PiP is going to
      * split screen.
      *
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 36e7124..05a890f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -28,7 +28,6 @@
 import static android.view.WindowManager.TRANSIT_PIP;
 import static android.view.WindowManager.transitTypeToString;
 import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
-import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 
 import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_ALPHA;
 import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_BOUNDS;
@@ -43,6 +42,7 @@
 import static com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP;
 import static com.android.wm.shell.transition.Transitions.isOpeningType;
 
+import android.animation.Animator;
 import android.app.ActivityManager;
 import android.app.TaskInfo;
 import android.content.Context;
@@ -52,6 +52,7 @@
 import android.os.IBinder;
 import android.view.Surface;
 import android.view.SurfaceControl;
+import android.view.WindowManager;
 import android.window.TransitionInfo;
 import android.window.TransitionRequestInfo;
 import android.window.WindowContainerToken;
@@ -145,6 +146,11 @@
         if (destinationBounds != null) {
             mExitDestinationBounds.set(destinationBounds);
         }
+        final PipAnimationController.PipTransitionAnimator animator =
+                mPipAnimationController.getCurrentAnimator();
+        if (animator != null && animator.isRunning()) {
+            animator.cancel();
+        }
         mExitTransition = mTransitions.startTransition(type, out, this);
     }
 
@@ -217,13 +223,20 @@
         }
 
         // Entering PIP.
-        if (isEnteringPip(info, mCurrentPipTaskToken)) {
-            return startEnterAnimation(info, startTransaction, finishTransaction, finishCallback);
+        if (isEnteringPip(info)) {
+            startEnterAnimation(info, startTransaction, finishTransaction, finishCallback);
+            return true;
         }
 
         // For transition that we don't animate, but contains the PIP leash, we need to update the
         // PIP surface, otherwise it will be reset after the transition.
         if (currentPipTaskChange != null) {
+            // Set the "end" bounds of pip. The default setup uses the start bounds. Since this is
+            // changing the *finish*Transaction, we need to use the end bounds. This will also
+            // make sure that the fade-in animation (below) uses the end bounds as well.
+            if (!currentPipTaskChange.getEndAbsBounds().isEmpty()) {
+                mPipBoundsState.setBounds(currentPipTaskChange.getEndAbsBounds());
+            }
             updatePipForUnhandledTransition(currentPipTaskChange, startTransaction,
                     finishTransaction);
         }
@@ -236,6 +249,13 @@
         return false;
     }
 
+    @Override
+    public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        end();
+    }
+
     /** Helper to identify whether this handler is currently the one playing an animation */
     private boolean isAnimatingLocally() {
         return mFinishTransaction != null;
@@ -245,16 +265,9 @@
     @Override
     public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
             @NonNull TransitionRequestInfo request) {
-        if (request.getType() == TRANSIT_PIP) {
+        if (requestHasPipEnter(request)) {
             WindowContainerTransaction wct = new WindowContainerTransaction();
-            if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
-                mRequestedEnterTransition = transition;
-                mRequestedEnterTask = request.getTriggerTask().token;
-                wct.setActivityWindowingMode(request.getTriggerTask().token,
-                        WINDOWING_MODE_UNDEFINED);
-                final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
-                wct.setBounds(request.getTriggerTask().token, destinationBounds);
-            }
+            augmentRequest(transition, request, wct);
             return wct;
         } else {
             return null;
@@ -262,6 +275,29 @@
     }
 
     @Override
+    public void augmentRequest(@NonNull IBinder transition,
+            @NonNull TransitionRequestInfo request, @NonNull WindowContainerTransaction outWCT) {
+        if (!requestHasPipEnter(request)) {
+            throw new IllegalStateException("Called PiP augmentRequest when request has no PiP");
+        }
+        if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
+            mRequestedEnterTransition = transition;
+            mRequestedEnterTask = request.getTriggerTask().token;
+            outWCT.setActivityWindowingMode(request.getTriggerTask().token,
+                    WINDOWING_MODE_UNDEFINED);
+            final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
+            outWCT.setBounds(request.getTriggerTask().token, destinationBounds);
+        }
+    }
+
+    @Override
+    public void end() {
+        Animator animator = mPipAnimationController.getCurrentAnimator();
+        if (animator == null) return;
+        animator.end();
+    }
+
+    @Override
     public boolean handleRotateDisplay(int startRotation, int endRotation,
             WindowContainerTransaction wct) {
         if (mRequestedEnterTransition != null && mOneShotAnimationType == ANIM_TYPE_ALPHA) {
@@ -315,11 +351,27 @@
         // (likely a remote like launcher), so don't fire the finish-callback here -- wait until
         // the exit transition is merged.
         if ((mExitTransition == null || isAnimatingLocally()) && mFinishCallback != null) {
-            WindowContainerTransaction wct = new WindowContainerTransaction();
-            prepareFinishResizeTransaction(taskInfo, destinationBounds,
-                    direction, wct);
-            if (tx != null) {
-                wct.setBoundsChangeTransaction(taskInfo.token, tx);
+            WindowContainerTransaction wct = null;
+            if (isOutPipDirection(direction)) {
+                // Only need to reset surface properties. The server-side operations were already
+                // done at the start.
+                if (tx != null) {
+                    mFinishTransaction.merge(tx);
+                }
+            } else {
+                wct = new WindowContainerTransaction();
+                if (isInPipDirection(direction)) {
+                    // If we are animating from fullscreen using a bounds animation, then reset the
+                    // activity windowing mode, and set the task bounds to the final bounds
+                    wct.setActivityWindowingMode(taskInfo.token, WINDOWING_MODE_UNDEFINED);
+                    wct.scheduleFinishEnterPip(taskInfo.token, destinationBounds);
+                    wct.setBounds(taskInfo.token, destinationBounds);
+                } else {
+                    wct.setBounds(taskInfo.token, null /* bounds */);
+                }
+                if (tx != null) {
+                    wct.setBoundsChangeTransaction(taskInfo.token, tx);
+                }
             }
             final SurfaceControl leash = mPipOrganizer.getSurfaceControl();
             final int displayRotation = taskInfo.getConfiguration().windowConfiguration
@@ -559,92 +611,94 @@
     }
 
     /** Whether we should handle the given {@link TransitionInfo} animation as entering PIP. */
-    private static boolean isEnteringPip(@NonNull TransitionInfo info,
-            @Nullable WindowContainerToken currentPipTaskToken) {
+    private boolean isEnteringPip(@NonNull TransitionInfo info) {
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             final TransitionInfo.Change change = info.getChanges().get(i);
-            if (change.getTaskInfo() != null
-                    && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_PINNED
-                    && !change.getContainer().equals(currentPipTaskToken)) {
-                // We support TRANSIT_PIP type (from RootWindowContainer) or TRANSIT_OPEN (from apps
-                // that enter PiP instantly on opening, mostly from CTS/Flicker tests)
-                if (info.getType() == TRANSIT_PIP || info.getType() == TRANSIT_OPEN) {
-                    return true;
-                }
-                // This can happen if the request to enter PIP happens when we are collecting for
-                // another transition, such as TRANSIT_CHANGE (display rotation).
-                if (info.getType() == TRANSIT_CHANGE) {
-                    return true;
-                }
-
-                // Please file a bug to handle the unexpected transition type.
-                throw new IllegalStateException("Entering PIP with unexpected transition type="
-                        + transitTypeToString(info.getType()));
-            }
+            if (isEnteringPip(change, info.getType())) return true;
         }
         return false;
     }
 
-    private boolean startEnterAnimation(@NonNull TransitionInfo info,
+    /** Whether a particular change is a window that is entering pip. */
+    @Override
+    public boolean isEnteringPip(@NonNull TransitionInfo.Change change,
+            @WindowManager.TransitionType int transitType) {
+        if (change.getTaskInfo() != null
+                && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_PINNED
+                && !change.getContainer().equals(mCurrentPipTaskToken)) {
+            // We support TRANSIT_PIP type (from RootWindowContainer) or TRANSIT_OPEN (from apps
+            // that enter PiP instantly on opening, mostly from CTS/Flicker tests)
+            if (transitType == TRANSIT_PIP || transitType == TRANSIT_OPEN) {
+                return true;
+            }
+            // This can happen if the request to enter PIP happens when we are collecting for
+            // another transition, such as TRANSIT_CHANGE (display rotation).
+            if (transitType == TRANSIT_CHANGE) {
+                return true;
+            }
+
+            // Please file a bug to handle the unexpected transition type.
+            throw new IllegalStateException("Entering PIP with unexpected transition type="
+                    + transitTypeToString(transitType));
+        }
+        return false;
+    }
+
+    private void startEnterAnimation(@NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
-        // Search for an Enter PiP transition (along with a show wallpaper one)
+        // Search for an Enter PiP transition
         TransitionInfo.Change enterPip = null;
-        TransitionInfo.Change wallpaper = null;
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             final TransitionInfo.Change change = info.getChanges().get(i);
             if (change.getTaskInfo() != null
                     && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_PINNED) {
                 enterPip = change;
-            } else if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
-                wallpaper = change;
             }
         }
         if (enterPip == null) {
-            return false;
-        }
-        // Keep track of the PIP task.
-        mCurrentPipTaskToken = enterPip.getContainer();
-        mHasFadeOut = false;
-
-        if (mFinishCallback != null) {
-            callFinishCallback(null /* wct */);
-            mFinishTransaction = null;
-            throw new RuntimeException("Previous callback not called, aborting entering PIP.");
+            throw new IllegalStateException("Trying to start PiP animation without a pip"
+                    + "participant");
         }
 
-        // Show the wallpaper if there is a wallpaper change.
-        if (wallpaper != null) {
-            startTransaction.show(wallpaper.getLeash());
-            startTransaction.setAlpha(wallpaper.getLeash(), 1.f);
-        }
         // Make sure other open changes are visible as entering PIP. Some may be hidden in
         // Transitions#setupStartState because the transition type is OPEN (such as auto-enter).
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             final TransitionInfo.Change change = info.getChanges().get(i);
-            if (change == enterPip || change == wallpaper) {
-                continue;
-            }
+            if (change == enterPip) continue;
             if (isOpeningType(change.getMode())) {
                 final SurfaceControl leash = change.getLeash();
                 startTransaction.show(leash).setAlpha(leash, 1.f);
             }
         }
 
+        startEnterAnimation(enterPip, startTransaction, finishTransaction, finishCallback);
+    }
+
+    @Override
+    public void startEnterAnimation(@NonNull final TransitionInfo.Change pipChange,
+            @NonNull final SurfaceControl.Transaction startTransaction,
+            @NonNull final SurfaceControl.Transaction finishTransaction,
+            @NonNull final Transitions.TransitionFinishCallback finishCallback) {
+        if (mFinishCallback != null) {
+            callFinishCallback(null /* wct */);
+            mFinishTransaction = null;
+            throw new RuntimeException("Previous callback not called, aborting entering PIP.");
+        }
+
+        // Keep track of the PIP task and animation.
+        mCurrentPipTaskToken = pipChange.getContainer();
+        mHasFadeOut = false;
         mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
         mFinishCallback = finishCallback;
         mFinishTransaction = finishTransaction;
-        final int endRotation = mInFixedRotation ? mEndFixedRotation : enterPip.getEndRotation();
-        return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(),
-                startTransaction, finishTransaction, enterPip.getStartRotation(),
-                endRotation);
-    }
 
-    private boolean startEnterAnimation(final TaskInfo taskInfo, final SurfaceControl leash,
-            final SurfaceControl.Transaction startTransaction,
-            final SurfaceControl.Transaction finishTransaction,
-            final int startRotation, final int endRotation) {
+        final ActivityManager.RunningTaskInfo taskInfo = pipChange.getTaskInfo();
+        final SurfaceControl leash = pipChange.getLeash();
+        final int startRotation = pipChange.getStartRotation();
+        final int endRotation = mInFixedRotation ? mEndFixedRotation : pipChange.getEndRotation();
+
         setBoundsStateForEntry(taskInfo.topActivity, taskInfo.pictureInPictureParams,
                 taskInfo.topActivityInfo);
         final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
@@ -657,12 +711,11 @@
             computeEnterPipRotatedBounds(rotationDelta, startRotation, endRotation, taskInfo,
                     destinationBounds, sourceHintRect);
         }
-        PipAnimationController.PipTransitionAnimator animator;
         // Set corner radius for entering pip.
         mSurfaceTransactionHelper
                 .crop(finishTransaction, leash, destinationBounds)
                 .round(finishTransaction, leash, true /* applyCornerRadius */);
-        mPipMenuController.attach(leash);
+        mTransitions.getMainExecutor().executeDelayed(() -> mPipMenuController.attach(leash), 0);
 
         if (taskInfo.pictureInPictureParams != null
                 && taskInfo.pictureInPictureParams.isAutoEnterEnabled()
@@ -694,7 +747,7 @@
                         null /* callback */, false /* withStartDelay */);
             }
             mPipTransitionState.setInSwipePipToHomeTransition(false);
-            return true;
+            return;
         }
 
         if (rotationDelta != Surface.ROTATION_0) {
@@ -702,6 +755,12 @@
             tmpTransform.postRotate(rotationDelta);
             startTransaction.setMatrix(leash, tmpTransform, new float[9]);
         }
+        if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
+            startTransaction.setAlpha(leash, 0f);
+        }
+        startTransaction.apply();
+
+        PipAnimationController.PipTransitionAnimator animator;
         if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
             animator = mPipAnimationController.getAnimator(taskInfo, leash, currentBounds,
                     currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP,
@@ -712,7 +771,6 @@
                 animator.setColorContentOverlay(mContext);
             }
         } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
-            startTransaction.setAlpha(leash, 0f);
             animator = mPipAnimationController.getAnimator(taskInfo, leash, destinationBounds,
                     0f, 1f);
             mOneShotAnimationType = ANIM_TYPE_BOUNDS;
@@ -720,7 +778,6 @@
             throw new RuntimeException("Unrecognized animation type: "
                     + mOneShotAnimationType);
         }
-        startTransaction.apply();
         animator.setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
                 .setPipAnimationCallback(mPipAnimationCallback)
                 .setDuration(mEnterExitAnimationDuration);
@@ -731,8 +788,6 @@
             animator.setDestinationBounds(mPipBoundsAlgorithm.getEntryDestinationBounds());
         }
         animator.start();
-
-        return true;
     }
 
     /** Computes destination bounds in old rotation and updates source hint rect if available. */
@@ -852,27 +907,4 @@
         mPipMenuController.movePipMenu(null, null, destinationBounds);
         mPipMenuController.updateMenuBounds(destinationBounds);
     }
-
-    private void prepareFinishResizeTransaction(TaskInfo taskInfo, Rect destinationBounds,
-            @PipAnimationController.TransitionDirection int direction,
-            WindowContainerTransaction wct) {
-        Rect taskBounds = null;
-        if (isInPipDirection(direction)) {
-            // If we are animating from fullscreen using a bounds animation, then reset the
-            // activity windowing mode set by WM, and set the task bounds to the final bounds
-            taskBounds = destinationBounds;
-            wct.setActivityWindowingMode(taskInfo.token, WINDOWING_MODE_UNDEFINED);
-            wct.scheduleFinishEnterPip(taskInfo.token, destinationBounds);
-        } else if (isOutPipDirection(direction)) {
-            // If we are animating to fullscreen, then we need to reset the override bounds
-            // on the task to ensure that the task "matches" the parent's bounds.
-            taskBounds = (direction == TRANSITION_DIRECTION_LEAVE_PIP)
-                    ? null : destinationBounds;
-            wct.setWindowingMode(taskInfo.token, getOutPipWindowingMode());
-            // Simply reset the activity mode set prior to the animation running.
-            wct.setActivityWindowingMode(taskInfo.token, WINDOWING_MODE_UNDEFINED);
-        }
-
-        wct.setBounds(taskInfo.token, taskBounds);
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index 54f46e0..90a2695 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -17,6 +17,7 @@
 package com.android.wm.shell.pip;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.view.WindowManager.TRANSIT_PIP;
 
 import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_REMOVE_STACK;
 import static com.android.wm.shell.pip.PipAnimationController.isInPipDirection;
@@ -27,11 +28,15 @@
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
 import android.graphics.Rect;
-import android.os.Handler;
-import android.os.Looper;
+import android.os.IBinder;
 import android.view.SurfaceControl;
+import android.view.WindowManager;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
 import android.window.WindowContainerTransaction;
 
+import androidx.annotation.NonNull;
+
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.transition.Transitions;
 
@@ -49,7 +54,6 @@
     protected final ShellTaskOrganizer mShellTaskOrganizer;
     protected final PipMenuController mPipMenuController;
     protected final Transitions mTransitions;
-    private final Handler mMainHandler;
     private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
     protected PipTaskOrganizer mPipOrganizer;
 
@@ -137,7 +141,6 @@
         mPipBoundsAlgorithm = pipBoundsAlgorithm;
         mPipAnimationController = pipAnimationController;
         mTransitions = transitions;
-        mMainHandler = new Handler(Looper.getMainLooper());
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
             transitions.addHandler(this);
         }
@@ -206,6 +209,34 @@
         return false;
     }
 
+    /** @return whether the transition-request represents a pip-entry. */
+    public boolean requestHasPipEnter(@NonNull TransitionRequestInfo request) {
+        return request.getType() == TRANSIT_PIP;
+    }
+
+    /** Whether a particular change is a window that is entering pip. */
+    public boolean isEnteringPip(@NonNull TransitionInfo.Change change,
+            @WindowManager.TransitionType int transitType) {
+        return false;
+    }
+
+    /** Add PiP-related changes to `outWCT` for the given request. */
+    public void augmentRequest(@NonNull IBinder transition,
+            @NonNull TransitionRequestInfo request, @NonNull WindowContainerTransaction outWCT) {
+        throw new IllegalStateException("Request isn't entering PiP");
+    }
+
+    /** Play a transition animation for entering PiP on a specific PiP change. */
+    public void startEnterAnimation(@NonNull final TransitionInfo.Change pipChange,
+            @NonNull final SurfaceControl.Transaction startTransaction,
+            @NonNull final SurfaceControl.Transaction finishTransaction,
+            @NonNull final Transitions.TransitionFinishCallback finishCallback) {
+    }
+
+    /** End the currently-playing PiP animation. */
+    public void end() {
+    }
+
     /**
      * Callback interface for PiP transitions (both from and to PiP mode)
      */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionState.java
index 85e56b7..1a4be3b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionState.java
@@ -17,12 +17,15 @@
 package com.android.wm.shell.pip;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.app.PictureInPictureParams;
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Used to keep track of PiP leash state as it appears and animates by {@link PipTaskOrganizer} and
@@ -37,6 +40,9 @@
     public static final int ENTERED_PIP = 4;
     public static final int EXITING_PIP = 5;
 
+    private final List<OnPipTransitionStateChangedListener> mOnPipTransitionStateChangedListeners =
+            new ArrayList<>();
+
     /**
      * If set to {@code true}, no entering PiP transition would be kicked off and most likely
      * it's due to the fact that Launcher is handling the transition directly when swiping
@@ -65,7 +71,13 @@
     }
 
     public void setTransitionState(@TransitionState int state) {
-        mState = state;
+        if (mState != state) {
+            for (int i = 0; i < mOnPipTransitionStateChangedListeners.size(); i++) {
+                mOnPipTransitionStateChangedListeners.get(i).onPipTransitionStateChanged(
+                        mState, state);
+            }
+            mState = state;
+        }
     }
 
     public @TransitionState int getTransitionState() {
@@ -73,8 +85,7 @@
     }
 
     public boolean isInPip() {
-        return mState >= TASK_APPEARED
-                && mState != EXITING_PIP;
+        return isInPip(mState);
     }
 
     public void setInSwipePipToHomeTransition(boolean inSwipePipToHomeTransition) {
@@ -94,4 +105,23 @@
         return mState < ENTERING_PIP
                 || mState == EXITING_PIP;
     }
+
+    public void addOnPipTransitionStateChangedListener(
+            @NonNull OnPipTransitionStateChangedListener listener) {
+        mOnPipTransitionStateChangedListeners.add(listener);
+    }
+
+    public void removeOnPipTransitionStateChangedListener(
+            @NonNull OnPipTransitionStateChangedListener listener) {
+        mOnPipTransitionStateChangedListeners.remove(listener);
+    }
+
+    public static boolean isInPip(@TransitionState int state) {
+        return state >= TASK_APPEARED && state != EXITING_PIP;
+    }
+
+    public interface OnPipTransitionStateChangedListener {
+        void onPipTransitionStateChanged(@TransitionState int oldState,
+                @TransitionState int newState);
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 4b1e5f8..3000998 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -84,6 +84,7 @@
 import com.android.wm.shell.pip.PipSnapAlgorithm;
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipTransitionController;
+import com.android.wm.shell.pip.PipTransitionState;
 import com.android.wm.shell.pip.PipUtils;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.transition.Transitions;
@@ -110,7 +111,9 @@
     private PipAppOpsListener mAppOpsListener;
     private PipMediaController mMediaController;
     private PipBoundsAlgorithm mPipBoundsAlgorithm;
+    private PipKeepClearAlgorithm mPipKeepClearAlgorithm;
     private PipBoundsState mPipBoundsState;
+    private PipMotionHelper mPipMotionHelper;
     private PipTouchHandler mTouchHandler;
     private PipTransitionController mPipTransitionController;
     private TaskStackListenerImpl mTaskStackListener;
@@ -126,11 +129,14 @@
 
     protected PhonePipMenuController mMenuController;
     protected PipTaskOrganizer mPipTaskOrganizer;
+    private PipTransitionState mPipTransitionState;
     protected PinnedStackListenerForwarder.PinnedTaskListener mPinnedTaskListener =
             new PipControllerPinnedTaskListener();
 
     private boolean mIsKeyguardShowingOrAnimating;
 
+    private Consumer<Boolean> mOnIsInPipStateChangedListener;
+
     private interface PipAnimationListener {
         /**
          * Notifies the listener that the Pip animation is started.
@@ -156,7 +162,7 @@
      * Handler for display rotation changes.
      */
     private final DisplayChangeController.OnDisplayChangingListener mRotationController = (
-            int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> {
+            displayId, fromRotation, toRotation, newDisplayAreaInfo, t) -> {
         if (mPipTransitionController.handleRotateDisplay(fromRotation, toRotation, t)) {
             return;
         }
@@ -286,8 +292,10 @@
     @Nullable
     public static Pip create(Context context, DisplayController displayController,
             PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
-            PipBoundsState pipBoundsState, PipMediaController pipMediaController,
+            PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState,
+            PipMotionHelper pipMotionHelper, PipMediaController pipMediaController,
             PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
+            PipTransitionState pipTransitionState,
             PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
             WindowManagerShellWrapper windowManagerShellWrapper,
             TaskStackListenerImpl taskStackListener,
@@ -301,8 +309,9 @@
         }
 
         return new PipController(context, displayController, pipAppOpsListener, pipBoundsAlgorithm,
-                pipBoundsState, pipMediaController,
-                phonePipMenuController, pipTaskOrganizer, pipTouchHandler, pipTransitionController,
+                pipKeepClearAlgorithm, pipBoundsState, pipMotionHelper, pipMediaController,
+                phonePipMenuController, pipTaskOrganizer, pipTransitionState,
+                pipTouchHandler, pipTransitionController,
                 windowManagerShellWrapper, taskStackListener, pipParamsChangedForwarder,
                 oneHandedController, mainExecutor)
                 .mImpl;
@@ -312,10 +321,13 @@
             DisplayController displayController,
             PipAppOpsListener pipAppOpsListener,
             PipBoundsAlgorithm pipBoundsAlgorithm,
+            PipKeepClearAlgorithm pipKeepClearAlgorithm,
             @NonNull PipBoundsState pipBoundsState,
+            PipMotionHelper pipMotionHelper,
             PipMediaController pipMediaController,
             PhonePipMenuController phonePipMenuController,
             PipTaskOrganizer pipTaskOrganizer,
+            PipTransitionState pipTransitionState,
             PipTouchHandler pipTouchHandler,
             PipTransitionController pipTransitionController,
             WindowManagerShellWrapper windowManagerShellWrapper,
@@ -335,8 +347,11 @@
         mWindowManagerShellWrapper = windowManagerShellWrapper;
         mDisplayController = displayController;
         mPipBoundsAlgorithm = pipBoundsAlgorithm;
+        mPipKeepClearAlgorithm = pipKeepClearAlgorithm;
         mPipBoundsState = pipBoundsState;
+        mPipMotionHelper = pipMotionHelper;
         mPipTaskOrganizer = pipTaskOrganizer;
+        mPipTransitionState = pipTransitionState;
         mMainExecutor = mainExecutor;
         mMediaController = pipMediaController;
         mMenuController = phonePipMenuController;
@@ -363,6 +378,15 @@
             onDisplayChanged(mDisplayController.getDisplayLayout(displayId),
                     false /* saveRestoreSnapFraction */);
         });
+        mPipTransitionState.addOnPipTransitionStateChangedListener((oldState, newState) -> {
+            if (mOnIsInPipStateChangedListener != null) {
+                final boolean wasInPip = PipTransitionState.isInPip(oldState);
+                final boolean nowInPip = PipTransitionState.isInPip(newState);
+                if (nowInPip != wasInPip) {
+                    mOnIsInPipStateChangedListener.accept(nowInPip);
+                }
+            }
+        });
         mPipBoundsState.setOnMinimalSizeChangeCallback(
                 () -> {
                     // The minimal size drives the normal bounds, so they need to be recalculated.
@@ -657,6 +681,13 @@
         }
     }
 
+    private void setOnIsInPipStateChangedListener(Consumer<Boolean> callback) {
+        mOnIsInPipStateChangedListener = callback;
+        if (mOnIsInPipStateChangedListener != null) {
+            callback.accept(mPipTransitionState.isInPip());
+        }
+    }
+
     private void setShelfHeightLocked(boolean visible, int height) {
         final int shelfHeight = visible ? height : 0;
         mPipBoundsState.setShelfVisibility(visible, shelfHeight);
@@ -934,6 +965,13 @@
         }
 
         @Override
+        public void setOnIsInPipStateChangedListener(Consumer<Boolean> callback) {
+            mMainExecutor.execute(() -> {
+                PipController.this.setOnIsInPipStateChangedListener(callback);
+            });
+        }
+
+        @Override
         public void setPinnedStackAnimationType(int animationType) {
             mMainExecutor.execute(() -> {
                 PipController.this.setPinnedStackAnimationType(animationType);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithm.java
new file mode 100644
index 0000000..78084fa
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithm.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip.phone;
+
+import android.graphics.Rect;
+import android.util.ArraySet;
+
+import com.android.wm.shell.pip.PipBoundsAlgorithm;
+import com.android.wm.shell.pip.PipBoundsState;
+
+import java.util.Set;
+
+/**
+ * Calculates the adjusted position that does not occlude keep clear areas.
+ */
+public class PipKeepClearAlgorithm {
+
+    /**
+     * Adjusts the current position of PiP to avoid occluding keep clear areas. If the user has
+     * moved PiP manually, the unmodified current position will be returned instead.
+     */
+    public Rect adjust(PipBoundsState boundsState, PipBoundsAlgorithm boundsAlgorithm) {
+        if (boundsState.hasUserResizedPip()) {
+            return boundsState.getBounds();
+        }
+        return adjust(boundsAlgorithm.getEntryDestinationBounds(),
+                boundsState.getRestrictedKeepClearAreas(),
+                boundsState.getUnrestrictedKeepClearAreas(), boundsState.getDisplayBounds());
+    }
+
+    /** Returns a new {@code Rect} that does not occlude the provided keep clear areas. */
+    public Rect adjust(Rect defaultBounds, Set<Rect> restrictedKeepClearAreas,
+            Set<Rect> unrestrictedKeepClearAreas, Rect displayBounds) {
+        if (restrictedKeepClearAreas.isEmpty()) {
+            return defaultBounds;
+        }
+        Set<Rect> keepClearAreas = new ArraySet<>();
+        if (!restrictedKeepClearAreas.isEmpty()) {
+            keepClearAreas.addAll(restrictedKeepClearAreas);
+        }
+        Rect outBounds = new Rect(defaultBounds);
+        for (Rect r : keepClearAreas) {
+            if (Rect.intersects(r, outBounds)) {
+                if (tryOffsetUp(outBounds, r, displayBounds)) continue;
+                if (tryOffsetLeft(outBounds, r, displayBounds)) continue;
+                if (tryOffsetDown(outBounds, r, displayBounds)) continue;
+                if (tryOffsetRight(outBounds, r, displayBounds)) continue;
+            }
+        }
+        return outBounds;
+    }
+
+    private boolean tryOffsetLeft(Rect rectToMove, Rect rectToAvoid, Rect displayBounds) {
+        return tryOffset(rectToMove, rectToAvoid, displayBounds,
+                rectToAvoid.left - rectToMove.right, 0);
+    }
+
+    private boolean tryOffsetRight(Rect rectToMove, Rect rectToAvoid, Rect displayBounds) {
+        return tryOffset(rectToMove, rectToAvoid, displayBounds,
+                rectToAvoid.right - rectToMove.left, 0);
+    }
+
+    private boolean tryOffsetUp(Rect rectToMove, Rect rectToAvoid, Rect displayBounds) {
+        return tryOffset(rectToMove, rectToAvoid, displayBounds,
+                0, rectToAvoid.top - rectToMove.bottom);
+    }
+
+    private boolean tryOffsetDown(Rect rectToMove, Rect rectToAvoid, Rect displayBounds) {
+        return tryOffset(rectToMove, rectToAvoid, displayBounds,
+                0, rectToAvoid.bottom - rectToMove.top);
+    }
+
+    private boolean tryOffset(Rect rectToMove, Rect rectToAvoid, Rect displayBounds,
+            int dx, int dy) {
+        Rect tmp = new Rect(rectToMove);
+        tmp.offset(dx, dy);
+        if (!Rect.intersects(rectToAvoid, tmp) && displayBounds.contains(tmp)) {
+            rectToMove.offsetTo(tmp.left, tmp.top);
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 6390c89..1958157 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -282,7 +282,7 @@
                 && mSplitScreenControllerOptional.get().isTaskInSplitScreen(taskInfo.taskId);
         mFocusedTaskAllowSplitScreen = isSplitScreen
                 || (taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
-                && taskInfo.supportsSplitScreenMultiWindow
+                && taskInfo.supportsMultiWindow
                 && taskInfo.topActivityType != WindowConfiguration.ACTIVITY_TYPE_HOME);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index ac7b9033b..a2ff972 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -54,6 +54,7 @@
 import com.android.wm.shell.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.pip.PipBoundsState;
 import com.android.wm.shell.pip.PipTaskOrganizer;
+import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.pip.PipUiEventLogger;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
@@ -250,6 +251,10 @@
                 });
     }
 
+    public PipTransitionController getTransitionHandler() {
+        return mPipTaskOrganizer.getTransitionController();
+    }
+
     private void reloadResources() {
         final Resources res = mContext.getResources();
         mBottomOffsetBufferPx = res.getDimensionPixelSize(R.dimen.pip_bottom_offset_buffer);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index c166178..0f7a4da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -44,7 +44,7 @@
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.util.GroupedRecentTaskInfo;
-import com.android.wm.shell.util.StagedSplitBounds;
+import com.android.wm.shell.util.SplitBounds;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -69,12 +69,12 @@
     // pair, then mSplitTasks[t1] = t2, and mSplitTasks[t2] = t1)
     private final SparseIntArray mSplitTasks = new SparseIntArray();
     /**
-     * Maps taskId to {@link StagedSplitBounds} for both taskIDs.
+     * Maps taskId to {@link SplitBounds} for both taskIDs.
      * Meaning there will be two taskId integers mapping to the same object.
      * If there's any ordering to the pairing than we can probably just get away with only one
      * taskID mapping to it, leaving both for consistency with {@link #mSplitTasks} for now.
      */
-    private final Map<Integer, StagedSplitBounds> mTaskSplitBoundsMap = new HashMap<>();
+    private final Map<Integer, SplitBounds> mTaskSplitBoundsMap = new HashMap<>();
 
     /**
      * Creates {@link RecentTasksController}, returns {@code null} if the feature is not
@@ -110,7 +110,7 @@
     /**
      * Adds a split pair. This call does not validate the taskIds, only that they are not the same.
      */
-    public void addSplitPair(int taskId1, int taskId2, StagedSplitBounds splitBounds) {
+    public void addSplitPair(int taskId1, int taskId2, SplitBounds splitBounds) {
         if (taskId1 == taskId2) {
             return;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
index ae5e075c..2bfa5db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.splitscreen;
 
-import android.annotation.Nullable;
 import android.content.Context;
 import android.view.SurfaceSession;
 import android.window.WindowContainerToken;
@@ -38,10 +37,9 @@
 
     MainStage(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
             StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
-            SurfaceSession surfaceSession, IconProvider iconProvider,
-            @Nullable StageTaskUnfoldController stageTaskUnfoldController) {
-        super(context, taskOrganizer, displayId, callbacks, syncQueue, surfaceSession, iconProvider,
-                stageTaskUnfoldController);
+            SurfaceSession surfaceSession, IconProvider iconProvider) {
+        super(context, taskOrganizer, displayId, callbacks, syncQueue, surfaceSession,
+                iconProvider);
     }
 
     boolean isActive() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
index d55619f..f92a0d3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SideStage.java
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.splitscreen;
 
-import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.view.SurfaceSession;
@@ -38,10 +37,9 @@
 
     SideStage(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
             StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
-            SurfaceSession surfaceSession, IconProvider iconProvider,
-            @Nullable StageTaskUnfoldController stageTaskUnfoldController) {
-        super(context, taskOrganizer, displayId, callbacks, syncQueue, surfaceSession, iconProvider,
-                stageTaskUnfoldController);
+            SurfaceSession surfaceSession, IconProvider iconProvider) {
+        super(context, taskOrganizer, displayId, callbacks, syncQueue, surfaceSession,
+                iconProvider);
     }
 
     boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index 448773a..29b6311 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.graphics.Rect;
 
 import com.android.wm.shell.common.annotations.ExternalThread;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
@@ -58,6 +59,7 @@
     interface SplitScreenListener {
         default void onStagePositionChanged(@StageType int stage, @SplitPosition int position) {}
         default void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) {}
+        default void onSplitBoundsChanged(Rect rootBounds, Rect mainBounds, Rect sideBounds) {}
         default void onSplitVisibilityChanged(boolean visible) {}
     }
 
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 31b510c..ee49366 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
@@ -83,11 +83,10 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.concurrent.Executor;
 
-import javax.inject.Provider;
-
 /**
  * Class manages split-screen multitasking mode and implements the main interface
  * {@link SplitScreen}.
@@ -108,7 +107,7 @@
     static final int EXIT_REASON_ROOT_TASK_VANISHED = 6;
     static final int EXIT_REASON_SCREEN_LOCKED = 7;
     static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8;
-    static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9;
+    public static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9;
     @IntDef(value = {
             EXIT_REASON_UNKNOWN,
             EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW,
@@ -138,7 +137,6 @@
     private final SplitscreenEventLogger mLogger;
     private final IconProvider mIconProvider;
     private final Optional<RecentTasksController> mRecentTasksOptional;
-    private final Provider<Optional<StageTaskUnfoldController>> mUnfoldControllerProvider;
 
     private StageCoordinator mStageCoordinator;
     // Only used for the legacy recents animation from splitscreen to allow the tasks to be animated
@@ -152,8 +150,7 @@
             DisplayImeController displayImeController,
             DisplayInsetsController displayInsetsController,
             Transitions transitions, TransactionPool transactionPool, IconProvider iconProvider,
-            Optional<RecentTasksController> recentTasks,
-            Provider<Optional<StageTaskUnfoldController>> unfoldControllerProvider) {
+            Optional<RecentTasksController> recentTasks) {
         mTaskOrganizer = shellTaskOrganizer;
         mSyncQueue = syncQueue;
         mContext = context;
@@ -164,7 +161,6 @@
         mDisplayInsetsController = displayInsetsController;
         mTransitions = transitions;
         mTransactionPool = transactionPool;
-        mUnfoldControllerProvider = unfoldControllerProvider;
         mLogger = new SplitscreenEventLogger();
         mIconProvider = iconProvider;
         mRecentTasksOptional = recentTasks;
@@ -190,7 +186,7 @@
             mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
                     mTaskOrganizer, mDisplayController, mDisplayImeController,
                     mDisplayInsetsController, mTransitions, mTransactionPool, mLogger,
-                    mIconProvider, mMainExecutor, mRecentTasksOptional, mUnfoldControllerProvider);
+                    mIconProvider, mMainExecutor, mRecentTasksOptional);
         }
     }
 
@@ -198,6 +194,10 @@
         return mStageCoordinator.isSplitScreenVisible();
     }
 
+    public StageCoordinator getTransitionHandler() {
+        return mStageCoordinator;
+    }
+
     @Nullable
     public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) {
         if (!isSplitScreenVisible() || splitPosition == SPLIT_POSITION_UNDEFINED) {
@@ -222,6 +222,14 @@
                 new WindowContainerTransaction());
     }
 
+    /**
+     * Update surfaces of the split screen layout based on the current state
+     * @param transaction to write the updates to
+     */
+    public void updateSplitScreenSurfaces(SurfaceControl.Transaction transaction) {
+        mStageCoordinator.updateSurfaces(transaction);
+    }
+
     private boolean moveToStage(int taskId, @StageType int stageType,
             @SplitPosition int stagePosition, WindowContainerTransaction wct) {
         final ActivityManager.RunningTaskInfo task = mTaskOrganizer.getRunningTaskInfo(taskId);
@@ -362,11 +370,12 @@
                 if (apps == null || apps.length == 0) {
                     final ActivityManager.RunningTaskInfo pairedTaskInfo =
                             getTaskInfo(SplitLayout.reversePosition(position));
-                    final ComponentName pairedActivity =
-                            pairedTaskInfo != null ? pairedTaskInfo.baseActivity : null;
-                    final ComponentName intentActivity =
-                            intent.getIntent() != null ? intent.getIntent().getComponent() : null;
-                    if (pairedActivity != null && pairedActivity.equals(intentActivity)) {
+                    final ComponentName pairedActivity = pairedTaskInfo != null
+                            ? pairedTaskInfo.baseIntent.getComponent() : null;
+                    final ComponentName intentActivity = intent.getIntent() != null
+                            ? intent.getIntent().getComponent() : null;
+
+                    if (Objects.equals(pairedActivity, intentActivity)) {
                         // Switch split position if dragging the same activity to another side.
                         setSideStagePosition(SplitLayout.reversePosition(
                                 mStageCoordinator.getSideStagePosition()));
@@ -535,6 +544,17 @@
             }
 
             @Override
+            public void onSplitBoundsChanged(Rect rootBounds, Rect mainBounds, Rect sideBounds) {
+                for (int i = 0; i < mExecutors.size(); i++) {
+                    final int index = i;
+                    mExecutors.valueAt(index).execute(() -> {
+                        mExecutors.keyAt(index).onSplitBoundsChanged(rootBounds, mainBounds,
+                                sideBounds);
+                    });
+                }
+            }
+
+            @Override
             public void onSplitVisibilityChanged(boolean visible) {
                 for (int i = 0; i < mExecutors.size(); i++) {
                     final int index = i;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index cd121ed..e55729a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -21,7 +21,6 @@
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
-import static android.window.TransitionInfo.FLAG_FIRST_CUSTOM;
 
 import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
@@ -58,9 +57,6 @@
 class SplitScreenTransitions {
     private static final String TAG = "SplitScreenTransitions";
 
-    /** Flag applied to a transition change to identify it as a divider bar for animation. */
-    public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM;
-
     private final TransactionPool mTransactionPool;
     private final Transitions mTransitions;
     private final Runnable mOnFinish;
@@ -70,8 +66,9 @@
     IBinder mPendingRecent = null;
 
     private IBinder mAnimatingTransition = null;
-    private OneShotRemoteHandler mPendingRemoteHandler = null;
+    OneShotRemoteHandler mPendingRemoteHandler = null;
     private OneShotRemoteHandler mActiveRemoteHandler = null;
+    private boolean mEnterTransitionMerged;
 
     private final Transitions.TransitionFinishCallback mRemoteFinishCB = this::onFinish;
 
@@ -94,7 +91,8 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback,
-            @NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot) {
+            @NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot,
+            @NonNull WindowContainerToken topRoot) {
         mFinishCallback = finishCallback;
         mAnimatingTransition = transition;
         if (mPendingRemoteHandler != null) {
@@ -104,12 +102,12 @@
             mPendingRemoteHandler = null;
             return;
         }
-        playInternalAnimation(transition, info, startTransaction, mainRoot, sideRoot);
+        playInternalAnimation(transition, info, startTransaction, mainRoot, sideRoot, topRoot);
     }
 
     private void playInternalAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction t, @NonNull WindowContainerToken mainRoot,
-            @NonNull WindowContainerToken sideRoot) {
+            @NonNull WindowContainerToken sideRoot, @NonNull WindowContainerToken topRoot) {
         mFinishTransaction = mTransactionPool.acquire();
 
         // Play some place-holder fade animations
@@ -140,7 +138,10 @@
                 endBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y);
                 startExampleResizeAnimation(leash, startBounds, endBounds);
             }
-            if (change.getParent() != null) {
+            boolean isRootOrSplitSideRoot = change.getParent() == null
+                    || topRoot.equals(change.getParent());
+            // For enter or exit, we only want to animate the side roots but not the top-root.
+            if (!isRootOrSplitSideRoot || topRoot.equals(change.getContainer())) {
                 continue;
             }
 
@@ -187,27 +188,28 @@
     }
 
     /** Starts a transition to dismiss split. */
-    IBinder startDismissTransition(@Nullable IBinder transition, WindowContainerTransaction wct,
+    IBinder startDismissTransition(WindowContainerTransaction wct,
             Transitions.TransitionHandler handler, @SplitScreen.StageType int dismissTop,
             @SplitScreenController.ExitReason int reason) {
         final int type = reason == EXIT_REASON_DRAG_DIVIDER
                 ? TRANSIT_SPLIT_DISMISS_SNAP : TRANSIT_SPLIT_DISMISS;
-        if (transition == null) {
-            transition = mTransitions.startTransition(type, wct, handler);
-        }
+        IBinder transition = mTransitions.startTransition(type, wct, handler);
+        setDismissTransition(transition, dismissTop, reason);
+        return transition;
+    }
+
+    /** Sets a transition to dismiss split. */
+    void setDismissTransition(@NonNull IBinder transition, @SplitScreen.StageType int dismissTop,
+            @SplitScreenController.ExitReason int reason) {
         mPendingDismiss = new DismissTransition(transition, reason, dismissTop);
 
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  splitTransition "
                         + " deduced Dismiss due to %s. toTop=%s",
                 exitReasonToString(reason), stageTypeToString(dismissTop));
-        return transition;
     }
 
-    IBinder startRecentTransition(@Nullable IBinder transition, WindowContainerTransaction wct,
-            Transitions.TransitionHandler handler, @Nullable RemoteTransition remoteTransition) {
-        if (transition == null) {
-            transition = mTransitions.startTransition(TRANSIT_OPEN, wct, handler);
-        }
+    void setRecentTransition(@NonNull IBinder transition,
+            @Nullable RemoteTransition remoteTransition) {
         mPendingRecent = transition;
 
         if (remoteTransition != null) {
@@ -219,13 +221,40 @@
 
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  splitTransition "
                         + " deduced Enter recent panel");
-        return transition;
     }
 
     void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t,
             IBinder mergeTarget, Transitions.TransitionFinishCallback finishCallback) {
-        if (mergeTarget == mAnimatingTransition && mActiveRemoteHandler != null) {
+        if (mergeTarget != mAnimatingTransition) return;
+        if (mActiveRemoteHandler != null) {
             mActiveRemoteHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
+        } else {
+            for (int i = mAnimations.size() - 1; i >= 0; --i) {
+                final Animator anim = mAnimations.get(i);
+                mTransitions.getAnimExecutor().execute(anim::end);
+            }
+        }
+    }
+
+    boolean end() {
+        // If its remote, there's nothing we can do right now.
+        if (mActiveRemoteHandler != null) return false;
+        for (int i = mAnimations.size() - 1; i >= 0; --i) {
+            final Animator anim = mAnimations.get(i);
+            mTransitions.getAnimExecutor().execute(anim::end);
+        }
+        return true;
+    }
+
+    void onTransitionMerged(@NonNull IBinder transition) {
+        // Once a pending enter transition got merged, make sure to append the reset of finishing
+        // operations to the finish transition.
+        if (transition == mPendingEnter) {
+            mFinishTransaction = mTransactionPool.acquire();
+            mStageCoordinator.finishEnterSplitScreen(mFinishTransaction);
+            mPendingEnter = null;
+            mPendingRemoteHandler = null;
+            mEnterTransitionMerged = true;
         }
     }
 
@@ -238,18 +267,16 @@
             mPendingDismiss = null;
         }
         if (mAnimatingTransition == mPendingRecent) {
-            // If the clean-up wct is null when finishing recent transition, it indicates it's
-            // returning to home and thus no need to reorder tasks.
-            final boolean returnToHome = wct == null;
-            if (returnToHome) {
-                wct = new WindowContainerTransaction();
+            if (!mEnterTransitionMerged) {
+                if (wct == null) wct = new WindowContainerTransaction();
+                mStageCoordinator.onRecentTransitionFinished(wct, mFinishTransaction);
             }
-            mStageCoordinator.onRecentTransitionFinished(returnToHome, wct, mFinishTransaction);
             mPendingRecent = null;
         }
         mPendingRemoteHandler = null;
         mActiveRemoteHandler = null;
         mAnimatingTransition = null;
+        mEnterTransitionMerged = false;
 
         mOnFinish.run();
         if (mFinishTransaction != null) {
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 30f316e..59b0afe 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
@@ -18,6 +18,8 @@
 
 import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED;
+import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -28,7 +30,9 @@
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
 import static android.view.WindowManager.transitTypeToString;
+import static android.window.TransitionInfo.FLAG_FIRST_CUSTOM;
 import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
 
 import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -47,7 +51,6 @@
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_UNKNOWN;
 import static com.android.wm.shell.splitscreen.SplitScreenController.exitReasonToString;
-import static com.android.wm.shell.splitscreen.SplitScreenTransitions.FLAG_IS_DIVIDER_BAR;
 import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
 import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE;
 import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
@@ -84,6 +87,7 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 import android.view.WindowManager;
+import android.window.DisplayAreaInfo;
 import android.window.RemoteTransition;
 import android.window.TransitionInfo;
 import android.window.TransitionRequestInfo;
@@ -110,15 +114,13 @@
 import com.android.wm.shell.splitscreen.SplitScreen.StageType;
 import com.android.wm.shell.splitscreen.SplitScreenController.ExitReason;
 import com.android.wm.shell.transition.Transitions;
-import com.android.wm.shell.util.StagedSplitBounds;
+import com.android.wm.shell.util.SplitBounds;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
 
-import javax.inject.Provider;
-
 /**
  * Coordinates the staging (visibility, sizing, ...) of the split-screen {@link MainStage} and
  * {@link SideStage} stages.
@@ -132,20 +134,21 @@
  * This rules are mostly implemented in {@link #onStageVisibilityChanged(StageListenerImpl)} and
  * {@link #onStageHasChildrenChanged(StageListenerImpl).}
  */
-class StageCoordinator implements SplitLayout.SplitLayoutHandler,
+public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
         DisplayController.OnDisplaysChangedListener, Transitions.TransitionHandler,
         ShellTaskOrganizer.TaskListener {
 
     private static final String TAG = StageCoordinator.class.getSimpleName();
 
+    /** Flag applied to a transition change to identify it as a divider bar for animation. */
+    public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM;
+
     private final SurfaceSession mSurfaceSession = new SurfaceSession();
 
     private final MainStage mMainStage;
     private final StageListenerImpl mMainStageListener = new StageListenerImpl();
-    private final StageTaskUnfoldController mMainUnfoldController;
     private final SideStage mSideStage;
     private final StageListenerImpl mSideStageListener = new StageListenerImpl();
-    private final StageTaskUnfoldController mSideUnfoldController;
     private final DisplayLayout mDisplayLayout;
     @SplitPosition
     private int mSideStagePosition = SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -206,8 +209,7 @@
             DisplayInsetsController displayInsetsController, Transitions transitions,
             TransactionPool transactionPool, SplitscreenEventLogger logger,
             IconProvider iconProvider, ShellExecutor mainExecutor,
-            Optional<RecentTasksController> recentTasks,
-            Provider<Optional<StageTaskUnfoldController>> unfoldControllerProvider) {
+            Optional<RecentTasksController> recentTasks) {
         mContext = context;
         mDisplayId = displayId;
         mSyncQueue = syncQueue;
@@ -215,8 +217,7 @@
         mLogger = logger;
         mMainExecutor = mainExecutor;
         mRecentTasks = recentTasks;
-        mMainUnfoldController = unfoldControllerProvider.get().orElse(null);
-        mSideUnfoldController = unfoldControllerProvider.get().orElse(null);
+
         taskOrganizer.createRootTask(displayId, WINDOWING_MODE_FULLSCREEN, this /* listener */);
 
         mMainStage = new MainStage(
@@ -226,8 +227,7 @@
                 mMainStageListener,
                 mSyncQueue,
                 mSurfaceSession,
-                iconProvider,
-                mMainUnfoldController);
+                iconProvider);
         mSideStage = new SideStage(
                 mContext,
                 mTaskOrganizer,
@@ -235,8 +235,7 @@
                 mSideStageListener,
                 mSyncQueue,
                 mSurfaceSession,
-                iconProvider,
-                mSideUnfoldController);
+                iconProvider);
         mDisplayController = displayController;
         mDisplayImeController = displayImeController;
         mDisplayInsetsController = displayInsetsController;
@@ -259,8 +258,7 @@
             DisplayInsetsController displayInsetsController, SplitLayout splitLayout,
             Transitions transitions, TransactionPool transactionPool,
             SplitscreenEventLogger logger, ShellExecutor mainExecutor,
-            Optional<RecentTasksController> recentTasks,
-            Provider<Optional<StageTaskUnfoldController>> unfoldControllerProvider) {
+            Optional<RecentTasksController> recentTasks) {
         mContext = context;
         mDisplayId = displayId;
         mSyncQueue = syncQueue;
@@ -274,8 +272,6 @@
         mSplitLayout = splitLayout;
         mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
                 this::onTransitionAnimationComplete, this);
-        mMainUnfoldController = unfoldControllerProvider.get().orElse(null);
-        mSideUnfoldController = unfoldControllerProvider.get().orElse(null);
         mLogger = logger;
         mMainExecutor = mainExecutor;
         mRecentTasks = recentTasks;
@@ -366,10 +362,15 @@
         sideOptions = sideOptions != null ? sideOptions : new Bundle();
         setSideStagePosition(sidePosition, wct);
 
+        if (mMainStage.isActive()) {
+            mMainStage.evictAllChildren(wct);
+            mSideStage.evictAllChildren(wct);
+        } else {
+            // Build a request WCT that will launch both apps such that task 0 is on the main stage
+            // while task 1 is on the side stage.
+            mMainStage.activate(wct, false /* reparent */);
+        }
         mSplitLayout.setDivideRatio(splitRatio);
-        // Build a request WCT that will launch both apps such that task 0 is on the main stage
-        // while task 1 is on the side stage.
-        mMainStage.activate(wct, false /* reparent */);
         updateWindowBounds(mSplitLayout, wct);
         wct.reorder(mRootTaskInfo.token, true);
 
@@ -610,6 +611,21 @@
         }
     }
 
+    void setSideStagePositionAnimated(@SplitPosition int sideStagePosition) {
+        if (mSideStagePosition == sideStagePosition) return;
+        SurfaceControl.Transaction t = mTransactionPool.acquire();
+        final StageTaskListener topLeftStage =
+                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
+        final StageTaskListener bottomRightStage =
+                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
+        mSplitLayout.splitSwitching(t, topLeftStage.mRootLeash, bottomRightStage.mRootLeash,
+                () -> {
+                    setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition),
+                            null /* wct */);
+                    mTransactionPool.release(t);
+                });
+    }
+
     void setSideStagePosition(@SplitPosition int sideStagePosition,
             @Nullable WindowContainerTransaction wct) {
         setSideStagePosition(sideStagePosition, true /* updateBounds */, wct);
@@ -627,7 +643,7 @@
                 onLayoutSizeChanged(mSplitLayout);
             } else {
                 updateWindowBounds(mSplitLayout, wct);
-                updateUnfoldBounds();
+                sendOnBoundsChanged();
             }
         }
     }
@@ -642,7 +658,7 @@
             if (ENABLE_SHELL_TRANSITIONS) {
                 final WindowContainerTransaction wct = new WindowContainerTransaction();
                 prepareExitSplitScreen(mTopStageAfterFoldDismiss, wct);
-                mSplitTransitions.startDismissTransition(null /* transition */, wct, this,
+                mSplitTransitions.startDismissTransition(wct, this,
                         mTopStageAfterFoldDismiss, EXIT_REASON_DEVICE_FOLDED);
             } else {
                 exitSplitScreen(
@@ -675,8 +691,8 @@
                 final int dismissTop = mainStageVisible ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
                 final WindowContainerTransaction wct = new WindowContainerTransaction();
                 prepareExitSplitScreen(dismissTop, wct);
-                mSplitTransitions.startDismissTransition(null /* transition */, wct, this,
-                        dismissTop, EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP);
+                mSplitTransitions.startDismissTransition(wct, this, dismissTop,
+                        EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP);
             }
         }
     }
@@ -739,10 +755,7 @@
             setDividerVisibility(false, t);
         });
 
-        // Hide divider and reset its position.
-        mSplitLayout.resetDividerPosition();
-        mSplitLayout.release();
-        mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
+        onTransitionAnimationComplete();
         Slog.i(TAG, "applyExitSplitScreen, reason = " + exitReasonToString(exitReason));
         // Log the exit
         if (childrenToTop != null) {
@@ -840,6 +853,9 @@
 
     private void addActivityOptions(Bundle opts, StageTaskListener stage) {
         opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, stage.mRootTaskInfo.token);
+        // Put BAL flags to avoid activity start aborted.
+        opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, true);
+        opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION, true);
     }
 
     void updateActivityOptions(Bundle opts, @SplitPosition int position) {
@@ -860,6 +876,10 @@
         listener.onStagePositionChanged(STAGE_TYPE_MAIN, getMainStagePosition());
         listener.onStagePositionChanged(STAGE_TYPE_SIDE, getSideStagePosition());
         listener.onSplitVisibilityChanged(isSplitScreenVisible());
+        if (mSplitLayout != null) {
+            listener.onSplitBoundsChanged(mSplitLayout.getRootBounds(), getMainStageBounds(),
+                    getSideStageBounds());
+        }
         mSideStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_SIDE);
         mMainStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_MAIN);
     }
@@ -872,6 +892,14 @@
         }
     }
 
+    private void sendOnBoundsChanged() {
+        if (mSplitLayout == null) return;
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onSplitBoundsChanged(mSplitLayout.getRootBounds(),
+                    getMainStageBounds(), getSideStageBounds());
+        }
+    }
+
     private void onStageChildTaskStatusChanged(StageListenerImpl stageListener, int taskId,
             boolean present, boolean visible) {
         int stage;
@@ -921,7 +949,7 @@
                 leftTopTaskId = mainStageTopTaskId;
                 rightBottomTaskId = sideStageTopTaskId;
             }
-            StagedSplitBounds splitBounds = new StagedSplitBounds(topLeftBounds, bottomRightBounds,
+            SplitBounds splitBounds = new SplitBounds(topLeftBounds, bottomRightBounds,
                     leftTopTaskId, rightBottomTaskId);
             if (mainStageTopTaskId != INVALID_TASK_ID && sideStageTopTaskId != INVALID_TASK_ID) {
                 // Update the pair for the top tasks
@@ -935,12 +963,7 @@
             final SplitScreen.SplitScreenListener l = mListeners.get(i);
             l.onSplitVisibilityChanged(mDividerVisible);
         }
-
-        if (mMainUnfoldController != null && mSideUnfoldController != null) {
-            mMainUnfoldController.onSplitVisibilityChanged(mDividerVisible);
-            mSideUnfoldController.onSplitVisibilityChanged(mDividerVisible);
-            updateUnfoldBounds();
-        }
+        sendOnBoundsChanged();
     }
 
     @Override
@@ -961,11 +984,6 @@
             mDisplayInsetsController.addInsetsChangedListener(mDisplayId, mSplitLayout);
         }
 
-        if (mMainUnfoldController != null && mSideUnfoldController != null) {
-            mMainUnfoldController.init();
-            mSideUnfoldController.init();
-        }
-
         onRootTaskAppeared();
     }
 
@@ -979,13 +997,8 @@
         mRootTaskInfo = taskInfo;
         if (mSplitLayout != null
                 && mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)
-                && mMainStage.isActive()) {
-            // TODO(b/204925795): With Shell transition, We are handling split bounds rotation at
-            //  onRotateDisplay. But still need to handle unfold case.
-            if (ENABLE_SHELL_TRANSITIONS) {
-                updateUnfoldBounds();
-                return;
-            }
+                && mMainStage.isActive()
+                && !ENABLE_SHELL_TRANSITIONS) {
             // Clear the divider remote animating flag as the divider will be re-rendered to apply
             // the new rotation config.
             mIsDividerRemoteAnimating = false;
@@ -1025,8 +1038,7 @@
         wct.reparent(mMainStage.mRootTaskInfo.token, mRootTaskInfo.token, true);
         wct.reparent(mSideStage.mRootTaskInfo.token, mRootTaskInfo.token, true);
         // Make the stages adjacent to each other so they occlude what's behind them.
-        wct.setAdjacentRoots(mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token,
-                true /* moveTogether */);
+        wct.setAdjacentRoots(mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token);
         wct.setLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token);
         mTaskOrganizer.applyTransaction(wct);
     }
@@ -1204,13 +1216,15 @@
         final int dismissTop = mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         prepareExitSplitScreen(dismissTop, wct);
-        mSplitTransitions.startDismissTransition(
-                null /* transition */, wct, this, dismissTop, EXIT_REASON_DRAG_DIVIDER);
+        if (mRootTaskInfo != null) {
+            wct.setDoNotPip(mRootTaskInfo.token);
+        }
+        mSplitTransitions.startDismissTransition(wct, this, dismissTop, EXIT_REASON_DRAG_DIVIDER);
     }
 
     @Override
     public void onDoubleTappedDivider() {
-        setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), null /* wct */);
+        setSideStagePositionAnimated(SplitLayout.reversePosition(mSideStagePosition));
         mLogger.logSwap(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
                 getSideStagePosition(), mSideStage.getTopChildTaskUid(),
                 mSplitLayout.isLandscape());
@@ -1241,7 +1255,7 @@
     public void onLayoutSizeChanged(SplitLayout layout) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         updateWindowBounds(layout, wct);
-        updateUnfoldBounds();
+        sendOnBoundsChanged();
         mSyncQueue.queue(wct);
         mSyncQueue.runInSync(t -> {
             setResizingSplits(false /* resizing */);
@@ -1252,15 +1266,6 @@
         mLogger.logResize(mSplitLayout.getDividerPositionAsFraction());
     }
 
-    private void updateUnfoldBounds() {
-        if (mMainUnfoldController != null && mSideUnfoldController != null) {
-            mMainUnfoldController.onLayoutChanged(getMainStageBounds(), getMainStagePosition(),
-                    isLandscape());
-            mSideUnfoldController.onLayoutChanged(getSideStageBounds(), getSideStagePosition(),
-                    isLandscape());
-        }
-    }
-
     private boolean isLandscape() {
         return mSplitLayout.isLandscape();
     }
@@ -1329,7 +1334,7 @@
         if (displayId != DEFAULT_DISPLAY) {
             return;
         }
-        mDisplayController.addDisplayChangingController(this::onRotateDisplay);
+        mDisplayController.addDisplayChangingController(this::onDisplayChange);
     }
 
     @Override
@@ -1340,16 +1345,24 @@
         mDisplayLayout.set(mDisplayController.getDisplayLayout(displayId));
     }
 
-    private void onRotateDisplay(int displayId, int fromRotation, int toRotation,
-            WindowContainerTransaction wct) {
+    void updateSurfaces(SurfaceControl.Transaction transaction) {
+        updateSurfaceBounds(mSplitLayout, transaction, /* applyResizingOffset */ false);
+        mSplitLayout.update(transaction);
+    }
+
+    private void onDisplayChange(int displayId, int fromRotation, int toRotation,
+            @Nullable DisplayAreaInfo newDisplayAreaInfo, WindowContainerTransaction wct) {
         if (!mMainStage.isActive()) return;
         // Only do this when shell transition
         if (!ENABLE_SHELL_TRANSITIONS) return;
 
         mDisplayLayout.rotateTo(mContext.getResources(), toRotation);
         mSplitLayout.rotateTo(toRotation, mDisplayLayout.stableInsets());
+        if (newDisplayAreaInfo != null) {
+            mSplitLayout.updateConfiguration(newDisplayAreaInfo.configuration);
+        }
         updateWindowBounds(mSplitLayout, wct);
-        updateUnfoldBounds();
+        sendOnBoundsChanged();
     }
 
     private void onFoldedStateChanged(boolean folded) {
@@ -1400,7 +1413,8 @@
             @Nullable TransitionRequestInfo request) {
         final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
         if (triggerTask == null) {
-            if (mMainStage.isActive()) {
+            if (isSplitActive()) {
+                // Check if the display is rotating.
                 final TransitionRequestInfo.DisplayChange displayChange =
                         request.getDisplayChange();
                 if (request.getType() == TRANSIT_CHANGE && displayChange != null
@@ -1427,7 +1441,7 @@
             mRecentTasks.ifPresent(recentTasks -> recentTasks.removeSplitPair(triggerTask.taskId));
         }
 
-        if (mMainStage.isActive()) {
+        if (isSplitActive()) {
             // Try to handle everything while in split-screen, so return a WCT even if it's empty.
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  split is active so using split"
                             + "Transition to handle request. triggerTask=%d type=%s mainChildren=%d"
@@ -1442,7 +1456,7 @@
                     int dismissTop = getStageType(stage) == STAGE_TYPE_MAIN ? STAGE_TYPE_SIDE
                             : STAGE_TYPE_MAIN;
                     prepareExitSplitScreen(dismissTop, out);
-                    mSplitTransitions.startDismissTransition(transition, out, this, dismissTop,
+                    mSplitTransitions.setDismissTransition(transition, dismissTop,
                             EXIT_REASON_APP_FINISHED);
                 }
             } else if (isOpening && inFullscreen) {
@@ -1452,12 +1466,13 @@
                 } else if (activityType == ACTIVITY_TYPE_HOME
                         || activityType == ACTIVITY_TYPE_RECENTS) {
                     // Enter overview panel, so start recent transition.
-                    mSplitTransitions.startRecentTransition(transition, out, this,
+                    mSplitTransitions.setRecentTransition(transition,
                             request.getRemoteTransition());
-                } else {
-                    // Occluded by the other fullscreen task, so dismiss both.
+                } else if (mSplitTransitions.mPendingRecent == null) {
+                    // If split-task is not controlled by recents animation
+                    // and occluded by the other fullscreen task, dismiss both.
                     prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, out);
-                    mSplitTransitions.startDismissTransition(transition, out, this,
+                    mSplitTransitions.setDismissTransition(transition,
                             STAGE_TYPE_UNDEFINED, EXIT_REASON_UNKNOWN);
                 }
             }
@@ -1472,6 +1487,33 @@
         return out;
     }
 
+    /**
+     * This is used for mixed scenarios. For such scenarios, just make sure to include exiting
+     * split or entering split when appropriate.
+     */
+    public void addEnterOrExitIfNeeded(@Nullable TransitionRequestInfo request,
+            @NonNull WindowContainerTransaction outWCT) {
+        final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
+        if (triggerTask != null && triggerTask.displayId != mDisplayId) {
+            // Skip handling task on the other display.
+            return;
+        }
+        final @WindowManager.TransitionType int type = request.getType();
+        if (isSplitActive() && !isOpeningType(type)
+                    && (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0)) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  One of the splits became "
+                            + "empty during a mixed transition (one not handled by split),"
+                            + " so make sure split-screen state is cleaned-up. "
+                            + "mainStageCount=%d sideStageCount=%d", mMainStage.getChildCount(),
+                    mSideStage.getChildCount());
+            prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, outWCT);
+        }
+    }
+
+    public boolean isSplitActive() {
+        return mMainStage.isActive();
+    }
+
     @Override
     public void mergeAnimation(IBinder transition, TransitionInfo info,
             SurfaceControl.Transaction t, IBinder mergeTarget,
@@ -1479,17 +1521,14 @@
         mSplitTransitions.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
     }
 
+    /** Jump the current transition animation to the end. */
+    public boolean end() {
+        return mSplitTransitions.end();
+    }
+
     @Override
     public void onTransitionMerged(@NonNull IBinder transition) {
-        // Once the pending enter transition got merged, make sure to bring divider bar visible and
-        // clear the pending transition from cache to prevent mess-up the following state.
-        if (transition == mSplitTransitions.mPendingEnter) {
-            final SurfaceControl.Transaction t = mTransactionPool.acquire();
-            finishEnterSplitScreen(t);
-            mSplitTransitions.mPendingEnter = null;
-            t.apply();
-            mTransactionPool.release(t);
-        }
+        mSplitTransitions.onTransitionMerged(transition);
     }
 
     @Override
@@ -1560,11 +1599,13 @@
         if (!shouldAnimate) return false;
 
         mSplitTransitions.playAnimation(transition, info, startTransaction, finishTransaction,
-                finishCallback, mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token);
+                finishCallback, mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token,
+                mRootTaskInfo.token);
         return true;
     }
 
-    void onTransitionAnimationComplete() {
+    /** Called to clean-up state and do house-keeping after the animation is done. */
+    public void onTransitionAnimationComplete() {
         // If still playing, let it finish.
         if (!mMainStage.isActive()) {
             // Update divider state after animation so that it is still around and positioned
@@ -1628,8 +1669,8 @@
         return true;
     }
 
-    private boolean startPendingDismissAnimation(
-            @NonNull SplitScreenTransitions.DismissTransition dismissTransition,
+    /** Synchronize split-screen state with transition and make appropriate preparations. */
+    public void prepareDismissAnimation(@StageType int toStage, @ExitReason int dismissReason,
             @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t,
             @NonNull SurfaceControl.Transaction finishT) {
         // Make some noise if things aren't totally expected. These states shouldn't effect
@@ -1662,7 +1703,7 @@
         mRecentTasks.ifPresent(recentTasks -> {
             // Notify recents if we are exiting in a way that breaks the pair, and disable further
             // updates to splits in the recents until we enter split again
-            if (shouldBreakPairedTaskInRecents(dismissTransition.mReason) && mShouldUpdateRecents) {
+            if (shouldBreakPairedTaskInRecents(dismissReason) && mShouldUpdateRecents) {
                 for (TransitionInfo.Change change : info.getChanges()) {
                     final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                     if (taskInfo != null
@@ -1679,30 +1720,37 @@
         // Wait until after animation to update divider
 
         // Reset crops so they don't interfere with subsequent launches
-        t.setWindowCrop(mMainStage.mRootLeash, null);
-        t.setWindowCrop(mSideStage.mRootLeash, null);
+        t.setCrop(mMainStage.mRootLeash, null);
+        t.setCrop(mSideStage.mRootLeash, null);
 
-        if (dismissTransition.mDismissTop == STAGE_TYPE_UNDEFINED) {
-            logExit(dismissTransition.mReason);
-            // TODO: Have a proper remote for this. Until then, though, reset state and use the
-            //       normal animation stuff (which falls back to the normal launcher remote).
-            mSplitLayout.release(t);
-            mSplitTransitions.mPendingDismiss = null;
-            return false;
+        if (toStage == STAGE_TYPE_UNDEFINED) {
+            logExit(dismissReason);
         } else {
-            logExitToStage(dismissTransition.mReason,
-                    dismissTransition.mDismissTop == STAGE_TYPE_MAIN);
+            logExitToStage(dismissReason, toStage == STAGE_TYPE_MAIN);
         }
 
-        addDividerBarToTransition(info, t, false /* show */);
-        // We're dismissing split by moving the other one to fullscreen.
-        // Since we don't have any animations for this yet, just use the internal example
-        // animations.
-
         // Hide divider and dim layer on transition finished.
         setDividerVisibility(false, finishT);
         finishT.hide(mMainStage.mDimLayer);
         finishT.hide(mSideStage.mDimLayer);
+    }
+
+    private boolean startPendingDismissAnimation(
+            @NonNull SplitScreenTransitions.DismissTransition dismissTransition,
+            @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t,
+            @NonNull SurfaceControl.Transaction finishT) {
+        prepareDismissAnimation(dismissTransition.mDismissTop, dismissTransition.mReason, info,
+                t, finishT);
+        if (dismissTransition.mDismissTop == STAGE_TYPE_UNDEFINED) {
+            // TODO: Have a proper remote for this. Until then, though, reset state and use the
+            //       normal animation stuff (which falls back to the normal launcher remote).
+            t.hide(mSplitLayout.getDividerLeash());
+            mSplitLayout.release(t);
+            mSplitTransitions.mPendingDismiss = null;
+            return false;
+        }
+
+        addDividerBarToTransition(info, t, false /* show */);
         return true;
     }
 
@@ -1712,26 +1760,26 @@
         return true;
     }
 
-    void onRecentTransitionFinished(boolean returnToHome, WindowContainerTransaction wct,
+    void onRecentTransitionFinished(WindowContainerTransaction wct,
             SurfaceControl.Transaction finishT) {
-        // Exclude the case that the split screen has been dismissed already.
-        if (!mMainStage.isActive()) {
-            // The latest split dismissing transition might be a no-op transition and thus won't
-            // callback startAnimation, update split visibility here to cover this kind of no-op
-            // transition case.
-            setSplitsVisible(false);
-            return;
+        // Check if the recent transition is finished by returning to the current split so we can
+        // restore the divider bar.
+        for (int i = 0; i < wct.getHierarchyOps().size(); ++i) {
+            final WindowContainerTransaction.HierarchyOp op = wct.getHierarchyOps().get(i);
+            final IBinder container = op.getContainer();
+            if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop()
+                    && (mMainStage.containsContainer(container)
+                    || mSideStage.containsContainer(container))) {
+                setDividerVisibility(true, finishT);
+                return;
+            }
         }
 
-        if (returnToHome) {
-            // When returning to home from recent apps, the splitting tasks are already hidden, so
-            // append the reset of dismissing operations into the clean-up wct.
-            prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, wct);
-            setSplitsVisible(false);
-            logExit(EXIT_REASON_RETURN_HOME);
-        } else {
-            setDividerVisibility(true, finishT);
-        }
+        // Dismiss the split screen is it's not returning to split.
+        prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, wct);
+        setSplitsVisible(false);
+        setDividerVisibility(false, finishT);
+        logExit(EXIT_REASON_UNKNOWN);
     }
 
     private void addDividerBarToTransition(@NonNull TransitionInfo info,
@@ -1878,8 +1926,7 @@
                 final int stageType = isMainStage ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
                 final WindowContainerTransaction wct = new WindowContainerTransaction();
                 prepareExitSplitScreen(stageType, wct);
-                mSplitTransitions.startDismissTransition(null /* transition */, wct,
-                        StageCoordinator.this, stageType,
+                mSplitTransitions.startDismissTransition(wct,StageCoordinator.this, stageType,
                         EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
             }
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index 949bf5f..23eec96a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -31,6 +31,7 @@
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.os.IBinder;
 import android.util.SparseArray;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -47,6 +48,7 @@
 import com.android.wm.shell.splitscreen.SplitScreen.StageType;
 
 import java.io.PrintWriter;
+import java.util.function.Predicate;
 
 /**
  * Base class that handle common task org. related for split-screen stages.
@@ -95,18 +97,14 @@
     // TODO(b/204308910): Extracts SplitDecorManager related code to common package.
     private SplitDecorManager mSplitDecorManager;
 
-    private final StageTaskUnfoldController mStageTaskUnfoldController;
-
     StageTaskListener(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
             StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
-            SurfaceSession surfaceSession, IconProvider iconProvider,
-            @Nullable StageTaskUnfoldController stageTaskUnfoldController) {
+            SurfaceSession surfaceSession, IconProvider iconProvider) {
         mContext = context;
         mCallbacks = callbacks;
         mSyncQueue = syncQueue;
         mSurfaceSession = surfaceSession;
         mIconProvider = iconProvider;
-        mStageTaskUnfoldController = stageTaskUnfoldController;
         taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
     }
 
@@ -119,63 +117,53 @@
     }
 
     boolean containsToken(WindowContainerToken token) {
-        if (token.equals(mRootTaskInfo.token)) {
-            return true;
-        }
+        return contains(t -> t.token.equals(token));
+    }
 
-        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
-            if (token.equals(mChildrenTaskInfo.valueAt(i).token)) {
-                return true;
-            }
-        }
-
-        return false;
+    boolean containsContainer(IBinder binder) {
+        return contains(t -> t.token.asBinder() == binder);
     }
 
     /**
      * Returns the top visible child task's id.
      */
     int getTopVisibleChildTaskId() {
-        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
-            final ActivityManager.RunningTaskInfo info = mChildrenTaskInfo.valueAt(i);
-            if (info.isVisible) {
-                return info.taskId;
-            }
-        }
-        return INVALID_TASK_ID;
+        final ActivityManager.RunningTaskInfo taskInfo = getChildTaskInfo(t -> t.isVisible);
+        return taskInfo != null ? taskInfo.taskId : INVALID_TASK_ID;
     }
 
     /**
      * Returns the top activity uid for the top child task.
      */
     int getTopChildTaskUid() {
-        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
-            final ActivityManager.RunningTaskInfo info = mChildrenTaskInfo.valueAt(i);
-            if (info.topActivityInfo == null) {
-                continue;
-            }
-            return info.topActivityInfo.applicationInfo.uid;
-        }
-        return 0;
+        final ActivityManager.RunningTaskInfo taskInfo =
+                getChildTaskInfo(t -> t.topActivityInfo != null);
+        return taskInfo != null ? taskInfo.topActivityInfo.applicationInfo.uid : 0;
     }
 
     /** @return {@code true} if this listener contains the currently focused task. */
     boolean isFocused() {
-        if (mRootTaskInfo == null) {
-            return false;
-        }
+        return contains(t -> t.isFocused);
+    }
 
-        if (mRootTaskInfo.isFocused) {
+    private boolean contains(Predicate<ActivityManager.RunningTaskInfo> predicate) {
+        if (mRootTaskInfo != null && predicate.test(mRootTaskInfo)) {
             return true;
         }
 
+        return getChildTaskInfo(predicate) != null;
+    }
+
+    @Nullable
+    private ActivityManager.RunningTaskInfo getChildTaskInfo(
+            Predicate<ActivityManager.RunningTaskInfo> predicate) {
         for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
-            if (mChildrenTaskInfo.valueAt(i).isFocused) {
-                return true;
+            final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
+            if (predicate.test(taskInfo)) {
+                return taskInfo;
             }
         }
-
-        return false;
+        return null;
     }
 
     @Override
@@ -207,10 +195,6 @@
             throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
                     + "\n mRootTaskInfo: " + mRootTaskInfo);
         }
-
-        if (mStageTaskUnfoldController != null) {
-            mStageTaskUnfoldController.onTaskAppeared(taskInfo, leash);
-        }
     }
 
     @Override
@@ -266,22 +250,18 @@
             mChildrenTaskInfo.remove(taskId);
             mChildrenLeashes.remove(taskId);
             mCallbacks.onChildTaskStatusChanged(taskId, false /* present */, taskInfo.isVisible);
-            if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) {
-                mCallbacks.onChildTaskEnterPip(taskId);
-            }
             if (ENABLE_SHELL_TRANSITIONS) {
                 // Status is managed/synchronized by the transition lifecycle.
                 return;
             }
+            if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) {
+                mCallbacks.onChildTaskEnterPip(taskId);
+            }
             sendStatusChanged();
         } else {
             throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
                     + "\n mRootTaskInfo: " + mRootTaskInfo);
         }
-
-        if (mStageTaskUnfoldController != null) {
-            mStageTaskUnfoldController.onTaskVanished(taskInfo);
-        }
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskUnfoldController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskUnfoldController.java
deleted file mode 100644
index 59eecb5d..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskUnfoldController.java
+++ /dev/null
@@ -1,281 +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.wm.shell.splitscreen;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
-
-import android.animation.RectEvaluator;
-import android.animation.TypeEvaluator;
-import android.annotation.NonNull;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.graphics.Insets;
-import android.graphics.Rect;
-import android.util.SparseArray;
-import android.view.InsetsSource;
-import android.view.InsetsState;
-import android.view.SurfaceControl;
-
-import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.wm.shell.common.DisplayInsetsController;
-import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener;
-import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
-import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
-import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener;
-import com.android.wm.shell.unfold.UnfoldBackgroundController;
-
-import java.util.concurrent.Executor;
-
-/**
- * Controls transformations of the split screen task surfaces in response
- * to the unfolding/folding action on foldable devices
- */
-public class StageTaskUnfoldController implements UnfoldListener, OnInsetsChangedListener {
-
-    private static final TypeEvaluator<Rect> RECT_EVALUATOR = new RectEvaluator(new Rect());
-    private static final float CROPPING_START_MARGIN_FRACTION = 0.05f;
-
-    private final SparseArray<AnimationContext> mAnimationContextByTaskId = new SparseArray<>();
-    private final ShellUnfoldProgressProvider mUnfoldProgressProvider;
-    private final DisplayInsetsController mDisplayInsetsController;
-    private final UnfoldBackgroundController mBackgroundController;
-    private final Executor mExecutor;
-    private final int mExpandedTaskBarHeight;
-    private final float mWindowCornerRadiusPx;
-    private final Rect mStageBounds = new Rect();
-    private final TransactionPool mTransactionPool;
-
-    private InsetsSource mTaskbarInsetsSource;
-    private boolean mBothStagesVisible;
-
-    public StageTaskUnfoldController(@NonNull Context context,
-            @NonNull TransactionPool transactionPool,
-            @NonNull ShellUnfoldProgressProvider unfoldProgressProvider,
-            @NonNull DisplayInsetsController displayInsetsController,
-            @NonNull UnfoldBackgroundController backgroundController,
-            @NonNull Executor executor) {
-        mUnfoldProgressProvider = unfoldProgressProvider;
-        mTransactionPool = transactionPool;
-        mExecutor = executor;
-        mBackgroundController = backgroundController;
-        mDisplayInsetsController = displayInsetsController;
-        mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(context);
-        mExpandedTaskBarHeight = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.taskbar_frame_height);
-    }
-
-    /**
-     * Initializes the controller, starts listening for the external events
-     */
-    public void init() {
-        mUnfoldProgressProvider.addListener(mExecutor, this);
-        mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY, this);
-    }
-
-    @Override
-    public void insetsChanged(InsetsState insetsState) {
-        mTaskbarInsetsSource = insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-            context.update();
-        }
-    }
-
-    /**
-     * Called when split screen task appeared
-     * @param taskInfo info for the appeared task
-     * @param leash surface leash for the appeared task
-     */
-    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
-        // Only handle child task surface here.
-        if (!taskInfo.hasParentTask()) return;
-
-        AnimationContext context = new AnimationContext(leash);
-        mAnimationContextByTaskId.put(taskInfo.taskId, context);
-    }
-
-    /**
-     * Called when a split screen task vanished
-     * @param taskInfo info for the vanished task
-     */
-    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
-        if (!taskInfo.hasParentTask()) return;
-
-        AnimationContext context = mAnimationContextByTaskId.get(taskInfo.taskId);
-        if (context != null) {
-            final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-            resetSurface(transaction, context);
-            transaction.apply();
-            mTransactionPool.release(transaction);
-        }
-        mAnimationContextByTaskId.remove(taskInfo.taskId);
-    }
-
-    @Override
-    public void onStateChangeProgress(float progress) {
-        if (mAnimationContextByTaskId.size() == 0 || !mBothStagesVisible) return;
-
-        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-        mBackgroundController.ensureBackground(transaction);
-
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-
-            context.mCurrentCropRect.set(RECT_EVALUATOR
-                    .evaluate(progress, context.mStartCropRect, context.mEndCropRect));
-
-            transaction.setWindowCrop(context.mLeash, context.mCurrentCropRect)
-                    .setCornerRadius(context.mLeash, mWindowCornerRadiusPx);
-        }
-
-        transaction.apply();
-
-        mTransactionPool.release(transaction);
-    }
-
-    @Override
-    public void onStateChangeFinished() {
-        resetTransformations();
-    }
-
-    /**
-     * Called when split screen visibility changes
-     * @param bothStagesVisible true if both stages of the split screen are visible
-     */
-    public void onSplitVisibilityChanged(boolean bothStagesVisible) {
-        mBothStagesVisible = bothStagesVisible;
-        if (!bothStagesVisible) {
-            resetTransformations();
-        }
-    }
-
-    /**
-     * Called when split screen stage bounds changed
-     * @param bounds new bounds for this stage
-     */
-    public void onLayoutChanged(Rect bounds, @SplitPosition int splitPosition,
-            boolean isLandscape) {
-        mStageBounds.set(bounds);
-
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-            context.update(splitPosition, isLandscape);
-        }
-    }
-
-    private void resetTransformations() {
-        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-            resetSurface(transaction, context);
-        }
-        mBackgroundController.removeBackground(transaction);
-        transaction.apply();
-
-        mTransactionPool.release(transaction);
-    }
-
-    private void resetSurface(SurfaceControl.Transaction transaction, AnimationContext context) {
-        transaction
-                .setWindowCrop(context.mLeash, null)
-                .setCornerRadius(context.mLeash, 0.0F);
-    }
-
-    private class AnimationContext {
-        final SurfaceControl mLeash;
-        final Rect mStartCropRect = new Rect();
-        final Rect mEndCropRect = new Rect();
-        final Rect mCurrentCropRect = new Rect();
-
-        private @SplitPosition int mSplitPosition = SPLIT_POSITION_UNDEFINED;
-        private boolean mIsLandscape = false;
-
-        private AnimationContext(SurfaceControl leash) {
-            this.mLeash = leash;
-            update();
-        }
-
-        private void update(@SplitPosition int splitPosition, boolean isLandscape) {
-            this.mSplitPosition = splitPosition;
-            this.mIsLandscape = isLandscape;
-            update();
-        }
-
-        private void update() {
-            mStartCropRect.set(mStageBounds);
-
-            boolean taskbarExpanded = isTaskbarExpanded();
-            if (taskbarExpanded) {
-                // Only insets the cropping window with taskbar when taskbar is expanded
-                mStartCropRect.inset(mTaskbarInsetsSource.calculateVisibleInsets(mStartCropRect));
-            }
-
-            // Offset to surface coordinates as layout bounds are in screen coordinates
-            mStartCropRect.offsetTo(0, 0);
-
-            mEndCropRect.set(mStartCropRect);
-
-            int maxSize = Math.max(mEndCropRect.width(), mEndCropRect.height());
-            int margin = (int) (maxSize * CROPPING_START_MARGIN_FRACTION);
-
-            // Sides adjacent to split bar or task bar are not be animated.
-            Insets margins;
-            if (mIsLandscape) { // Left and right splits.
-                margins = getLandscapeMargins(margin, taskbarExpanded);
-            } else { // Top and bottom splits.
-                margins = getPortraitMargins(margin, taskbarExpanded);
-            }
-            mStartCropRect.inset(margins);
-        }
-
-        private Insets getLandscapeMargins(int margin, boolean taskbarExpanded) {
-            int left = margin;
-            int right = margin;
-            int bottom = taskbarExpanded ? 0 : margin; // Taskbar margin.
-            if (mSplitPosition == SPLIT_POSITION_TOP_OR_LEFT) {
-                right = 0; // Divider margin.
-            } else {
-                left = 0; // Divider margin.
-            }
-            return Insets.of(left, /* top= */ margin, right, bottom);
-        }
-
-        private Insets getPortraitMargins(int margin, boolean taskbarExpanded) {
-            int bottom = margin;
-            int top = margin;
-            if (mSplitPosition == SPLIT_POSITION_TOP_OR_LEFT) {
-                bottom = 0; // Divider margin.
-            } else { // Bottom split.
-                top = 0; // Divider margin.
-                if (taskbarExpanded) {
-                    bottom = 0; // Taskbar margin.
-                }
-            }
-            return Insets.of(/* left= */ margin, top, /* right= */ margin, bottom);
-        }
-
-        private boolean isTaskbarExpanded() {
-            return mTaskbarInsetsSource != null
-                    && mTaskbarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight;
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/ISplitScreen.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/ISplitScreen.aidl
deleted file mode 100644
index 45f6d3c..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/ISplitScreen.aidl
+++ /dev/null
@@ -1,103 +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.wm.shell.stagesplit;
-
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.view.RemoteAnimationAdapter;
-import android.view.RemoteAnimationTarget;
-import android.window.RemoteTransition;
-
-import com.android.wm.shell.stagesplit.ISplitScreenListener;
-
-/**
- * Interface that is exposed to remote callers to manipulate the splitscreen feature.
- */
-interface ISplitScreen {
-
-    /**
-     * Registers a split screen listener.
-     */
-    oneway void registerSplitScreenListener(in ISplitScreenListener listener) = 1;
-
-    /**
-     * Unregisters a split screen listener.
-     */
-    oneway void unregisterSplitScreenListener(in ISplitScreenListener listener) = 2;
-
-    /**
-     * Hides the side-stage if it is currently visible.
-     */
-    oneway void setSideStageVisibility(boolean visible) = 3;
-
-    /**
-     * Removes a task from the side stage.
-     */
-    oneway void removeFromSideStage(int taskId) = 4;
-
-    /**
-     * Removes the split-screen stages and leaving indicated task to top. Passing INVALID_TASK_ID
-     * to indicate leaving no top task after leaving split-screen.
-     */
-    oneway void exitSplitScreen(int toTopTaskId) = 5;
-
-    /**
-     * @param exitSplitScreenOnHide if to exit split-screen if both stages are not visible.
-     */
-    oneway void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) = 6;
-
-    /**
-     * Starts a task in a stage.
-     */
-    oneway void startTask(int taskId, int stage, int position, in Bundle options) = 7;
-
-    /**
-     * Starts a shortcut in a stage.
-     */
-    oneway void startShortcut(String packageName, String shortcutId, int stage, int position,
-            in Bundle options, in UserHandle user) = 8;
-
-    /**
-     * Starts an activity in a stage.
-     */
-    oneway void startIntent(in PendingIntent intent, in Intent fillInIntent, int stage,
-            int position, in Bundle options) = 9;
-
-    /**
-     * Starts tasks simultaneously in one transition.
-     */
-    oneway void startTasks(int mainTaskId, in Bundle mainOptions, int sideTaskId,
-            in Bundle sideOptions, int sidePosition, in RemoteTransition remoteTransition) = 10;
-
-    /**
-     * Version of startTasks using legacy transition system.
-     */
-     oneway void startTasksWithLegacyTransition(int mainTaskId, in Bundle mainOptions,
-                            int sideTaskId, in Bundle sideOptions, int sidePosition,
-                            in RemoteAnimationAdapter adapter) = 11;
-
-    /**
-     * Blocking call that notifies and gets additional split-screen targets when entering
-     * recents (for example: the dividerBar).
-     * @param cancel is true if leaving recents back to split (eg. the gesture was cancelled).
-     * @param appTargets apps that will be re-parented to display area
-     */
-    RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel,
-                                                   in RemoteAnimationTarget[] appTargets) = 12;
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/ISplitScreenListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/ISplitScreenListener.aidl
deleted file mode 100644
index 46e4299..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/ISplitScreenListener.aidl
+++ /dev/null
@@ -1,33 +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.wm.shell.stagesplit;
-
-/**
- * Listener interface that Launcher attaches to SystemUI to get split-screen callbacks.
- */
-oneway interface ISplitScreenListener {
-
-    /**
-     * Called when the stage position changes.
-     */
-    void onStagePositionChanged(int stage, int position);
-
-    /**
-     * Called when a task changes stages.
-     */
-    void onTaskStageChanged(int taskId, int stage, boolean visible);
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/MainStage.java
deleted file mode 100644
index 83855be..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/MainStage.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.stagesplit;
-
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
-
-import android.annotation.Nullable;
-import android.graphics.Rect;
-import android.view.SurfaceSession;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
-
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.SyncTransactionQueue;
-
-/**
- * Main stage for split-screen mode. When split-screen is active all standard activity types launch
- * on the main stage, except for task that are explicitly pinned to the {@link SideStage}.
- * @see StageCoordinator
- */
-class MainStage extends StageTaskListener {
-    private static final String TAG = MainStage.class.getSimpleName();
-
-    private boolean mIsActive = false;
-
-    MainStage(ShellTaskOrganizer taskOrganizer, int displayId,
-            StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
-            SurfaceSession surfaceSession,
-            @Nullable StageTaskUnfoldController stageTaskUnfoldController) {
-        super(taskOrganizer, displayId, callbacks, syncQueue, surfaceSession,
-                stageTaskUnfoldController);
-    }
-
-    boolean isActive() {
-        return mIsActive;
-    }
-
-    void activate(Rect rootBounds, WindowContainerTransaction wct) {
-        if (mIsActive) return;
-
-        final WindowContainerToken rootToken = mRootTaskInfo.token;
-        wct.setBounds(rootToken, rootBounds)
-                .setWindowingMode(rootToken, WINDOWING_MODE_MULTI_WINDOW)
-                .setLaunchRoot(
-                        rootToken,
-                        CONTROLLED_WINDOWING_MODES,
-                        CONTROLLED_ACTIVITY_TYPES)
-                .reparentTasks(
-                        null /* currentParent */,
-                        rootToken,
-                        CONTROLLED_WINDOWING_MODES,
-                        CONTROLLED_ACTIVITY_TYPES,
-                        true /* onTop */)
-                // Moving the root task to top after the child tasks were re-parented , or the root
-                // task cannot be visible and focused.
-                .reorder(rootToken, true /* onTop */);
-
-        mIsActive = true;
-    }
-
-    void deactivate(WindowContainerTransaction wct) {
-        deactivate(wct, false /* toTop */);
-    }
-
-    void deactivate(WindowContainerTransaction wct, boolean toTop) {
-        if (!mIsActive) return;
-        mIsActive = false;
-
-        if (mRootTaskInfo == null) return;
-        final WindowContainerToken rootToken = mRootTaskInfo.token;
-        wct.setLaunchRoot(
-                        rootToken,
-                        null,
-                        null)
-                .reparentTasks(
-                        rootToken,
-                        null /* newParent */,
-                        CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
-                        CONTROLLED_ACTIVITY_TYPES,
-                        toTop)
-                // We want this re-order to the bottom regardless since we are re-parenting
-                // all its tasks.
-                .reorder(rootToken, false /* onTop */);
-    }
-
-    void updateConfiguration(int windowingMode, Rect bounds, WindowContainerTransaction wct) {
-        wct.setBounds(mRootTaskInfo.token, bounds)
-                .setWindowingMode(mRootTaskInfo.token, windowingMode);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/OWNERS
deleted file mode 100644
index 264e88f..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# WM shell sub-modules stagesplit owner
-chenghsiuchang@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/OutlineManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/OutlineManager.java
deleted file mode 100644
index 8fbad52..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/OutlineManager.java
+++ /dev/null
@@ -1,181 +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.wm.shell.stagesplit;
-
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.os.Binder;
-import android.view.IWindow;
-import android.view.InsetsSource;
-import android.view.InsetsState;
-import android.view.LayoutInflater;
-import android.view.SurfaceControl;
-import android.view.SurfaceControlViewHost;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.WindowlessWindowManager;
-import android.widget.FrameLayout;
-
-import com.android.wm.shell.R;
-
-/**
- * Handles drawing outline of the bounds of provided root surface. The outline will be drown with
- * the consideration of display insets like status bar, navigation bar and display cutout.
- */
-class OutlineManager extends WindowlessWindowManager {
-    private static final String WINDOW_NAME = "SplitOutlineLayer";
-    private final Context mContext;
-    private final Rect mRootBounds = new Rect();
-    private final Rect mTempRect = new Rect();
-    private final Rect mLastOutlineBounds = new Rect();
-    private final InsetsState mInsetsState = new InsetsState();
-    private final int mExpandedTaskBarHeight;
-    private OutlineView mOutlineView;
-    private SurfaceControlViewHost mViewHost;
-    private SurfaceControl mHostLeash;
-    private SurfaceControl mLeash;
-
-    OutlineManager(Context context, Configuration configuration) {
-        super(configuration, null /* rootSurface */, null /* hostInputToken */);
-        mContext = context.createWindowContext(context.getDisplay(), TYPE_APPLICATION_OVERLAY,
-                null /* options */);
-        mExpandedTaskBarHeight = mContext.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.taskbar_frame_height);
-    }
-
-    @Override
-    protected void attachToParentSurface(IWindow window, SurfaceControl.Builder b) {
-        b.setParent(mHostLeash);
-    }
-
-    void inflate(SurfaceControl rootLeash, Rect rootBounds) {
-        if (mLeash != null || mViewHost != null) return;
-
-        mHostLeash = rootLeash;
-        mRootBounds.set(rootBounds);
-        mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);
-
-        final FrameLayout rootLayout = (FrameLayout) LayoutInflater.from(mContext)
-                .inflate(R.layout.split_outline, null);
-        mOutlineView = rootLayout.findViewById(R.id.split_outline);
-
-        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                0 /* width */, 0 /* height */, TYPE_APPLICATION_OVERLAY,
-                FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
-        lp.width = mRootBounds.width();
-        lp.height = mRootBounds.height();
-        lp.token = new Binder();
-        lp.setTitle(WINDOW_NAME);
-        lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
-        // TODO(b/189839391): Set INPUT_FEATURE_NO_INPUT_CHANNEL after WM supports
-        //  TRUSTED_OVERLAY for windowless window without input channel.
-        mViewHost.setView(rootLayout, lp);
-        mLeash = getSurfaceControl(mViewHost.getWindowToken());
-
-        drawOutline();
-    }
-
-    void release() {
-        if (mViewHost != null) {
-            mViewHost.release();
-            mViewHost = null;
-        }
-        mRootBounds.setEmpty();
-        mLastOutlineBounds.setEmpty();
-        mOutlineView = null;
-        mHostLeash = null;
-        mLeash = null;
-    }
-
-    @Nullable
-    SurfaceControl getOutlineLeash() {
-        return mLeash;
-    }
-
-    void setVisibility(boolean visible) {
-        if (mOutlineView != null) {
-            mOutlineView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
-        }
-    }
-
-    void setRootBounds(Rect rootBounds) {
-        if (mViewHost == null || mViewHost.getView() == null) {
-            return;
-        }
-
-        if (!mRootBounds.equals(rootBounds)) {
-            WindowManager.LayoutParams lp =
-                    (WindowManager.LayoutParams) mViewHost.getView().getLayoutParams();
-            lp.width = rootBounds.width();
-            lp.height = rootBounds.height();
-            mViewHost.relayout(lp);
-            mRootBounds.set(rootBounds);
-            drawOutline();
-        }
-    }
-
-    void onInsetsChanged(InsetsState insetsState) {
-        if (!mInsetsState.equals(insetsState)) {
-            mInsetsState.set(insetsState);
-            drawOutline();
-        }
-    }
-
-    private void computeOutlineBounds(Rect rootBounds, InsetsState insetsState, Rect outBounds) {
-        outBounds.set(rootBounds);
-        final InsetsSource taskBarInsetsSource =
-                insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
-        // Only insets the divider bar with task bar when it's expanded so that the rounded corners
-        // will be drawn against task bar.
-        if (taskBarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight) {
-            outBounds.inset(taskBarInsetsSource.calculateVisibleInsets(outBounds));
-        }
-
-        // Offset the coordinate from screen based to surface based.
-        outBounds.offset(-rootBounds.left, -rootBounds.top);
-    }
-
-    void drawOutline() {
-        if (mOutlineView == null) {
-            return;
-        }
-
-        computeOutlineBounds(mRootBounds, mInsetsState, mTempRect);
-        if (mTempRect.equals(mLastOutlineBounds)) {
-            return;
-        }
-
-        ViewGroup.MarginLayoutParams lp =
-                (ViewGroup.MarginLayoutParams) mOutlineView.getLayoutParams();
-        lp.leftMargin = mTempRect.left;
-        lp.topMargin = mTempRect.top;
-        lp.width = mTempRect.width();
-        lp.height = mTempRect.height();
-        mOutlineView.setLayoutParams(lp);
-        mLastOutlineBounds.set(mTempRect);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/OutlineView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/OutlineView.java
deleted file mode 100644
index 92b1381..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/OutlineView.java
+++ /dev/null
@@ -1,82 +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.wm.shell.stagesplit;
-
-import static android.view.RoundedCorner.POSITION_BOTTOM_LEFT;
-import static android.view.RoundedCorner.POSITION_BOTTOM_RIGHT;
-import static android.view.RoundedCorner.POSITION_TOP_LEFT;
-import static android.view.RoundedCorner.POSITION_TOP_RIGHT;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.util.AttributeSet;
-import android.view.RoundedCorner;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.R;
-
-/** View for drawing split outline. */
-public class OutlineView extends View {
-    private final Paint mPaint = new Paint();
-    private final Path mPath = new Path();
-    private final float[] mRadii = new float[8];
-
-    public OutlineView(@NonNull Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-        mPaint.setStyle(Paint.Style.STROKE);
-        mPaint.setStrokeWidth(
-                getResources().getDimension(R.dimen.accessibility_focus_highlight_stroke_width));
-        mPaint.setColor(getResources().getColor(R.color.system_accent1_100, null));
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        // TODO(b/200850654): match the screen corners with the actual display decor.
-        mRadii[0] = mRadii[1] = getCornerRadius(POSITION_TOP_LEFT);
-        mRadii[2] = mRadii[3] = getCornerRadius(POSITION_TOP_RIGHT);
-        mRadii[4] = mRadii[5] = getCornerRadius(POSITION_BOTTOM_RIGHT);
-        mRadii[6] = mRadii[7] = getCornerRadius(POSITION_BOTTOM_LEFT);
-    }
-
-    private int getCornerRadius(@RoundedCorner.Position int position) {
-        final RoundedCorner roundedCorner = getDisplay().getRoundedCorner(position);
-        return roundedCorner == null ? 0 : roundedCorner.getRadius();
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        if (changed) {
-            mPath.reset();
-            mPath.addRoundRect(0, 0, getWidth(), getHeight(), mRadii, Path.Direction.CW);
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        canvas.drawPath(mPath, mPaint);
-    }
-
-    @Override
-    public boolean hasOverlappingRendering() {
-        return false;
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SideStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SideStage.java
deleted file mode 100644
index 55c4f3a..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SideStage.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.stagesplit;
-
-import android.annotation.CallSuper;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.graphics.Rect;
-import android.view.InsetsSourceControl;
-import android.view.InsetsState;
-import android.view.SurfaceControl;
-import android.view.SurfaceSession;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
-
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.DisplayInsetsController;
-import com.android.wm.shell.common.SyncTransactionQueue;
-
-/**
- * Side stage for split-screen mode. Only tasks that are explicitly pinned to this stage show up
- * here. All other task are launch in the {@link MainStage}.
- *
- * @see StageCoordinator
- */
-class SideStage extends StageTaskListener implements
-        DisplayInsetsController.OnInsetsChangedListener {
-    private static final String TAG = SideStage.class.getSimpleName();
-    private final Context mContext;
-    private OutlineManager mOutlineManager;
-
-    SideStage(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
-            StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
-            SurfaceSession surfaceSession,
-            @Nullable StageTaskUnfoldController stageTaskUnfoldController) {
-        super(taskOrganizer, displayId, callbacks, syncQueue, surfaceSession,
-                stageTaskUnfoldController);
-        mContext = context;
-    }
-
-    void addTask(ActivityManager.RunningTaskInfo task, Rect rootBounds,
-            WindowContainerTransaction wct) {
-        final WindowContainerToken rootToken = mRootTaskInfo.token;
-        wct.setBounds(rootToken, rootBounds)
-                .reparent(task.token, rootToken, true /* onTop*/)
-                // Moving the root task to top after the child tasks were reparented , or the root
-                // task cannot be visible and focused.
-                .reorder(rootToken, true /* onTop */);
-    }
-
-    boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
-        // No matter if the root task is empty or not, moving the root to bottom because it no
-        // longer preserves visible child task.
-        wct.reorder(mRootTaskInfo.token, false /* onTop */);
-        if (mChildrenTaskInfo.size() == 0) return false;
-        wct.reparentTasks(
-                mRootTaskInfo.token,
-                null /* newParent */,
-                CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
-                CONTROLLED_ACTIVITY_TYPES,
-                toTop);
-        return true;
-    }
-
-    boolean removeTask(int taskId, WindowContainerToken newParent, WindowContainerTransaction wct) {
-        final ActivityManager.RunningTaskInfo task = mChildrenTaskInfo.get(taskId);
-        if (task == null) return false;
-        wct.reparent(task.token, newParent, false /* onTop */);
-        return true;
-    }
-
-    @Nullable
-    public SurfaceControl getOutlineLeash() {
-        return mOutlineManager.getOutlineLeash();
-    }
-
-    @Override
-    @CallSuper
-    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
-        super.onTaskAppeared(taskInfo, leash);
-        if (isRootTask(taskInfo)) {
-            mOutlineManager = new OutlineManager(mContext, taskInfo.configuration);
-            enableOutline(true);
-        }
-    }
-
-    @Override
-    @CallSuper
-    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
-        super.onTaskInfoChanged(taskInfo);
-        if (isRootTask(taskInfo)) {
-            mOutlineManager.setRootBounds(taskInfo.configuration.windowConfiguration.getBounds());
-        }
-    }
-
-    private boolean isRootTask(ActivityManager.RunningTaskInfo taskInfo) {
-        return mRootTaskInfo != null && mRootTaskInfo.taskId == taskInfo.taskId;
-    }
-
-    void enableOutline(boolean enable) {
-        if (mOutlineManager == null) {
-            return;
-        }
-
-        if (enable) {
-            if (mRootTaskInfo != null) {
-                mOutlineManager.inflate(mRootLeash,
-                        mRootTaskInfo.configuration.windowConfiguration.getBounds());
-            }
-        } else {
-            mOutlineManager.release();
-        }
-    }
-
-    void setOutlineVisibility(boolean visible) {
-        mOutlineManager.setVisibility(visible);
-    }
-
-    @Override
-    public void insetsChanged(InsetsState insetsState) {
-        mOutlineManager.onInsetsChanged(insetsState);
-    }
-
-    @Override
-    public void insetsControlChanged(InsetsState insetsState,
-            InsetsSourceControl[] activeControls) {
-        insetsChanged(insetsState);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreen.java
deleted file mode 100644
index c5d2312..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreen.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.stagesplit;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-
-import com.android.wm.shell.common.annotations.ExternalThread;
-import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
-
-import java.util.concurrent.Executor;
-
-/**
- * Interface to engage split-screen feature.
- * TODO: Figure out which of these are actually needed outside of the Shell
- */
-@ExternalThread
-public interface SplitScreen {
-    /**
-     * Stage type isn't specified normally meaning to use what ever the default is.
-     * E.g. exit split-screen and launch the app in fullscreen.
-     */
-    int STAGE_TYPE_UNDEFINED = -1;
-    /**
-     * The main stage type.
-     * @see MainStage
-     */
-    int STAGE_TYPE_MAIN = 0;
-
-    /**
-     * The side stage type.
-     * @see SideStage
-     */
-    int STAGE_TYPE_SIDE = 1;
-
-    @IntDef(prefix = { "STAGE_TYPE_" }, value = {
-            STAGE_TYPE_UNDEFINED,
-            STAGE_TYPE_MAIN,
-            STAGE_TYPE_SIDE
-    })
-    @interface StageType {}
-
-    /** Callback interface for listening to changes in a split-screen stage. */
-    interface SplitScreenListener {
-        default void onStagePositionChanged(@StageType int stage, @SplitPosition int position) {}
-        default void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) {}
-        default void onSplitVisibilityChanged(boolean visible) {}
-    }
-
-    /** Registers listener that gets split screen callback. */
-    void registerSplitScreenListener(@NonNull SplitScreenListener listener,
-            @NonNull Executor executor);
-
-    /** Unregisters listener that gets split screen callback. */
-    void unregisterSplitScreenListener(@NonNull SplitScreenListener listener);
-
-    /**
-     * Returns a binder that can be passed to an external process to manipulate SplitScreen.
-     */
-    default ISplitScreen createExternalInterface() {
-        return null;
-    }
-
-    /**
-     * Called when the keyguard occluded state changes.
-     * @param occluded Indicates if the keyguard is now occluded.
-     */
-    void onKeyguardOccludedChanged(boolean occluded);
-
-    /**
-     * Called when the visibility of the keyguard changes.
-     * @param showing Indicates if the keyguard is now visible.
-     */
-    void onKeyguardVisibilityChanged(boolean showing);
-
-    /** Get a string representation of a stage type */
-    static String stageTypeToString(@StageType int stage) {
-        switch (stage) {
-            case STAGE_TYPE_UNDEFINED: return "UNDEFINED";
-            case STAGE_TYPE_MAIN: return "MAIN";
-            case STAGE_TYPE_SIDE: return "SIDE";
-            default: return "UNKNOWN(" + stage + ")";
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreenController.java
deleted file mode 100644
index 0717405..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreenController.java
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.stagesplit;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.RemoteAnimationTarget.MODE_OPENING;
-
-import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
-
-import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
-import android.app.PendingIntent;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.LauncherApps;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Slog;
-import android.view.IRemoteAnimationFinishedCallback;
-import android.view.RemoteAnimationAdapter;
-import android.view.RemoteAnimationTarget;
-import android.view.SurfaceControl;
-import android.view.SurfaceSession;
-import android.view.WindowManager;
-import android.window.RemoteTransition;
-import android.window.WindowContainerTransaction;
-
-import androidx.annotation.BinderThread;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.logging.InstanceId;
-import com.android.internal.util.FrameworkStatsLog;
-import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.DisplayInsetsController;
-import com.android.wm.shell.common.RemoteCallable;
-import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.common.annotations.ExternalThread;
-import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
-import com.android.wm.shell.draganddrop.DragAndDropPolicy;
-import com.android.wm.shell.transition.LegacyTransitions;
-import com.android.wm.shell.transition.Transitions;
-
-import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.Optional;
-import java.util.concurrent.Executor;
-
-import javax.inject.Provider;
-
-/**
- * Class manages split-screen multitasking mode and implements the main interface
- * {@link SplitScreen}.
- * @see StageCoordinator
- */
-// TODO(b/198577848): Implement split screen flicker test to consolidate CUJ of split screen.
-public class SplitScreenController implements DragAndDropPolicy.Starter,
-        RemoteCallable<SplitScreenController> {
-    private static final String TAG = SplitScreenController.class.getSimpleName();
-
-    private final ShellTaskOrganizer mTaskOrganizer;
-    private final SyncTransactionQueue mSyncQueue;
-    private final Context mContext;
-    private final RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
-    private final ShellExecutor mMainExecutor;
-    private final SplitScreenImpl mImpl = new SplitScreenImpl();
-    private final DisplayImeController mDisplayImeController;
-    private final DisplayInsetsController mDisplayInsetsController;
-    private final Transitions mTransitions;
-    private final TransactionPool mTransactionPool;
-    private final SplitscreenEventLogger mLogger;
-    private final Provider<Optional<StageTaskUnfoldController>> mUnfoldControllerProvider;
-
-    private StageCoordinator mStageCoordinator;
-
-    public SplitScreenController(ShellTaskOrganizer shellTaskOrganizer,
-            SyncTransactionQueue syncQueue, Context context,
-            RootTaskDisplayAreaOrganizer rootTDAOrganizer,
-            ShellExecutor mainExecutor, DisplayImeController displayImeController,
-            DisplayInsetsController displayInsetsController,
-            Transitions transitions, TransactionPool transactionPool,
-            Provider<Optional<StageTaskUnfoldController>> unfoldControllerProvider) {
-        mTaskOrganizer = shellTaskOrganizer;
-        mSyncQueue = syncQueue;
-        mContext = context;
-        mRootTDAOrganizer = rootTDAOrganizer;
-        mMainExecutor = mainExecutor;
-        mDisplayImeController = displayImeController;
-        mDisplayInsetsController = displayInsetsController;
-        mTransitions = transitions;
-        mTransactionPool = transactionPool;
-        mUnfoldControllerProvider = unfoldControllerProvider;
-        mLogger = new SplitscreenEventLogger();
-    }
-
-    public SplitScreen asSplitScreen() {
-        return mImpl;
-    }
-
-    @Override
-    public Context getContext() {
-        return mContext;
-    }
-
-    @Override
-    public ShellExecutor getRemoteCallExecutor() {
-        return mMainExecutor;
-    }
-
-    public void onOrganizerRegistered() {
-        if (mStageCoordinator == null) {
-            // TODO: Multi-display
-            mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
-                    mRootTDAOrganizer, mTaskOrganizer, mDisplayImeController,
-                    mDisplayInsetsController, mTransitions, mTransactionPool, mLogger,
-                    mUnfoldControllerProvider);
-        }
-    }
-
-    public boolean isSplitScreenVisible() {
-        return mStageCoordinator.isSplitScreenVisible();
-    }
-
-    public boolean moveToSideStage(int taskId, @SplitPosition int sideStagePosition) {
-        final ActivityManager.RunningTaskInfo task = mTaskOrganizer.getRunningTaskInfo(taskId);
-        if (task == null) {
-            throw new IllegalArgumentException("Unknown taskId" + taskId);
-        }
-        return moveToSideStage(task, sideStagePosition);
-    }
-
-    public boolean moveToSideStage(ActivityManager.RunningTaskInfo task,
-            @SplitPosition int sideStagePosition) {
-        return mStageCoordinator.moveToSideStage(task, sideStagePosition);
-    }
-
-    public boolean removeFromSideStage(int taskId) {
-        return mStageCoordinator.removeFromSideStage(taskId);
-    }
-
-    public void setSideStageOutline(boolean enable) {
-        mStageCoordinator.setSideStageOutline(enable);
-    }
-
-    public void setSideStagePosition(@SplitPosition int sideStagePosition) {
-        mStageCoordinator.setSideStagePosition(sideStagePosition, null /* wct */);
-    }
-
-    public void setSideStageVisibility(boolean visible) {
-        mStageCoordinator.setSideStageVisibility(visible);
-    }
-
-    public void enterSplitScreen(int taskId, boolean leftOrTop) {
-        moveToSideStage(taskId,
-                leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT);
-    }
-
-    public void exitSplitScreen(int toTopTaskId, int exitReason) {
-        mStageCoordinator.exitSplitScreen(toTopTaskId, exitReason);
-    }
-
-    public void onKeyguardOccludedChanged(boolean occluded) {
-        mStageCoordinator.onKeyguardOccludedChanged(occluded);
-    }
-
-    public void onKeyguardVisibilityChanged(boolean showing) {
-        mStageCoordinator.onKeyguardVisibilityChanged(showing);
-    }
-
-    public void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
-        mStageCoordinator.exitSplitScreenOnHide(exitSplitScreenOnHide);
-    }
-
-    public void getStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
-        mStageCoordinator.getStageBounds(outTopOrLeftBounds, outBottomOrRightBounds);
-    }
-
-    public void registerSplitScreenListener(SplitScreen.SplitScreenListener listener) {
-        mStageCoordinator.registerSplitScreenListener(listener);
-    }
-
-    public void unregisterSplitScreenListener(SplitScreen.SplitScreenListener listener) {
-        mStageCoordinator.unregisterSplitScreenListener(listener);
-    }
-
-    public void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options) {
-        options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options,
-                null /* wct */);
-
-        try {
-            ActivityTaskManager.getService().startActivityFromRecents(taskId, options);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Failed to launch task", e);
-        }
-    }
-
-    public void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
-            @Nullable Bundle options, UserHandle user) {
-        options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options,
-                null /* wct */);
-
-        try {
-            LauncherApps launcherApps =
-                    mContext.getSystemService(LauncherApps.class);
-            launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */,
-                    options, user);
-        } catch (ActivityNotFoundException e) {
-            Slog.e(TAG, "Failed to launch shortcut", e);
-        }
-    }
-
-    public void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
-            @Nullable Bundle options) {
-        if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
-            startIntentLegacy(intent, fillInIntent, position, options);
-            return;
-        }
-        mStageCoordinator.startIntent(intent, fillInIntent, STAGE_TYPE_UNDEFINED, position, options,
-                null /* remote */);
-    }
-
-    private void startIntentLegacy(PendingIntent intent, Intent fillInIntent,
-            @SplitPosition int position, @Nullable Bundle options) {
-        LegacyTransitions.ILegacyTransition transition = new LegacyTransitions.ILegacyTransition() {
-            @Override
-            public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
-                    RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
-                    IRemoteAnimationFinishedCallback finishedCallback,
-                    SurfaceControl.Transaction t) {
-                mStageCoordinator.updateSurfaceBounds(null /* layout */, t,
-                        false /* applyResizingOffset */);
-
-                if (apps != null) {
-                    for (int i = 0; i < apps.length; ++i) {
-                        if (apps[i].mode == MODE_OPENING) {
-                            t.show(apps[i].leash);
-                        }
-                    }
-                }
-
-                t.apply();
-                if (finishedCallback != null) {
-                    try {
-                        finishedCallback.onAnimationFinished();
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Error finishing legacy transition: ", e);
-                    }
-                }
-            }
-        };
-        WindowContainerTransaction wct = new WindowContainerTransaction();
-        options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, wct);
-        wct.sendPendingIntent(intent, fillInIntent, options);
-        mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
-    }
-
-    RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel, RemoteAnimationTarget[] apps) {
-        if (!isSplitScreenVisible()) return null;
-        final SurfaceControl.Builder builder = new SurfaceControl.Builder(new SurfaceSession())
-                .setContainerLayer()
-                .setName("RecentsAnimationSplitTasks")
-                .setHidden(false)
-                .setCallsite("SplitScreenController#onGoingtoRecentsLegacy");
-        mRootTDAOrganizer.attachToDisplayArea(DEFAULT_DISPLAY, builder);
-        SurfaceControl sc = builder.build();
-        SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
-
-        // Ensure that we order these in the parent in the right z-order as their previous order
-        Arrays.sort(apps, (a1, a2) -> a1.prefixOrderIndex - a2.prefixOrderIndex);
-        int layer = 1;
-        for (RemoteAnimationTarget appTarget : apps) {
-            transaction.reparent(appTarget.leash, sc);
-            transaction.setPosition(appTarget.leash, appTarget.screenSpaceBounds.left,
-                    appTarget.screenSpaceBounds.top);
-            transaction.setLayer(appTarget.leash, layer++);
-        }
-        transaction.apply();
-        transaction.close();
-        return new RemoteAnimationTarget[]{
-                mStageCoordinator.getDividerBarLegacyTarget(),
-                mStageCoordinator.getOutlineLegacyTarget()};
-    }
-
-    /**
-     * Sets drag info to be logged when splitscreen is entered.
-     */
-    public void logOnDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) {
-        mStageCoordinator.logOnDroppedToSplit(position, dragSessionId);
-    }
-
-    public void dump(@NonNull PrintWriter pw, String prefix) {
-        pw.println(prefix + TAG);
-        if (mStageCoordinator != null) {
-            mStageCoordinator.dump(pw, prefix);
-        }
-    }
-
-    /**
-     * The interface for calls from outside the Shell, within the host process.
-     */
-    @ExternalThread
-    private class SplitScreenImpl implements SplitScreen {
-        private ISplitScreenImpl mISplitScreen;
-        private final ArrayMap<SplitScreenListener, Executor> mExecutors = new ArrayMap<>();
-        private final SplitScreenListener mListener = new SplitScreenListener() {
-            @Override
-            public void onStagePositionChanged(int stage, int position) {
-                for (int i = 0; i < mExecutors.size(); i++) {
-                    final int index = i;
-                    mExecutors.valueAt(index).execute(() -> {
-                        mExecutors.keyAt(index).onStagePositionChanged(stage, position);
-                    });
-                }
-            }
-
-            @Override
-            public void onTaskStageChanged(int taskId, int stage, boolean visible) {
-                for (int i = 0; i < mExecutors.size(); i++) {
-                    final int index = i;
-                    mExecutors.valueAt(index).execute(() -> {
-                        mExecutors.keyAt(index).onTaskStageChanged(taskId, stage, visible);
-                    });
-                }
-            }
-
-            @Override
-            public void onSplitVisibilityChanged(boolean visible) {
-                for (int i = 0; i < mExecutors.size(); i++) {
-                    final int index = i;
-                    mExecutors.valueAt(index).execute(() -> {
-                        mExecutors.keyAt(index).onSplitVisibilityChanged(visible);
-                    });
-                }
-            }
-        };
-
-        @Override
-        public ISplitScreen createExternalInterface() {
-            if (mISplitScreen != null) {
-                mISplitScreen.invalidate();
-            }
-            mISplitScreen = new ISplitScreenImpl(SplitScreenController.this);
-            return mISplitScreen;
-        }
-
-        @Override
-        public void onKeyguardOccludedChanged(boolean occluded) {
-            mMainExecutor.execute(() -> {
-                SplitScreenController.this.onKeyguardOccludedChanged(occluded);
-            });
-        }
-
-        @Override
-        public void registerSplitScreenListener(SplitScreenListener listener, Executor executor) {
-            if (mExecutors.containsKey(listener)) return;
-
-            mMainExecutor.execute(() -> {
-                if (mExecutors.size() == 0) {
-                    SplitScreenController.this.registerSplitScreenListener(mListener);
-                }
-
-                mExecutors.put(listener, executor);
-            });
-
-            executor.execute(() -> {
-                mStageCoordinator.sendStatusToListener(listener);
-            });
-        }
-
-        @Override
-        public void unregisterSplitScreenListener(SplitScreenListener listener) {
-            mMainExecutor.execute(() -> {
-                mExecutors.remove(listener);
-
-                if (mExecutors.size() == 0) {
-                    SplitScreenController.this.unregisterSplitScreenListener(mListener);
-                }
-            });
-        }
-
-        @Override
-        public void onKeyguardVisibilityChanged(boolean showing) {
-            mMainExecutor.execute(() -> {
-                SplitScreenController.this.onKeyguardVisibilityChanged(showing);
-            });
-        }
-    }
-
-    /**
-     * The interface for calls from outside the host process.
-     */
-    @BinderThread
-    private static class ISplitScreenImpl extends ISplitScreen.Stub {
-        private SplitScreenController mController;
-        private ISplitScreenListener mListener;
-        private final SplitScreen.SplitScreenListener mSplitScreenListener =
-                new SplitScreen.SplitScreenListener() {
-                    @Override
-                    public void onStagePositionChanged(int stage, int position) {
-                        try {
-                            if (mListener != null) {
-                                mListener.onStagePositionChanged(stage, position);
-                            }
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "onStagePositionChanged", e);
-                        }
-                    }
-
-                    @Override
-                    public void onTaskStageChanged(int taskId, int stage, boolean visible) {
-                        try {
-                            if (mListener != null) {
-                                mListener.onTaskStageChanged(taskId, stage, visible);
-                            }
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "onTaskStageChanged", e);
-                        }
-                    }
-                };
-        private final IBinder.DeathRecipient mListenerDeathRecipient =
-                new IBinder.DeathRecipient() {
-                    @Override
-                    @BinderThread
-                    public void binderDied() {
-                        final SplitScreenController controller = mController;
-                        controller.getRemoteCallExecutor().execute(() -> {
-                            mListener = null;
-                            controller.unregisterSplitScreenListener(mSplitScreenListener);
-                        });
-                    }
-                };
-
-        public ISplitScreenImpl(SplitScreenController controller) {
-            mController = controller;
-        }
-
-        /**
-         * Invalidates this instance, preventing future calls from updating the controller.
-         */
-        void invalidate() {
-            mController = null;
-        }
-
-        @Override
-        public void registerSplitScreenListener(ISplitScreenListener listener) {
-            executeRemoteCallWithTaskPermission(mController, "registerSplitScreenListener",
-                    (controller) -> {
-                        if (mListener != null) {
-                            mListener.asBinder().unlinkToDeath(mListenerDeathRecipient,
-                                    0 /* flags */);
-                        }
-                        if (listener != null) {
-                            try {
-                                listener.asBinder().linkToDeath(mListenerDeathRecipient,
-                                        0 /* flags */);
-                            } catch (RemoteException e) {
-                                Slog.e(TAG, "Failed to link to death");
-                                return;
-                            }
-                        }
-                        mListener = listener;
-                        controller.registerSplitScreenListener(mSplitScreenListener);
-                    });
-        }
-
-        @Override
-        public void unregisterSplitScreenListener(ISplitScreenListener listener) {
-            executeRemoteCallWithTaskPermission(mController, "unregisterSplitScreenListener",
-                    (controller) -> {
-                        if (mListener != null) {
-                            mListener.asBinder().unlinkToDeath(mListenerDeathRecipient,
-                                    0 /* flags */);
-                        }
-                        mListener = null;
-                        controller.unregisterSplitScreenListener(mSplitScreenListener);
-                    });
-        }
-
-        @Override
-        public void exitSplitScreen(int toTopTaskId) {
-            executeRemoteCallWithTaskPermission(mController, "exitSplitScreen",
-                    (controller) -> {
-                        controller.exitSplitScreen(toTopTaskId,
-                                FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__UNKNOWN_EXIT);
-                    });
-        }
-
-        @Override
-        public void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
-            executeRemoteCallWithTaskPermission(mController, "exitSplitScreenOnHide",
-                    (controller) -> {
-                        controller.exitSplitScreenOnHide(exitSplitScreenOnHide);
-                    });
-        }
-
-        @Override
-        public void setSideStageVisibility(boolean visible) {
-            executeRemoteCallWithTaskPermission(mController, "setSideStageVisibility",
-                    (controller) -> {
-                        controller.setSideStageVisibility(visible);
-                    });
-        }
-
-        @Override
-        public void removeFromSideStage(int taskId) {
-            executeRemoteCallWithTaskPermission(mController, "removeFromSideStage",
-                    (controller) -> {
-                        controller.removeFromSideStage(taskId);
-                    });
-        }
-
-        @Override
-        public void startTask(int taskId, int stage, int position, @Nullable Bundle options) {
-            executeRemoteCallWithTaskPermission(mController, "startTask",
-                    (controller) -> {
-                        controller.startTask(taskId, position, options);
-                    });
-        }
-
-        @Override
-        public void startTasksWithLegacyTransition(int mainTaskId, @Nullable Bundle mainOptions,
-                int sideTaskId, @Nullable Bundle sideOptions, @SplitPosition int sidePosition,
-                RemoteAnimationAdapter adapter) {
-            executeRemoteCallWithTaskPermission(mController, "startTasks",
-                    (controller) -> controller.mStageCoordinator.startTasksWithLegacyTransition(
-                            mainTaskId, mainOptions, sideTaskId, sideOptions, sidePosition,
-                            adapter));
-        }
-
-        @Override
-        public void startTasks(int mainTaskId, @Nullable Bundle mainOptions,
-                int sideTaskId, @Nullable Bundle sideOptions,
-                @SplitPosition int sidePosition,
-                @Nullable RemoteTransition remoteTransition) {
-            executeRemoteCallWithTaskPermission(mController, "startTasks",
-                    (controller) -> controller.mStageCoordinator.startTasks(mainTaskId, mainOptions,
-                            sideTaskId, sideOptions, sidePosition, remoteTransition));
-        }
-
-        @Override
-        public void startShortcut(String packageName, String shortcutId, int stage, int position,
-                @Nullable Bundle options, UserHandle user) {
-            executeRemoteCallWithTaskPermission(mController, "startShortcut",
-                    (controller) -> {
-                        controller.startShortcut(packageName, shortcutId, position,
-                                options, user);
-                    });
-        }
-
-        @Override
-        public void startIntent(PendingIntent intent, Intent fillInIntent, int stage, int position,
-                @Nullable Bundle options) {
-            executeRemoteCallWithTaskPermission(mController, "startIntent",
-                    (controller) -> {
-                        controller.startIntent(intent, fillInIntent, position, options);
-                    });
-        }
-
-        @Override
-        public RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel,
-                RemoteAnimationTarget[] apps) {
-            final RemoteAnimationTarget[][] out = new RemoteAnimationTarget[][]{null};
-            executeRemoteCallWithTaskPermission(mController, "onGoingToRecentsLegacy",
-                    (controller) -> out[0] = controller.onGoingToRecentsLegacy(cancel, apps),
-                    true /* blocking */);
-            return out[0];
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreenTransitions.java
deleted file mode 100644
index 0183654..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitScreenTransitions.java
+++ /dev/null
@@ -1,292 +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.wm.shell.stagesplit;
-
-import static android.view.WindowManager.TRANSIT_CHANGE;
-import static android.view.WindowManager.TRANSIT_CLOSE;
-import static android.view.WindowManager.TRANSIT_OPEN;
-import static android.view.WindowManager.TRANSIT_TO_BACK;
-import static android.view.WindowManager.TRANSIT_TO_FRONT;
-import static android.window.TransitionInfo.FLAG_FIRST_CUSTOM;
-
-import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_DISMISS_SNAP;
-import static com.android.wm.shell.transition.Transitions.isOpeningType;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.graphics.Rect;
-import android.os.IBinder;
-import android.view.SurfaceControl;
-import android.view.WindowManager;
-import android.window.RemoteTransition;
-import android.window.TransitionInfo;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
-
-import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.transition.OneShotRemoteHandler;
-import com.android.wm.shell.transition.Transitions;
-
-import java.util.ArrayList;
-
-/** Manages transition animations for split-screen. */
-class SplitScreenTransitions {
-    private static final String TAG = "SplitScreenTransitions";
-
-    /** Flag applied to a transition change to identify it as a divider bar for animation. */
-    public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM;
-
-    private final TransactionPool mTransactionPool;
-    private final Transitions mTransitions;
-    private final Runnable mOnFinish;
-
-    IBinder mPendingDismiss = null;
-    IBinder mPendingEnter = null;
-
-    private IBinder mAnimatingTransition = null;
-    private OneShotRemoteHandler mRemoteHandler = null;
-
-    private Transitions.TransitionFinishCallback mRemoteFinishCB = (wct, wctCB) -> {
-        if (wct != null || wctCB != null) {
-            throw new UnsupportedOperationException("finish transactions not supported yet.");
-        }
-        onFinish();
-    };
-
-    /** Keeps track of currently running animations */
-    private final ArrayList<Animator> mAnimations = new ArrayList<>();
-
-    private Transitions.TransitionFinishCallback mFinishCallback = null;
-    private SurfaceControl.Transaction mFinishTransaction;
-
-    SplitScreenTransitions(@NonNull TransactionPool pool, @NonNull Transitions transitions,
-            @NonNull Runnable onFinishCallback) {
-        mTransactionPool = pool;
-        mTransitions = transitions;
-        mOnFinish = onFinishCallback;
-    }
-
-    void playAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
-            @NonNull SurfaceControl.Transaction startTransaction,
-            @NonNull SurfaceControl.Transaction finishTransaction,
-            @NonNull Transitions.TransitionFinishCallback finishCallback,
-            @NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot) {
-        mFinishCallback = finishCallback;
-        mAnimatingTransition = transition;
-        if (mRemoteHandler != null) {
-            mRemoteHandler.startAnimation(transition, info, startTransaction, finishTransaction,
-                    mRemoteFinishCB);
-            mRemoteHandler = null;
-            return;
-        }
-        playInternalAnimation(transition, info, startTransaction, mainRoot, sideRoot);
-    }
-
-    private void playInternalAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
-            @NonNull SurfaceControl.Transaction t, @NonNull WindowContainerToken mainRoot,
-            @NonNull WindowContainerToken sideRoot) {
-        mFinishTransaction = mTransactionPool.acquire();
-
-        // Play some place-holder fade animations
-        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
-            final TransitionInfo.Change change = info.getChanges().get(i);
-            final SurfaceControl leash = change.getLeash();
-            final int mode = info.getChanges().get(i).getMode();
-
-            if (mode == TRANSIT_CHANGE) {
-                if (change.getParent() != null) {
-                    // This is probably reparented, so we want the parent to be immediately visible
-                    final TransitionInfo.Change parentChange = info.getChange(change.getParent());
-                    t.show(parentChange.getLeash());
-                    t.setAlpha(parentChange.getLeash(), 1.f);
-                    // and then animate this layer outside the parent (since, for example, this is
-                    // the home task animating from fullscreen to part-screen).
-                    t.reparent(leash, info.getRootLeash());
-                    t.setLayer(leash, info.getChanges().size() - i);
-                    // build the finish reparent/reposition
-                    mFinishTransaction.reparent(leash, parentChange.getLeash());
-                    mFinishTransaction.setPosition(leash,
-                            change.getEndRelOffset().x, change.getEndRelOffset().y);
-                }
-                // TODO(shell-transitions): screenshot here
-                final Rect startBounds = new Rect(change.getStartAbsBounds());
-                final Rect endBounds = new Rect(change.getEndAbsBounds());
-                startBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y);
-                endBounds.offset(-info.getRootOffset().x, -info.getRootOffset().y);
-                startExampleResizeAnimation(leash, startBounds, endBounds);
-            }
-            if (change.getParent() != null) {
-                continue;
-            }
-
-            if (transition == mPendingEnter && (mainRoot.equals(change.getContainer())
-                    || sideRoot.equals(change.getContainer()))) {
-                t.setWindowCrop(leash, change.getStartAbsBounds().width(),
-                        change.getStartAbsBounds().height());
-            }
-            boolean isOpening = isOpeningType(info.getType());
-            if (isOpening && (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
-                // fade in
-                startExampleAnimation(leash, true /* show */);
-            } else if (!isOpening && (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK)) {
-                // fade out
-                if (info.getType() == TRANSIT_SPLIT_DISMISS_SNAP) {
-                    // Dismissing via snap-to-top/bottom means that the dismissed task is already
-                    // not-visible (usually cropped to oblivion) so immediately set its alpha to 0
-                    // and don't animate it so it doesn't pop-in when reparented.
-                    t.setAlpha(leash, 0.f);
-                } else {
-                    startExampleAnimation(leash, false /* show */);
-                }
-            }
-        }
-        t.apply();
-        onFinish();
-    }
-
-    /** Starts a transition to enter split with a remote transition animator. */
-    IBinder startEnterTransition(@WindowManager.TransitionType int transitType,
-            @NonNull WindowContainerTransaction wct, @Nullable RemoteTransition remoteTransition,
-            @NonNull Transitions.TransitionHandler handler) {
-        if (remoteTransition != null) {
-            // Wrapping it for ease-of-use (OneShot handles all the binder linking/death stuff)
-            mRemoteHandler = new OneShotRemoteHandler(
-                    mTransitions.getMainExecutor(), remoteTransition);
-        }
-        final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
-        mPendingEnter = transition;
-        if (mRemoteHandler != null) {
-            mRemoteHandler.setTransition(transition);
-        }
-        return transition;
-    }
-
-    /** Starts a transition for dismissing split after dragging the divider to a screen edge */
-    IBinder startSnapToDismiss(@NonNull WindowContainerTransaction wct,
-            @NonNull Transitions.TransitionHandler handler) {
-        final IBinder transition = mTransitions.startTransition(
-                TRANSIT_SPLIT_DISMISS_SNAP, wct, handler);
-        mPendingDismiss = transition;
-        return transition;
-    }
-
-    void onFinish() {
-        if (!mAnimations.isEmpty()) return;
-        mOnFinish.run();
-        if (mFinishTransaction != null) {
-            mFinishTransaction.apply();
-            mTransactionPool.release(mFinishTransaction);
-            mFinishTransaction = null;
-        }
-        mFinishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
-        mFinishCallback = null;
-        if (mAnimatingTransition == mPendingEnter) {
-            mPendingEnter = null;
-        }
-        if (mAnimatingTransition == mPendingDismiss) {
-            mPendingDismiss = null;
-        }
-        mAnimatingTransition = null;
-    }
-
-    // TODO(shell-transitions): real animations
-    private void startExampleAnimation(@NonNull SurfaceControl leash, boolean show) {
-        final float end = show ? 1.f : 0.f;
-        final float start = 1.f - end;
-        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-        final ValueAnimator va = ValueAnimator.ofFloat(start, end);
-        va.setDuration(500);
-        va.addUpdateListener(animation -> {
-            float fraction = animation.getAnimatedFraction();
-            transaction.setAlpha(leash, start * (1.f - fraction) + end * fraction);
-            transaction.apply();
-        });
-        final Runnable finisher = () -> {
-            transaction.setAlpha(leash, end);
-            transaction.apply();
-            mTransactionPool.release(transaction);
-            mTransitions.getMainExecutor().execute(() -> {
-                mAnimations.remove(va);
-                onFinish();
-            });
-        };
-        va.addListener(new Animator.AnimatorListener() {
-            @Override
-            public void onAnimationStart(Animator animation) { }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                finisher.run();
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                finisher.run();
-            }
-
-            @Override
-            public void onAnimationRepeat(Animator animation) { }
-        });
-        mAnimations.add(va);
-        mTransitions.getAnimExecutor().execute(va::start);
-    }
-
-    // TODO(shell-transitions): real animations
-    private void startExampleResizeAnimation(@NonNull SurfaceControl leash,
-            @NonNull Rect startBounds, @NonNull Rect endBounds) {
-        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-        final ValueAnimator va = ValueAnimator.ofFloat(0.f, 1.f);
-        va.setDuration(500);
-        va.addUpdateListener(animation -> {
-            float fraction = animation.getAnimatedFraction();
-            transaction.setWindowCrop(leash,
-                    (int) (startBounds.width() * (1.f - fraction) + endBounds.width() * fraction),
-                    (int) (startBounds.height() * (1.f - fraction)
-                            + endBounds.height() * fraction));
-            transaction.setPosition(leash,
-                    startBounds.left * (1.f - fraction) + endBounds.left * fraction,
-                    startBounds.top * (1.f - fraction) + endBounds.top * fraction);
-            transaction.apply();
-        });
-        final Runnable finisher = () -> {
-            transaction.setWindowCrop(leash, 0, 0);
-            transaction.setPosition(leash, endBounds.left, endBounds.top);
-            transaction.apply();
-            mTransactionPool.release(transaction);
-            mTransitions.getMainExecutor().execute(() -> {
-                mAnimations.remove(va);
-                onFinish();
-            });
-        };
-        va.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                finisher.run();
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                finisher.run();
-            }
-        });
-        mAnimations.add(va);
-        mTransitions.getAnimExecutor().execute(va::start);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitscreenEventLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitscreenEventLogger.java
deleted file mode 100644
index e185039..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/SplitscreenEventLogger.java
+++ /dev/null
@@ -1,324 +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.wm.shell.stagesplit;
-
-import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__OVERVIEW;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
-
-import com.android.internal.logging.InstanceId;
-import com.android.internal.logging.InstanceIdSequence;
-import com.android.internal.util.FrameworkStatsLog;
-import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
-
-/**
- * Helper class that to log Drag & Drop UIEvents for a single session, see also go/uievent
- */
-public class SplitscreenEventLogger {
-
-    // Used to generate instance ids for this drag if one is not provided
-    private final InstanceIdSequence mIdSequence;
-
-    // The instance id for the current splitscreen session (from start to end)
-    private InstanceId mLoggerSessionId;
-
-    // Drag info
-    private @SplitPosition int mDragEnterPosition;
-    private InstanceId mDragEnterSessionId;
-
-    // For deduping async events
-    private int mLastMainStagePosition = -1;
-    private int mLastMainStageUid = -1;
-    private int mLastSideStagePosition = -1;
-    private int mLastSideStageUid = -1;
-    private float mLastSplitRatio = -1f;
-
-    public SplitscreenEventLogger() {
-        mIdSequence = new InstanceIdSequence(Integer.MAX_VALUE);
-    }
-
-    /**
-     * Return whether a splitscreen session has started.
-     */
-    public boolean hasStartedSession() {
-        return mLoggerSessionId != null;
-    }
-
-    /**
-     * May be called before logEnter() to indicate that the session was started from a drag.
-     */
-    public void enterRequestedByDrag(@SplitPosition int position, InstanceId dragSessionId) {
-        mDragEnterPosition = position;
-        mDragEnterSessionId = dragSessionId;
-    }
-
-    /**
-     * Logs when the user enters splitscreen.
-     */
-    public void logEnter(float splitRatio,
-            @SplitPosition int mainStagePosition, int mainStageUid,
-            @SplitPosition int sideStagePosition, int sideStageUid,
-            boolean isLandscape) {
-        mLoggerSessionId = mIdSequence.newInstanceId();
-        int enterReason = mDragEnterPosition != SPLIT_POSITION_UNDEFINED
-                ? getDragEnterReasonFromSplitPosition(mDragEnterPosition, isLandscape)
-                : SPLITSCREEN_UICHANGED__ENTER_REASON__OVERVIEW;
-        updateMainStageState(getMainStagePositionFromSplitPosition(mainStagePosition, isLandscape),
-                mainStageUid);
-        updateSideStageState(getSideStagePositionFromSplitPosition(sideStagePosition, isLandscape),
-                sideStageUid);
-        updateSplitRatioState(splitRatio);
-        FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
-                FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__ENTER,
-                enterReason,
-                0 /* exitReason */,
-                splitRatio,
-                mLastMainStagePosition,
-                mLastMainStageUid,
-                mLastSideStagePosition,
-                mLastSideStageUid,
-                mDragEnterSessionId != null ? mDragEnterSessionId.getId() : 0,
-                mLoggerSessionId.getId());
-    }
-
-    /**
-     * Logs when the user exits splitscreen.  Only one of the main or side stages should be
-     * specified to indicate which position was focused as a part of exiting (both can be unset).
-     */
-    public void logExit(int exitReason, @SplitPosition int mainStagePosition, int mainStageUid,
-            @SplitPosition int sideStagePosition, int sideStageUid, boolean isLandscape) {
-        if (mLoggerSessionId == null) {
-            // Ignore changes until we've started logging the session
-            return;
-        }
-        if ((mainStagePosition != SPLIT_POSITION_UNDEFINED
-                && sideStagePosition != SPLIT_POSITION_UNDEFINED)
-                        || (mainStageUid != 0 && sideStageUid != 0)) {
-            throw new IllegalArgumentException("Only main or side stage should be set");
-        }
-        FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
-                FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__EXIT,
-                0 /* enterReason */,
-                exitReason,
-                0f /* splitRatio */,
-                getMainStagePositionFromSplitPosition(mainStagePosition, isLandscape),
-                mainStageUid,
-                getSideStagePositionFromSplitPosition(sideStagePosition, isLandscape),
-                sideStageUid,
-                0 /* dragInstanceId */,
-                mLoggerSessionId.getId());
-
-        // Reset states
-        mLoggerSessionId = null;
-        mDragEnterPosition = SPLIT_POSITION_UNDEFINED;
-        mDragEnterSessionId = null;
-        mLastMainStagePosition = -1;
-        mLastMainStageUid = -1;
-        mLastSideStagePosition = -1;
-        mLastSideStageUid = -1;
-    }
-
-    /**
-     * Logs when an app in the main stage changes.
-     */
-    public void logMainStageAppChange(@SplitPosition int mainStagePosition, int mainStageUid,
-            boolean isLandscape) {
-        if (mLoggerSessionId == null) {
-            // Ignore changes until we've started logging the session
-            return;
-        }
-        if (!updateMainStageState(getMainStagePositionFromSplitPosition(mainStagePosition,
-                isLandscape), mainStageUid)) {
-            // Ignore if there are no user perceived changes
-            return;
-        }
-
-        FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
-                FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__APP_CHANGE,
-                0 /* enterReason */,
-                0 /* exitReason */,
-                0f /* splitRatio */,
-                mLastMainStagePosition,
-                mLastMainStageUid,
-                0 /* sideStagePosition */,
-                0 /* sideStageUid */,
-                0 /* dragInstanceId */,
-                mLoggerSessionId.getId());
-    }
-
-    /**
-     * Logs when an app in the side stage changes.
-     */
-    public void logSideStageAppChange(@SplitPosition int sideStagePosition, int sideStageUid,
-            boolean isLandscape) {
-        if (mLoggerSessionId == null) {
-            // Ignore changes until we've started logging the session
-            return;
-        }
-        if (!updateSideStageState(getSideStagePositionFromSplitPosition(sideStagePosition,
-                isLandscape), sideStageUid)) {
-            // Ignore if there are no user perceived changes
-            return;
-        }
-
-        FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
-                FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__APP_CHANGE,
-                0 /* enterReason */,
-                0 /* exitReason */,
-                0f /* splitRatio */,
-                0 /* mainStagePosition */,
-                0 /* mainStageUid */,
-                mLastSideStagePosition,
-                mLastSideStageUid,
-                0 /* dragInstanceId */,
-                mLoggerSessionId.getId());
-    }
-
-    /**
-     * Logs when the splitscreen ratio changes.
-     */
-    public void logResize(float splitRatio) {
-        if (mLoggerSessionId == null) {
-            // Ignore changes until we've started logging the session
-            return;
-        }
-        if (splitRatio <= 0f || splitRatio >= 1f) {
-            // Don't bother reporting resizes that end up dismissing the split, that will be logged
-            // via the exit event
-            return;
-        }
-        if (!updateSplitRatioState(splitRatio)) {
-            // Ignore if there are no user perceived changes
-            return;
-        }
-        FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
-                FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__RESIZE,
-                0 /* enterReason */,
-                0 /* exitReason */,
-                mLastSplitRatio,
-                0 /* mainStagePosition */, 0 /* mainStageUid */,
-                0 /* sideStagePosition */, 0 /* sideStageUid */,
-                0 /* dragInstanceId */,
-                mLoggerSessionId.getId());
-    }
-
-    /**
-     * Logs when the apps in splitscreen are swapped.
-     */
-    public void logSwap(@SplitPosition int mainStagePosition, int mainStageUid,
-            @SplitPosition int sideStagePosition, int sideStageUid, boolean isLandscape) {
-        if (mLoggerSessionId == null) {
-            // Ignore changes until we've started logging the session
-            return;
-        }
-
-        updateMainStageState(getMainStagePositionFromSplitPosition(mainStagePosition, isLandscape),
-                mainStageUid);
-        updateSideStageState(getSideStagePositionFromSplitPosition(sideStagePosition, isLandscape),
-                sideStageUid);
-        FrameworkStatsLog.write(FrameworkStatsLog.SPLITSCREEN_UI_CHANGED,
-                FrameworkStatsLog.SPLITSCREEN_UICHANGED__ACTION__SWAP,
-                0 /* enterReason */,
-                0 /* exitReason */,
-                0f /* splitRatio */,
-                mLastMainStagePosition,
-                mLastMainStageUid,
-                mLastSideStagePosition,
-                mLastSideStageUid,
-                0 /* dragInstanceId */,
-                mLoggerSessionId.getId());
-    }
-
-    private boolean updateMainStageState(int mainStagePosition, int mainStageUid) {
-        boolean changed = (mLastMainStagePosition != mainStagePosition)
-                || (mLastMainStageUid != mainStageUid);
-        if (!changed) {
-            return false;
-        }
-
-        mLastMainStagePosition = mainStagePosition;
-        mLastMainStageUid = mainStageUid;
-        return true;
-    }
-
-    private boolean updateSideStageState(int sideStagePosition, int sideStageUid) {
-        boolean changed = (mLastSideStagePosition != sideStagePosition)
-                || (mLastSideStageUid != sideStageUid);
-        if (!changed) {
-            return false;
-        }
-
-        mLastSideStagePosition = sideStagePosition;
-        mLastSideStageUid = sideStageUid;
-        return true;
-    }
-
-    private boolean updateSplitRatioState(float splitRatio) {
-        boolean changed = Float.compare(mLastSplitRatio, splitRatio) != 0;
-        if (!changed) {
-            return false;
-        }
-
-        mLastSplitRatio = splitRatio;
-        return true;
-    }
-
-    public int getDragEnterReasonFromSplitPosition(@SplitPosition int position,
-            boolean isLandscape) {
-        if (isLandscape) {
-            return position == SPLIT_POSITION_TOP_OR_LEFT
-                    ? FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__DRAG_LEFT
-                    : FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__DRAG_RIGHT;
-        } else {
-            return position == SPLIT_POSITION_TOP_OR_LEFT
-                    ? FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__DRAG_TOP
-                    : FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__DRAG_BOTTOM;
-        }
-    }
-
-    private int getMainStagePositionFromSplitPosition(@SplitPosition int position,
-            boolean isLandscape) {
-        if (position == SPLIT_POSITION_UNDEFINED) {
-            return 0;
-        }
-        if (isLandscape) {
-            return position == SPLIT_POSITION_TOP_OR_LEFT
-                    ? FrameworkStatsLog.SPLITSCREEN_UICHANGED__MAIN_STAGE_POSITION__LEFT
-                    : FrameworkStatsLog.SPLITSCREEN_UICHANGED__MAIN_STAGE_POSITION__RIGHT;
-        } else {
-            return position == SPLIT_POSITION_TOP_OR_LEFT
-                    ? FrameworkStatsLog.SPLITSCREEN_UICHANGED__MAIN_STAGE_POSITION__TOP
-                    : FrameworkStatsLog.SPLITSCREEN_UICHANGED__MAIN_STAGE_POSITION__BOTTOM;
-        }
-    }
-
-    private int getSideStagePositionFromSplitPosition(@SplitPosition int position,
-            boolean isLandscape) {
-        if (position == SPLIT_POSITION_UNDEFINED) {
-            return 0;
-        }
-        if (isLandscape) {
-            return position == SPLIT_POSITION_TOP_OR_LEFT
-                    ? FrameworkStatsLog.SPLITSCREEN_UICHANGED__SIDE_STAGE_POSITION__LEFT
-                    : FrameworkStatsLog.SPLITSCREEN_UICHANGED__SIDE_STAGE_POSITION__RIGHT;
-        } else {
-            return position == SPLIT_POSITION_TOP_OR_LEFT
-                    ? FrameworkStatsLog.SPLITSCREEN_UICHANGED__SIDE_STAGE_POSITION__TOP
-                    : FrameworkStatsLog.SPLITSCREEN_UICHANGED__SIDE_STAGE_POSITION__BOTTOM;
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java
deleted file mode 100644
index de0feee..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java
+++ /dev/null
@@ -1,1333 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.stagesplit;
-
-import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.TRANSIT_OPEN;
-import static android.view.WindowManager.TRANSIT_TO_BACK;
-import static android.view.WindowManager.TRANSIT_TO_FRONT;
-import static android.view.WindowManager.transitTypeToString;
-
-import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__APP_DOES_NOT_SUPPORT_MULTIWINDOW;
-import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__APP_FINISHED;
-import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DEVICE_FOLDED;
-import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DRAG_DIVIDER;
-import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME;
-import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED_SHOW_ON_TOP;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
-import static com.android.wm.shell.stagesplit.SplitScreen.STAGE_TYPE_MAIN;
-import static com.android.wm.shell.stagesplit.SplitScreen.STAGE_TYPE_SIDE;
-import static com.android.wm.shell.stagesplit.SplitScreen.STAGE_TYPE_UNDEFINED;
-import static com.android.wm.shell.stagesplit.SplitScreen.stageTypeToString;
-import static com.android.wm.shell.stagesplit.SplitScreenTransitions.FLAG_IS_DIVIDER_BAR;
-import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
-import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_DISMISS_SNAP;
-import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE;
-import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
-import static com.android.wm.shell.transition.Transitions.isClosingType;
-import static com.android.wm.shell.transition.Transitions.isOpeningType;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.app.ActivityOptions;
-import android.app.ActivityTaskManager;
-import android.app.PendingIntent;
-import android.app.WindowConfiguration;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Rect;
-import android.hardware.devicestate.DeviceStateManager;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.Slog;
-import android.view.IRemoteAnimationFinishedCallback;
-import android.view.IRemoteAnimationRunner;
-import android.view.RemoteAnimationAdapter;
-import android.view.RemoteAnimationTarget;
-import android.view.SurfaceControl;
-import android.view.SurfaceSession;
-import android.view.WindowManager;
-import android.window.DisplayAreaInfo;
-import android.window.RemoteTransition;
-import android.window.TransitionInfo;
-import android.window.TransitionRequestInfo;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
-
-import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
-import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.DisplayInsetsController;
-import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.common.split.SplitLayout;
-import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
-import com.android.wm.shell.common.split.SplitWindowManager;
-import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import com.android.wm.shell.transition.Transitions;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import javax.inject.Provider;
-
-/**
- * Coordinates the staging (visibility, sizing, ...) of the split-screen {@link MainStage} and
- * {@link SideStage} stages.
- * Some high-level rules:
- * - The {@link StageCoordinator} is only considered active if the {@link SideStage} contains at
- * least one child task.
- * - The {@link MainStage} should only have children if the coordinator is active.
- * - The {@link SplitLayout} divider is only visible if both the {@link MainStage}
- * and {@link SideStage} are visible.
- * - The {@link MainStage} configuration is fullscreen when the {@link SideStage} isn't visible.
- * This rules are mostly implemented in {@link #onStageVisibilityChanged(StageListenerImpl)} and
- * {@link #onStageHasChildrenChanged(StageListenerImpl).}
- */
-class StageCoordinator implements SplitLayout.SplitLayoutHandler,
-        RootTaskDisplayAreaOrganizer.RootTaskDisplayAreaListener, Transitions.TransitionHandler {
-
-    private static final String TAG = StageCoordinator.class.getSimpleName();
-
-    /** internal value for mDismissTop that represents no dismiss */
-    private static final int NO_DISMISS = -2;
-
-    private final SurfaceSession mSurfaceSession = new SurfaceSession();
-
-    private final MainStage mMainStage;
-    private final StageListenerImpl mMainStageListener = new StageListenerImpl();
-    private final StageTaskUnfoldController mMainUnfoldController;
-    private final SideStage mSideStage;
-    private final StageListenerImpl mSideStageListener = new StageListenerImpl();
-    private final StageTaskUnfoldController mSideUnfoldController;
-    @SplitPosition
-    private int mSideStagePosition = SPLIT_POSITION_BOTTOM_OR_RIGHT;
-
-    private final int mDisplayId;
-    private SplitLayout mSplitLayout;
-    private boolean mDividerVisible;
-    private final SyncTransactionQueue mSyncQueue;
-    private final RootTaskDisplayAreaOrganizer mRootTDAOrganizer;
-    private final ShellTaskOrganizer mTaskOrganizer;
-    private DisplayAreaInfo mDisplayAreaInfo;
-    private final Context mContext;
-    private final List<SplitScreen.SplitScreenListener> mListeners = new ArrayList<>();
-    private final DisplayImeController mDisplayImeController;
-    private final DisplayInsetsController mDisplayInsetsController;
-    private final SplitScreenTransitions mSplitTransitions;
-    private final SplitscreenEventLogger mLogger;
-    private boolean mExitSplitScreenOnHide;
-    private boolean mKeyguardOccluded;
-
-    // TODO(b/187041611): remove this flag after totally deprecated legacy split
-    /** Whether the device is supporting legacy split or not. */
-    private boolean mUseLegacySplit;
-
-    @SplitScreen.StageType private int mDismissTop = NO_DISMISS;
-
-    /** The target stage to dismiss to when unlock after folded. */
-    @SplitScreen.StageType private int mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
-
-    private final Runnable mOnTransitionAnimationComplete = () -> {
-        // If still playing, let it finish.
-        if (!isSplitScreenVisible()) {
-            // Update divider state after animation so that it is still around and positioned
-            // properly for the animation itself.
-            setDividerVisibility(false);
-            mSplitLayout.resetDividerPosition();
-        }
-        mDismissTop = NO_DISMISS;
-    };
-
-    private final SplitWindowManager.ParentContainerCallbacks mParentContainerCallbacks =
-            new SplitWindowManager.ParentContainerCallbacks() {
-        @Override
-        public void attachToParentSurface(SurfaceControl.Builder b) {
-            mRootTDAOrganizer.attachToDisplayArea(mDisplayId, b);
-        }
-
-        @Override
-        public void onLeashReady(SurfaceControl leash) {
-            mSyncQueue.runInSync(t -> applyDividerVisibility(t));
-        }
-    };
-
-    StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
-            RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
-            DisplayImeController displayImeController,
-            DisplayInsetsController displayInsetsController, Transitions transitions,
-            TransactionPool transactionPool, SplitscreenEventLogger logger,
-            Provider<Optional<StageTaskUnfoldController>> unfoldControllerProvider) {
-        mContext = context;
-        mDisplayId = displayId;
-        mSyncQueue = syncQueue;
-        mRootTDAOrganizer = rootTDAOrganizer;
-        mTaskOrganizer = taskOrganizer;
-        mLogger = logger;
-        mMainUnfoldController = unfoldControllerProvider.get().orElse(null);
-        mSideUnfoldController = unfoldControllerProvider.get().orElse(null);
-
-        mMainStage = new MainStage(
-                mTaskOrganizer,
-                mDisplayId,
-                mMainStageListener,
-                mSyncQueue,
-                mSurfaceSession,
-                mMainUnfoldController);
-        mSideStage = new SideStage(
-                mContext,
-                mTaskOrganizer,
-                mDisplayId,
-                mSideStageListener,
-                mSyncQueue,
-                mSurfaceSession,
-                mSideUnfoldController);
-        mDisplayImeController = displayImeController;
-        mDisplayInsetsController = displayInsetsController;
-        mDisplayInsetsController.addInsetsChangedListener(mDisplayId, mSideStage);
-        mRootTDAOrganizer.registerListener(displayId, this);
-        final DeviceStateManager deviceStateManager =
-                mContext.getSystemService(DeviceStateManager.class);
-        deviceStateManager.registerCallback(taskOrganizer.getExecutor(),
-                new DeviceStateManager.FoldStateListener(mContext, this::onFoldedStateChanged));
-        mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
-                mOnTransitionAnimationComplete);
-        transitions.addHandler(this);
-    }
-
-    @VisibleForTesting
-    StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
-            RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
-            MainStage mainStage, SideStage sideStage, DisplayImeController displayImeController,
-            DisplayInsetsController displayInsetsController, SplitLayout splitLayout,
-            Transitions transitions, TransactionPool transactionPool,
-            SplitscreenEventLogger logger,
-            Provider<Optional<StageTaskUnfoldController>> unfoldControllerProvider) {
-        mContext = context;
-        mDisplayId = displayId;
-        mSyncQueue = syncQueue;
-        mRootTDAOrganizer = rootTDAOrganizer;
-        mTaskOrganizer = taskOrganizer;
-        mMainStage = mainStage;
-        mSideStage = sideStage;
-        mDisplayImeController = displayImeController;
-        mDisplayInsetsController = displayInsetsController;
-        mRootTDAOrganizer.registerListener(displayId, this);
-        mSplitLayout = splitLayout;
-        mSplitTransitions = new SplitScreenTransitions(transactionPool, transitions,
-                mOnTransitionAnimationComplete);
-        mMainUnfoldController = unfoldControllerProvider.get().orElse(null);
-        mSideUnfoldController = unfoldControllerProvider.get().orElse(null);
-        mLogger = logger;
-        transitions.addHandler(this);
-    }
-
-    @VisibleForTesting
-    SplitScreenTransitions getSplitTransitions() {
-        return mSplitTransitions;
-    }
-
-    boolean isSplitScreenVisible() {
-        return mSideStageListener.mVisible && mMainStageListener.mVisible;
-    }
-
-    boolean moveToSideStage(ActivityManager.RunningTaskInfo task,
-            @SplitPosition int sideStagePosition) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        setSideStagePosition(sideStagePosition, wct);
-        mMainStage.activate(getMainStageBounds(), wct);
-        mSideStage.addTask(task, getSideStageBounds(), wct);
-        mSyncQueue.queue(wct);
-        mSyncQueue.runInSync(
-                t -> updateSurfaceBounds(null /* layout */, t, false /* applyResizingOffset */));
-        return true;
-    }
-
-    boolean removeFromSideStage(int taskId) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-
-        /**
-         * {@link MainStage} will be deactivated in {@link #onStageHasChildrenChanged} if the
-         * {@link SideStage} no longer has children.
-         */
-        final boolean result = mSideStage.removeTask(taskId,
-                mMainStage.isActive() ? mMainStage.mRootTaskInfo.token : null,
-                wct);
-        mTaskOrganizer.applyTransaction(wct);
-        return result;
-    }
-
-    void setSideStageOutline(boolean enable) {
-        mSideStage.enableOutline(enable);
-    }
-
-    /** Starts 2 tasks in one transition. */
-    void startTasks(int mainTaskId, @Nullable Bundle mainOptions, int sideTaskId,
-            @Nullable Bundle sideOptions, @SplitPosition int sidePosition,
-            @Nullable RemoteTransition remoteTransition) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        mainOptions = mainOptions != null ? mainOptions : new Bundle();
-        sideOptions = sideOptions != null ? sideOptions : new Bundle();
-        setSideStagePosition(sidePosition, wct);
-
-        // Build a request WCT that will launch both apps such that task 0 is on the main stage
-        // while task 1 is on the side stage.
-        mMainStage.activate(getMainStageBounds(), wct);
-        mSideStage.setBounds(getSideStageBounds(), wct);
-
-        // Make sure the launch options will put tasks in the corresponding split roots
-        addActivityOptions(mainOptions, mMainStage);
-        addActivityOptions(sideOptions, mSideStage);
-
-        // Add task launch requests
-        wct.startTask(mainTaskId, mainOptions);
-        wct.startTask(sideTaskId, sideOptions);
-
-        mSplitTransitions.startEnterTransition(
-                TRANSIT_SPLIT_SCREEN_PAIR_OPEN, wct, remoteTransition, this);
-    }
-
-    /** Starts 2 tasks in one legacy transition. */
-    void startTasksWithLegacyTransition(int mainTaskId, @Nullable Bundle mainOptions,
-            int sideTaskId, @Nullable Bundle sideOptions, @SplitPosition int sidePosition,
-            RemoteAnimationAdapter adapter) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        // Need to add another wrapper here in shell so that we can inject the divider bar
-        // and also manage the process elevation via setRunningRemote
-        IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
-            @Override
-            public void onAnimationStart(@WindowManager.TransitionOldType int transit,
-                    RemoteAnimationTarget[] apps,
-                    RemoteAnimationTarget[] wallpapers,
-                    RemoteAnimationTarget[] nonApps,
-                    final IRemoteAnimationFinishedCallback finishedCallback) {
-                RemoteAnimationTarget[] augmentedNonApps =
-                        new RemoteAnimationTarget[nonApps.length + 1];
-                for (int i = 0; i < nonApps.length; ++i) {
-                    augmentedNonApps[i] = nonApps[i];
-                }
-                augmentedNonApps[augmentedNonApps.length - 1] = getDividerBarLegacyTarget();
-                try {
-                    ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(
-                            adapter.getCallingApplication());
-                    adapter.getRunner().onAnimationStart(transit, apps, wallpapers, nonApps,
-                            finishedCallback);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Error starting remote animation", e);
-                }
-            }
-
-            @Override
-            public void onAnimationCancelled(boolean isKeyguardOccluded) {
-                try {
-                    adapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Error starting remote animation", e);
-                }
-            }
-        };
-        RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(
-                wrapper, adapter.getDuration(), adapter.getStatusBarTransitionDelay());
-
-        if (mainOptions == null) {
-            mainOptions = ActivityOptions.makeRemoteAnimation(wrappedAdapter).toBundle();
-        } else {
-            ActivityOptions mainActivityOptions = ActivityOptions.fromBundle(mainOptions);
-            mainActivityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
-        }
-
-        sideOptions = sideOptions != null ? sideOptions : new Bundle();
-        setSideStagePosition(sidePosition, wct);
-
-        // Build a request WCT that will launch both apps such that task 0 is on the main stage
-        // while task 1 is on the side stage.
-        mMainStage.activate(getMainStageBounds(), wct);
-        mSideStage.setBounds(getSideStageBounds(), wct);
-
-        // Make sure the launch options will put tasks in the corresponding split roots
-        addActivityOptions(mainOptions, mMainStage);
-        addActivityOptions(sideOptions, mSideStage);
-
-        // Add task launch requests
-        wct.startTask(mainTaskId, mainOptions);
-        wct.startTask(sideTaskId, sideOptions);
-
-        // Using legacy transitions, so we can't use blast sync since it conflicts.
-        mTaskOrganizer.applyTransaction(wct);
-    }
-
-    public void startIntent(PendingIntent intent, Intent fillInIntent,
-            @SplitScreen.StageType int stage, @SplitPosition int position,
-            @androidx.annotation.Nullable Bundle options,
-            @Nullable RemoteTransition remoteTransition) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        options = resolveStartStage(stage, position, options, wct);
-        wct.sendPendingIntent(intent, fillInIntent, options);
-        mSplitTransitions.startEnterTransition(
-                TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, wct, remoteTransition, this);
-    }
-
-    Bundle resolveStartStage(@SplitScreen.StageType int stage,
-            @SplitPosition int position, @androidx.annotation.Nullable Bundle options,
-            @androidx.annotation.Nullable WindowContainerTransaction wct) {
-        switch (stage) {
-            case STAGE_TYPE_UNDEFINED: {
-                // Use the stage of the specified position is valid.
-                if (position != SPLIT_POSITION_UNDEFINED) {
-                    if (position == getSideStagePosition()) {
-                        options = resolveStartStage(STAGE_TYPE_SIDE, position, options, wct);
-                    } else {
-                        options = resolveStartStage(STAGE_TYPE_MAIN, position, options, wct);
-                    }
-                } else {
-                    // Exit split-screen and launch fullscreen since stage wasn't specified.
-                    prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, wct);
-                }
-                break;
-            }
-            case STAGE_TYPE_SIDE: {
-                if (position != SPLIT_POSITION_UNDEFINED) {
-                    setSideStagePosition(position, wct);
-                } else {
-                    position = getSideStagePosition();
-                }
-                if (options == null) {
-                    options = new Bundle();
-                }
-                updateActivityOptions(options, position);
-                break;
-            }
-            case STAGE_TYPE_MAIN: {
-                if (position != SPLIT_POSITION_UNDEFINED) {
-                    // Set the side stage opposite of what we want to the main stage.
-                    final int sideStagePosition = position == SPLIT_POSITION_TOP_OR_LEFT
-                            ? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT;
-                    setSideStagePosition(sideStagePosition, wct);
-                } else {
-                    position = getMainStagePosition();
-                }
-                if (options == null) {
-                    options = new Bundle();
-                }
-                updateActivityOptions(options, position);
-                break;
-            }
-            default:
-                throw new IllegalArgumentException("Unknown stage=" + stage);
-        }
-
-        return options;
-    }
-
-    @SplitPosition
-    int getSideStagePosition() {
-        return mSideStagePosition;
-    }
-
-    @SplitPosition
-    int getMainStagePosition() {
-        return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
-                ? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT;
-    }
-
-    void setSideStagePosition(@SplitPosition int sideStagePosition,
-            @Nullable WindowContainerTransaction wct) {
-        setSideStagePosition(sideStagePosition, true /* updateBounds */, wct);
-    }
-
-    private void setSideStagePosition(@SplitPosition int sideStagePosition, boolean updateBounds,
-            @Nullable WindowContainerTransaction wct) {
-        if (mSideStagePosition == sideStagePosition) return;
-        mSideStagePosition = sideStagePosition;
-        sendOnStagePositionChanged();
-
-        if (mSideStageListener.mVisible && updateBounds) {
-            if (wct == null) {
-                // onLayoutSizeChanged builds/applies a wct with the contents of updateWindowBounds.
-                onLayoutSizeChanged(mSplitLayout);
-            } else {
-                updateWindowBounds(mSplitLayout, wct);
-                updateUnfoldBounds();
-            }
-        }
-    }
-
-    void setSideStageVisibility(boolean visible) {
-        if (mSideStageListener.mVisible == visible) return;
-
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        mSideStage.setVisibility(visible, wct);
-        mTaskOrganizer.applyTransaction(wct);
-    }
-
-    void onKeyguardOccludedChanged(boolean occluded) {
-        // Do not exit split directly, because it needs to wait for task info update to determine
-        // which task should remain on top after split dismissed.
-        mKeyguardOccluded = occluded;
-    }
-
-    void onKeyguardVisibilityChanged(boolean showing) {
-        if (!showing && mMainStage.isActive()
-                && mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) {
-            exitSplitScreen(mTopStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
-                    SPLITSCREEN_UICHANGED__EXIT_REASON__DEVICE_FOLDED);
-        }
-    }
-
-    void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
-        mExitSplitScreenOnHide = exitSplitScreenOnHide;
-    }
-
-    void exitSplitScreen(int toTopTaskId, int exitReason) {
-        StageTaskListener childrenToTop = null;
-        if (mMainStage.containsTask(toTopTaskId)) {
-            childrenToTop = mMainStage;
-        } else if (mSideStage.containsTask(toTopTaskId)) {
-            childrenToTop = mSideStage;
-        }
-
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        if (childrenToTop != null) {
-            childrenToTop.reorderChild(toTopTaskId, true /* onTop */, wct);
-        }
-        applyExitSplitScreen(childrenToTop, wct, exitReason);
-    }
-
-    private void exitSplitScreen(StageTaskListener childrenToTop, int exitReason) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        applyExitSplitScreen(childrenToTop, wct, exitReason);
-    }
-
-    private void applyExitSplitScreen(
-            StageTaskListener childrenToTop,
-            WindowContainerTransaction wct, int exitReason) {
-        mSideStage.removeAllTasks(wct, childrenToTop == mSideStage);
-        mMainStage.deactivate(wct, childrenToTop == mMainStage);
-        mTaskOrganizer.applyTransaction(wct);
-        mSyncQueue.runInSync(t -> t
-                .setWindowCrop(mMainStage.mRootLeash, null)
-                .setWindowCrop(mSideStage.mRootLeash, null));
-        // Hide divider and reset its position.
-        setDividerVisibility(false);
-        mSplitLayout.resetDividerPosition();
-        mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
-        if (childrenToTop != null) {
-            logExitToStage(exitReason, childrenToTop == mMainStage);
-        } else {
-            logExit(exitReason);
-        }
-    }
-
-    /**
-     * Unlike exitSplitScreen, this takes a stagetype vs an actual stage-reference and populates
-     * an existing WindowContainerTransaction (rather than applying immediately). This is intended
-     * to be used when exiting split might be bundled with other window operations.
-     */
-    void prepareExitSplitScreen(@SplitScreen.StageType int stageToTop,
-            @NonNull WindowContainerTransaction wct) {
-        mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
-        mMainStage.deactivate(wct, stageToTop == STAGE_TYPE_MAIN);
-    }
-
-    void getStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
-        outTopOrLeftBounds.set(mSplitLayout.getBounds1());
-        outBottomOrRightBounds.set(mSplitLayout.getBounds2());
-    }
-
-    private void addActivityOptions(Bundle opts, StageTaskListener stage) {
-        opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, stage.mRootTaskInfo.token);
-    }
-
-    void updateActivityOptions(Bundle opts, @SplitPosition int position) {
-        addActivityOptions(opts, position == mSideStagePosition ? mSideStage : mMainStage);
-    }
-
-    void registerSplitScreenListener(SplitScreen.SplitScreenListener listener) {
-        if (mListeners.contains(listener)) return;
-        mListeners.add(listener);
-        sendStatusToListener(listener);
-    }
-
-    void unregisterSplitScreenListener(SplitScreen.SplitScreenListener listener) {
-        mListeners.remove(listener);
-    }
-
-    void sendStatusToListener(SplitScreen.SplitScreenListener listener) {
-        listener.onStagePositionChanged(STAGE_TYPE_MAIN, getMainStagePosition());
-        listener.onStagePositionChanged(STAGE_TYPE_SIDE, getSideStagePosition());
-        listener.onSplitVisibilityChanged(isSplitScreenVisible());
-        mSideStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_SIDE);
-        mMainStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_MAIN);
-    }
-
-    private void sendOnStagePositionChanged() {
-        for (int i = mListeners.size() - 1; i >= 0; --i) {
-            final SplitScreen.SplitScreenListener l = mListeners.get(i);
-            l.onStagePositionChanged(STAGE_TYPE_MAIN, getMainStagePosition());
-            l.onStagePositionChanged(STAGE_TYPE_SIDE, getSideStagePosition());
-        }
-    }
-
-    private void onStageChildTaskStatusChanged(StageListenerImpl stageListener, int taskId,
-            boolean present, boolean visible) {
-        int stage;
-        if (present) {
-            stage = stageListener == mSideStageListener ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN;
-        } else {
-            // No longer on any stage
-            stage = STAGE_TYPE_UNDEFINED;
-        }
-        if (stage == STAGE_TYPE_MAIN) {
-            mLogger.logMainStageAppChange(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
-                    mSplitLayout.isLandscape());
-        } else {
-            mLogger.logSideStageAppChange(getSideStagePosition(), mSideStage.getTopChildTaskUid(),
-                    mSplitLayout.isLandscape());
-        }
-
-        for (int i = mListeners.size() - 1; i >= 0; --i) {
-            mListeners.get(i).onTaskStageChanged(taskId, stage, visible);
-        }
-    }
-
-    private void sendSplitVisibilityChanged() {
-        for (int i = mListeners.size() - 1; i >= 0; --i) {
-            final SplitScreen.SplitScreenListener l = mListeners.get(i);
-            l.onSplitVisibilityChanged(mDividerVisible);
-        }
-
-        if (mMainUnfoldController != null && mSideUnfoldController != null) {
-            mMainUnfoldController.onSplitVisibilityChanged(mDividerVisible);
-            mSideUnfoldController.onSplitVisibilityChanged(mDividerVisible);
-        }
-    }
-
-    private void onStageRootTaskAppeared(StageListenerImpl stageListener) {
-        if (mMainStageListener.mHasRootTask && mSideStageListener.mHasRootTask) {
-            mUseLegacySplit = mContext.getResources().getBoolean(R.bool.config_useLegacySplit);
-            final WindowContainerTransaction wct = new WindowContainerTransaction();
-            // Make the stages adjacent to each other so they occlude what's behind them.
-            wct.setAdjacentRoots(mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token,
-                    true /* moveTogether */);
-
-            // Only sets side stage as launch-adjacent-flag-root when the device is not using legacy
-            // split to prevent new split behavior confusing users.
-            if (!mUseLegacySplit) {
-                wct.setLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token);
-            }
-
-            mTaskOrganizer.applyTransaction(wct);
-        }
-    }
-
-    private void onStageRootTaskVanished(StageListenerImpl stageListener) {
-        if (stageListener == mMainStageListener || stageListener == mSideStageListener) {
-            final WindowContainerTransaction wct = new WindowContainerTransaction();
-            // Deactivate the main stage if it no longer has a root task.
-            mMainStage.deactivate(wct);
-
-            if (!mUseLegacySplit) {
-                wct.clearLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token);
-            }
-
-            mTaskOrganizer.applyTransaction(wct);
-        }
-    }
-
-    private void setDividerVisibility(boolean visible) {
-        if (mDividerVisible == visible) return;
-        mDividerVisible = visible;
-        if (visible) {
-            mSplitLayout.init();
-            updateUnfoldBounds();
-        } else {
-            mSplitLayout.release();
-        }
-        sendSplitVisibilityChanged();
-    }
-
-    private void onStageVisibilityChanged(StageListenerImpl stageListener) {
-        final boolean sideStageVisible = mSideStageListener.mVisible;
-        final boolean mainStageVisible = mMainStageListener.mVisible;
-        final boolean bothStageVisible = sideStageVisible && mainStageVisible;
-        final boolean bothStageInvisible = !sideStageVisible && !mainStageVisible;
-        final boolean sameVisibility = sideStageVisible == mainStageVisible;
-        // Only add or remove divider when both visible or both invisible to avoid sometimes we only
-        // got one stage visibility changed for a moment and it will cause flicker.
-        if (sameVisibility) {
-            setDividerVisibility(bothStageVisible);
-        }
-
-        if (bothStageInvisible) {
-            if (mExitSplitScreenOnHide
-            // Don't dismiss staged split when both stages are not visible due to sleeping display,
-            // like the cases keyguard showing or screen off.
-            || (!mMainStage.mRootTaskInfo.isSleeping && !mSideStage.mRootTaskInfo.isSleeping)) {
-                exitSplitScreen(null /* childrenToTop */,
-                        SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME);
-            }
-        } else if (mKeyguardOccluded) {
-            // At least one of the stages is visible while keyguard occluded. Dismiss split because
-            // there's show-when-locked activity showing on top of keyguard. Also make sure the
-            // task contains show-when-locked activity remains on top after split dismissed.
-            final StageTaskListener toTop =
-                    mainStageVisible ? mMainStage : (sideStageVisible ? mSideStage : null);
-            exitSplitScreen(toTop, SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED_SHOW_ON_TOP);
-        }
-
-        mSyncQueue.runInSync(t -> {
-            // Same above, we only set root tasks and divider leash visibility when both stage
-            // change to visible or invisible to avoid flicker.
-            if (sameVisibility) {
-                t.setVisibility(mSideStage.mRootLeash, bothStageVisible)
-                        .setVisibility(mMainStage.mRootLeash, bothStageVisible);
-                applyDividerVisibility(t);
-                applyOutlineVisibility(t);
-            }
-        });
-    }
-
-    private void applyDividerVisibility(SurfaceControl.Transaction t) {
-        final SurfaceControl dividerLeash = mSplitLayout.getDividerLeash();
-        if (dividerLeash == null) {
-            return;
-        }
-
-        if (mDividerVisible) {
-            t.show(dividerLeash)
-                    .setLayer(dividerLeash, Integer.MAX_VALUE)
-                    .setPosition(dividerLeash,
-                            mSplitLayout.getDividerBounds().left,
-                            mSplitLayout.getDividerBounds().top);
-        } else {
-            t.hide(dividerLeash);
-        }
-    }
-
-    private void applyOutlineVisibility(SurfaceControl.Transaction t) {
-        final SurfaceControl outlineLeash = mSideStage.getOutlineLeash();
-        if (outlineLeash == null) {
-            return;
-        }
-
-        if (mDividerVisible) {
-            t.show(outlineLeash).setLayer(outlineLeash, Integer.MAX_VALUE);
-        } else {
-            t.hide(outlineLeash);
-        }
-    }
-
-    private void onStageHasChildrenChanged(StageListenerImpl stageListener) {
-        final boolean hasChildren = stageListener.mHasChildren;
-        final boolean isSideStage = stageListener == mSideStageListener;
-        if (!hasChildren) {
-            if (isSideStage && mMainStageListener.mVisible) {
-                // Exit to main stage if side stage no longer has children.
-                exitSplitScreen(mMainStage, SPLITSCREEN_UICHANGED__EXIT_REASON__APP_FINISHED);
-            } else if (!isSideStage && mSideStageListener.mVisible) {
-                // Exit to side stage if main stage no longer has children.
-                exitSplitScreen(mSideStage, SPLITSCREEN_UICHANGED__EXIT_REASON__APP_FINISHED);
-            }
-        } else if (isSideStage) {
-            final WindowContainerTransaction wct = new WindowContainerTransaction();
-            // Make sure the main stage is active.
-            mMainStage.activate(getMainStageBounds(), wct);
-            mSideStage.setBounds(getSideStageBounds(), wct);
-            mTaskOrganizer.applyTransaction(wct);
-        }
-        if (!mLogger.hasStartedSession() && mMainStageListener.mHasChildren
-                && mSideStageListener.mHasChildren) {
-            mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
-                    getMainStagePosition(), mMainStage.getTopChildTaskUid(),
-                    getSideStagePosition(), mSideStage.getTopChildTaskUid(),
-                    mSplitLayout.isLandscape());
-        }
-    }
-
-    @VisibleForTesting
-    IBinder onSnappedToDismissTransition(boolean mainStageToTop) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        prepareExitSplitScreen(mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE, wct);
-        return mSplitTransitions.startSnapToDismiss(wct, this);
-    }
-
-    @Override
-    public void onSnappedToDismiss(boolean bottomOrRight) {
-        final boolean mainStageToTop =
-                bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
-                        : mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
-        if (ENABLE_SHELL_TRANSITIONS) {
-            onSnappedToDismissTransition(mainStageToTop);
-            return;
-        }
-        exitSplitScreen(mainStageToTop ? mMainStage : mSideStage,
-                SPLITSCREEN_UICHANGED__EXIT_REASON__DRAG_DIVIDER);
-    }
-
-    @Override
-    public void onDoubleTappedDivider() {
-        setSideStagePosition(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
-                ? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT, null /* wct */);
-        mLogger.logSwap(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
-                getSideStagePosition(), mSideStage.getTopChildTaskUid(),
-                mSplitLayout.isLandscape());
-    }
-
-    @Override
-    public void onLayoutPositionChanging(SplitLayout layout) {
-        mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t, true /* applyResizingOffset */));
-    }
-
-    @Override
-    public void onLayoutSizeChanging(SplitLayout layout) {
-        mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t, true /* applyResizingOffset */));
-        mSideStage.setOutlineVisibility(false);
-    }
-
-    @Override
-    public void onLayoutSizeChanged(SplitLayout layout) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        updateWindowBounds(layout, wct);
-        updateUnfoldBounds();
-        mSyncQueue.queue(wct);
-        mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t, false /* applyResizingOffset */));
-        mSideStage.setOutlineVisibility(true);
-        mLogger.logResize(mSplitLayout.getDividerPositionAsFraction());
-    }
-
-    private void updateUnfoldBounds() {
-        if (mMainUnfoldController != null && mSideUnfoldController != null) {
-            mMainUnfoldController.onLayoutChanged(getMainStageBounds());
-            mSideUnfoldController.onLayoutChanged(getSideStageBounds());
-        }
-    }
-
-    /**
-     * Populates `wct` with operations that match the split windows to the current layout.
-     * To match relevant surfaces, make sure to call updateSurfaceBounds after `wct` is applied
-     */
-    private void updateWindowBounds(SplitLayout layout, WindowContainerTransaction wct) {
-        final StageTaskListener topLeftStage =
-                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
-        final StageTaskListener bottomRightStage =
-                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
-        layout.applyTaskChanges(wct, topLeftStage.mRootTaskInfo, bottomRightStage.mRootTaskInfo);
-    }
-
-    void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t,
-            boolean applyResizingOffset) {
-        final StageTaskListener topLeftStage =
-                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
-        final StageTaskListener bottomRightStage =
-                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
-        (layout != null ? layout : mSplitLayout).applySurfaceChanges(t, topLeftStage.mRootLeash,
-                bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer,
-                applyResizingOffset);
-    }
-
-    @Override
-    public int getSplitItemPosition(WindowContainerToken token) {
-        if (token == null) {
-            return SPLIT_POSITION_UNDEFINED;
-        }
-
-        if (token.equals(mMainStage.mRootTaskInfo.getToken())) {
-            return getMainStagePosition();
-        } else if (token.equals(mSideStage.mRootTaskInfo.getToken())) {
-            return getSideStagePosition();
-        }
-
-        return SPLIT_POSITION_UNDEFINED;
-    }
-
-    @Override
-    public void setLayoutOffsetTarget(int offsetX, int offsetY, SplitLayout layout) {
-        final StageTaskListener topLeftStage =
-                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
-        final StageTaskListener bottomRightStage =
-                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
-        layout.applyLayoutOffsetTarget(wct, offsetX, offsetY, topLeftStage.mRootTaskInfo,
-                bottomRightStage.mRootTaskInfo);
-        mTaskOrganizer.applyTransaction(wct);
-    }
-
-    @Override
-    public void onDisplayAreaAppeared(DisplayAreaInfo displayAreaInfo) {
-        mDisplayAreaInfo = displayAreaInfo;
-        if (mSplitLayout == null) {
-            mSplitLayout = new SplitLayout(TAG + "SplitDivider", mContext,
-                    mDisplayAreaInfo.configuration, this, mParentContainerCallbacks,
-                    mDisplayImeController, mTaskOrganizer, SplitLayout.PARALLAX_DISMISSING);
-            mDisplayInsetsController.addInsetsChangedListener(mDisplayId, mSplitLayout);
-
-            if (mMainUnfoldController != null && mSideUnfoldController != null) {
-                mMainUnfoldController.init();
-                mSideUnfoldController.init();
-            }
-        }
-    }
-
-    @Override
-    public void onDisplayAreaVanished(DisplayAreaInfo displayAreaInfo) {
-        throw new IllegalStateException("Well that was unexpected...");
-    }
-
-    @Override
-    public void onDisplayAreaInfoChanged(DisplayAreaInfo displayAreaInfo) {
-        mDisplayAreaInfo = displayAreaInfo;
-        if (mSplitLayout != null
-                && mSplitLayout.updateConfiguration(mDisplayAreaInfo.configuration)
-                && mMainStage.isActive()) {
-            onLayoutSizeChanged(mSplitLayout);
-        }
-    }
-
-    private void onFoldedStateChanged(boolean folded) {
-        mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
-        if (!folded) return;
-
-        if (mMainStage.isFocused()) {
-            mTopStageAfterFoldDismiss = STAGE_TYPE_MAIN;
-        } else if (mSideStage.isFocused()) {
-            mTopStageAfterFoldDismiss = STAGE_TYPE_SIDE;
-        }
-    }
-
-    private Rect getSideStageBounds() {
-        return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
-                ? mSplitLayout.getBounds1() : mSplitLayout.getBounds2();
-    }
-
-    private Rect getMainStageBounds() {
-        return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
-                ? mSplitLayout.getBounds2() : mSplitLayout.getBounds1();
-    }
-
-    /**
-     * Get the stage that should contain this `taskInfo`. The stage doesn't necessarily contain
-     * this task (yet) so this can also be used to identify which stage to put a task into.
-     */
-    private StageTaskListener getStageOfTask(ActivityManager.RunningTaskInfo taskInfo) {
-        // TODO(b/184679596): Find a way to either include task-org information in the transition,
-        //                    or synchronize task-org callbacks so we can use stage.containsTask
-        if (mMainStage.mRootTaskInfo != null
-                && taskInfo.parentTaskId == mMainStage.mRootTaskInfo.taskId) {
-            return mMainStage;
-        } else if (mSideStage.mRootTaskInfo != null
-                && taskInfo.parentTaskId == mSideStage.mRootTaskInfo.taskId) {
-            return mSideStage;
-        }
-        return null;
-    }
-
-    @SplitScreen.StageType
-    private int getStageType(StageTaskListener stage) {
-        return stage == mMainStage ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
-    }
-
-    @Override
-    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
-            @Nullable TransitionRequestInfo request) {
-        final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
-        if (triggerTask == null) {
-            // still want to monitor everything while in split-screen, so return non-null.
-            return isSplitScreenVisible() ? new WindowContainerTransaction() : null;
-        }
-
-        WindowContainerTransaction out = null;
-        final @WindowManager.TransitionType int type = request.getType();
-        if (isSplitScreenVisible()) {
-            // try to handle everything while in split-screen, so return a WCT even if it's empty.
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  split is active so using split"
-                            + "Transition to handle request. triggerTask=%d type=%s mainChildren=%d"
-                            + " sideChildren=%d", triggerTask.taskId, transitTypeToString(type),
-                    mMainStage.getChildCount(), mSideStage.getChildCount());
-            out = new WindowContainerTransaction();
-            final StageTaskListener stage = getStageOfTask(triggerTask);
-            if (stage != null) {
-                // dismiss split if the last task in one of the stages is going away
-                if (isClosingType(type) && stage.getChildCount() == 1) {
-                    // The top should be the opposite side that is closing:
-                    mDismissTop = getStageType(stage) == STAGE_TYPE_MAIN
-                            ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN;
-                }
-            } else {
-                if (triggerTask.getActivityType() == ACTIVITY_TYPE_HOME && isOpeningType(type)) {
-                    // Going home so dismiss both.
-                    mDismissTop = STAGE_TYPE_UNDEFINED;
-                }
-            }
-            if (mDismissTop != NO_DISMISS) {
-                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  splitTransition "
-                                + " deduced Dismiss from request. toTop=%s",
-                        stageTypeToString(mDismissTop));
-                prepareExitSplitScreen(mDismissTop, out);
-                mSplitTransitions.mPendingDismiss = transition;
-            }
-        } else {
-            // Not in split mode, so look for an open into a split stage just so we can whine and
-            // complain about how this isn't a supported operation.
-            if ((type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT)) {
-                if (getStageOfTask(triggerTask) != null) {
-                    throw new IllegalStateException("Entering split implicitly with only one task"
-                            + " isn't supported.");
-                }
-            }
-        }
-        return out;
-    }
-
-    @Override
-    public boolean startAnimation(@NonNull IBinder transition,
-            @NonNull TransitionInfo info,
-            @NonNull SurfaceControl.Transaction startTransaction,
-            @NonNull SurfaceControl.Transaction finishTransaction,
-            @NonNull Transitions.TransitionFinishCallback finishCallback) {
-        if (transition != mSplitTransitions.mPendingDismiss
-                && transition != mSplitTransitions.mPendingEnter) {
-            // Not entering or exiting, so just do some house-keeping and validation.
-
-            // If we're not in split-mode, just abort so something else can handle it.
-            if (!isSplitScreenVisible()) return false;
-
-            for (int iC = 0; iC < info.getChanges().size(); ++iC) {
-                final TransitionInfo.Change change = info.getChanges().get(iC);
-                final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
-                if (taskInfo == null || !taskInfo.hasParentTask()) continue;
-                final StageTaskListener stage = getStageOfTask(taskInfo);
-                if (stage == null) continue;
-                if (isOpeningType(change.getMode())) {
-                    if (!stage.containsTask(taskInfo.taskId)) {
-                        Log.w(TAG, "Expected onTaskAppeared on " + stage + " to have been called"
-                                + " with " + taskInfo.taskId + " before startAnimation().");
-                    }
-                } else if (isClosingType(change.getMode())) {
-                    if (stage.containsTask(taskInfo.taskId)) {
-                        Log.w(TAG, "Expected onTaskVanished on " + stage + " to have been called"
-                                + " with " + taskInfo.taskId + " before startAnimation().");
-                    }
-                }
-            }
-            if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
-                // TODO(shell-transitions): Implement a fallback behavior for now.
-                throw new IllegalStateException("Somehow removed the last task in a stage"
-                        + " outside of a proper transition");
-                // This can happen in some pathological cases. For example:
-                // 1. main has 2 tasks [Task A (Single-task), Task B], side has one task [Task C]
-                // 2. Task B closes itself and starts Task A in LAUNCH_ADJACENT at the same time
-                // In this case, the result *should* be that we leave split.
-                // TODO(b/184679596): Find a way to either include task-org information in
-                //                    the transition, or synchronize task-org callbacks.
-            }
-
-            // Use normal animations.
-            return false;
-        }
-
-        boolean shouldAnimate = true;
-        if (mSplitTransitions.mPendingEnter == transition) {
-            shouldAnimate = startPendingEnterAnimation(transition, info, startTransaction);
-        } else if (mSplitTransitions.mPendingDismiss == transition) {
-            shouldAnimate = startPendingDismissAnimation(transition, info, startTransaction);
-        }
-        if (!shouldAnimate) return false;
-
-        mSplitTransitions.playAnimation(transition, info, startTransaction, finishTransaction,
-                finishCallback, mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token);
-        return true;
-    }
-
-    private boolean startPendingEnterAnimation(@NonNull IBinder transition,
-            @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t) {
-        if (info.getType() == TRANSIT_SPLIT_SCREEN_PAIR_OPEN) {
-            // First, verify that we actually have opened 2 apps in split.
-            TransitionInfo.Change mainChild = null;
-            TransitionInfo.Change sideChild = null;
-            for (int iC = 0; iC < info.getChanges().size(); ++iC) {
-                final TransitionInfo.Change change = info.getChanges().get(iC);
-                final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
-                if (taskInfo == null || !taskInfo.hasParentTask()) continue;
-                final @SplitScreen.StageType int stageType = getStageType(getStageOfTask(taskInfo));
-                if (stageType == STAGE_TYPE_MAIN) {
-                    mainChild = change;
-                } else if (stageType == STAGE_TYPE_SIDE) {
-                    sideChild = change;
-                }
-            }
-            if (mainChild == null || sideChild == null) {
-                throw new IllegalStateException("Launched 2 tasks in split, but didn't receive"
-                        + " 2 tasks in transition. Possibly one of them failed to launch");
-                // TODO: fallback logic. Probably start a new transition to exit split before
-                //       applying anything here. Ideally consolidate with transition-merging.
-            }
-
-            // Update local states (before animating).
-            setDividerVisibility(true);
-            setSideStagePosition(SPLIT_POSITION_BOTTOM_OR_RIGHT, false /* updateBounds */,
-                    null /* wct */);
-            setSplitsVisible(true);
-
-            addDividerBarToTransition(info, t, true /* show */);
-
-            // Make some noise if things aren't totally expected. These states shouldn't effect
-            // transitions locally, but remotes (like Launcher) may get confused if they were
-            // depending on listener callbacks. This can happen because task-organizer callbacks
-            // aren't serialized with transition callbacks.
-            // TODO(b/184679596): Find a way to either include task-org information in
-            //                    the transition, or synchronize task-org callbacks.
-            if (!mMainStage.containsTask(mainChild.getTaskInfo().taskId)) {
-                Log.w(TAG, "Expected onTaskAppeared on " + mMainStage
-                        + " to have been called with " + mainChild.getTaskInfo().taskId
-                        + " before startAnimation().");
-            }
-            if (!mSideStage.containsTask(sideChild.getTaskInfo().taskId)) {
-                Log.w(TAG, "Expected onTaskAppeared on " + mSideStage
-                        + " to have been called with " + sideChild.getTaskInfo().taskId
-                        + " before startAnimation().");
-            }
-            return true;
-        } else {
-            // TODO: other entry method animations
-            throw new RuntimeException("Unsupported split-entry");
-        }
-    }
-
-    private boolean startPendingDismissAnimation(@NonNull IBinder transition,
-            @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t) {
-        // Make some noise if things aren't totally expected. These states shouldn't effect
-        // transitions locally, but remotes (like Launcher) may get confused if they were
-        // depending on listener callbacks. This can happen because task-organizer callbacks
-        // aren't serialized with transition callbacks.
-        // TODO(b/184679596): Find a way to either include task-org information in
-        //                    the transition, or synchronize task-org callbacks.
-        if (mMainStage.getChildCount() != 0) {
-            final StringBuilder tasksLeft = new StringBuilder();
-            for (int i = 0; i < mMainStage.getChildCount(); ++i) {
-                tasksLeft.append(i != 0 ? ", " : "");
-                tasksLeft.append(mMainStage.mChildrenTaskInfo.keyAt(i));
-            }
-            Log.w(TAG, "Expected onTaskVanished on " + mMainStage
-                    + " to have been called with [" + tasksLeft.toString()
-                    + "] before startAnimation().");
-        }
-        if (mSideStage.getChildCount() != 0) {
-            final StringBuilder tasksLeft = new StringBuilder();
-            for (int i = 0; i < mSideStage.getChildCount(); ++i) {
-                tasksLeft.append(i != 0 ? ", " : "");
-                tasksLeft.append(mSideStage.mChildrenTaskInfo.keyAt(i));
-            }
-            Log.w(TAG, "Expected onTaskVanished on " + mSideStage
-                    + " to have been called with [" + tasksLeft.toString()
-                    + "] before startAnimation().");
-        }
-
-        // Update local states.
-        setSplitsVisible(false);
-        // Wait until after animation to update divider
-
-        if (info.getType() == TRANSIT_SPLIT_DISMISS_SNAP) {
-            // Reset crops so they don't interfere with subsequent launches
-            t.setWindowCrop(mMainStage.mRootLeash, null);
-            t.setWindowCrop(mSideStage.mRootLeash, null);
-        }
-
-        if (mDismissTop == STAGE_TYPE_UNDEFINED) {
-            // Going home (dismissing both splits)
-
-            // TODO: Have a proper remote for this. Until then, though, reset state and use the
-            //       normal animation stuff (which falls back to the normal launcher remote).
-            t.hide(mSplitLayout.getDividerLeash());
-            setDividerVisibility(false);
-            mSplitTransitions.mPendingDismiss = null;
-            return false;
-        }
-
-        addDividerBarToTransition(info, t, false /* show */);
-        // We're dismissing split by moving the other one to fullscreen.
-        // Since we don't have any animations for this yet, just use the internal example
-        // animations.
-        return true;
-    }
-
-    private void addDividerBarToTransition(@NonNull TransitionInfo info,
-            @NonNull SurfaceControl.Transaction t, boolean show) {
-        final SurfaceControl leash = mSplitLayout.getDividerLeash();
-        final TransitionInfo.Change barChange = new TransitionInfo.Change(null /* token */, leash);
-        final Rect bounds = mSplitLayout.getDividerBounds();
-        barChange.setStartAbsBounds(bounds);
-        barChange.setEndAbsBounds(bounds);
-        barChange.setMode(show ? TRANSIT_TO_FRONT : TRANSIT_TO_BACK);
-        barChange.setFlags(FLAG_IS_DIVIDER_BAR);
-        // Technically this should be order-0, but this is running after layer assignment
-        // and it's a special case, so just add to end.
-        info.addChange(barChange);
-        // Be default, make it visible. The remote animator can adjust alpha if it plans to animate.
-        if (show) {
-            t.setAlpha(leash, 1.f);
-            t.setLayer(leash, Integer.MAX_VALUE);
-            t.setPosition(leash, bounds.left, bounds.top);
-            t.show(leash);
-        }
-    }
-
-    RemoteAnimationTarget getDividerBarLegacyTarget() {
-        final Rect bounds = mSplitLayout.getDividerBounds();
-        return new RemoteAnimationTarget(-1 /* taskId */, -1 /* mode */,
-                mSplitLayout.getDividerLeash(), false /* isTranslucent */, null /* clipRect */,
-                null /* contentInsets */, Integer.MAX_VALUE /* prefixOrderIndex */,
-                new android.graphics.Point(0, 0) /* position */, bounds, bounds,
-                new WindowConfiguration(), true, null /* startLeash */, null /* startBounds */,
-                null /* taskInfo */, false /* allowEnterPip */, TYPE_DOCK_DIVIDER);
-    }
-
-    RemoteAnimationTarget getOutlineLegacyTarget() {
-        final Rect bounds = mSideStage.mRootTaskInfo.configuration.windowConfiguration.getBounds();
-        // Leverage TYPE_DOCK_DIVIDER type when wrapping outline remote animation target in order to
-        // distinguish as a split auxiliary target in Launcher.
-        return new RemoteAnimationTarget(-1 /* taskId */, -1 /* mode */,
-                mSideStage.getOutlineLeash(), false /* isTranslucent */, null /* clipRect */,
-                null /* contentInsets */, Integer.MAX_VALUE /* prefixOrderIndex */,
-                new android.graphics.Point(0, 0) /* position */, bounds, bounds,
-                new WindowConfiguration(), true, null /* startLeash */, null /* startBounds */,
-                null /* taskInfo */, false /* allowEnterPip */, TYPE_DOCK_DIVIDER);
-    }
-
-    @Override
-    public void dump(@NonNull PrintWriter pw, String prefix) {
-        final String innerPrefix = prefix + "  ";
-        final String childPrefix = innerPrefix + "  ";
-        pw.println(prefix + TAG + " mDisplayId=" + mDisplayId);
-        pw.println(innerPrefix + "mDividerVisible=" + mDividerVisible);
-        pw.println(innerPrefix + "MainStage");
-        pw.println(childPrefix + "isActive=" + mMainStage.isActive());
-        mMainStageListener.dump(pw, childPrefix);
-        pw.println(innerPrefix + "SideStage");
-        mSideStageListener.dump(pw, childPrefix);
-        pw.println(innerPrefix + "mSplitLayout=" + mSplitLayout);
-    }
-
-    /**
-     * Directly set the visibility of both splits. This assumes hasChildren matches visibility.
-     * This is intended for batch use, so it assumes other state management logic is already
-     * handled.
-     */
-    private void setSplitsVisible(boolean visible) {
-        mMainStageListener.mVisible = mSideStageListener.mVisible = visible;
-        mMainStageListener.mHasChildren = mSideStageListener.mHasChildren = visible;
-    }
-
-    /**
-     * Sets drag info to be logged when splitscreen is next entered.
-     */
-    public void logOnDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) {
-        mLogger.enterRequestedByDrag(position, dragSessionId);
-    }
-
-    /**
-     * Logs the exit of splitscreen.
-     */
-    private void logExit(int exitReason) {
-        mLogger.logExit(exitReason,
-                SPLIT_POSITION_UNDEFINED, 0 /* mainStageUid */,
-                SPLIT_POSITION_UNDEFINED, 0 /* sideStageUid */,
-                mSplitLayout.isLandscape());
-    }
-
-    /**
-     * Logs the exit of splitscreen to a specific stage. This must be called before the exit is
-     * executed.
-     */
-    private void logExitToStage(int exitReason, boolean toMainStage) {
-        mLogger.logExit(exitReason,
-                toMainStage ? getMainStagePosition() : SPLIT_POSITION_UNDEFINED,
-                toMainStage ? mMainStage.getTopChildTaskUid() : 0 /* mainStageUid */,
-                !toMainStage ? getSideStagePosition() : SPLIT_POSITION_UNDEFINED,
-                !toMainStage ? mSideStage.getTopChildTaskUid() : 0 /* sideStageUid */,
-                mSplitLayout.isLandscape());
-    }
-
-    class StageListenerImpl implements StageTaskListener.StageListenerCallbacks {
-        boolean mHasRootTask = false;
-        boolean mVisible = false;
-        boolean mHasChildren = false;
-
-        @Override
-        public void onRootTaskAppeared() {
-            mHasRootTask = true;
-            StageCoordinator.this.onStageRootTaskAppeared(this);
-        }
-
-        @Override
-        public void onStatusChanged(boolean visible, boolean hasChildren) {
-            if (!mHasRootTask) return;
-
-            if (mHasChildren != hasChildren) {
-                mHasChildren = hasChildren;
-                StageCoordinator.this.onStageHasChildrenChanged(this);
-            }
-            if (mVisible != visible) {
-                mVisible = visible;
-                StageCoordinator.this.onStageVisibilityChanged(this);
-            }
-        }
-
-        @Override
-        public void onChildTaskStatusChanged(int taskId, boolean present, boolean visible) {
-            StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present, visible);
-        }
-
-        @Override
-        public void onRootTaskVanished() {
-            reset();
-            StageCoordinator.this.onStageRootTaskVanished(this);
-        }
-
-        @Override
-        public void onNoLongerSupportMultiWindow() {
-            if (mMainStage.isActive()) {
-                StageCoordinator.this.exitSplitScreen(null /* childrenToTop */,
-                        SPLITSCREEN_UICHANGED__EXIT_REASON__APP_DOES_NOT_SUPPORT_MULTIWINDOW);
-            }
-        }
-
-        private void reset() {
-            mHasRootTask = false;
-            mVisible = false;
-            mHasChildren = false;
-        }
-
-        public void dump(@NonNull PrintWriter pw, String prefix) {
-            pw.println(prefix + "mHasRootTask=" + mHasRootTask);
-            pw.println(prefix + "mVisible=" + mVisible);
-            pw.println(prefix + "mHasChildren=" + mHasChildren);
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
deleted file mode 100644
index 7b679580..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskListener.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.stagesplit;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-
-import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
-
-import android.annotation.CallSuper;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.util.SparseArray;
-import android.view.SurfaceControl;
-import android.view.SurfaceSession;
-import android.window.WindowContainerTransaction;
-
-import androidx.annotation.NonNull;
-
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.SurfaceUtils;
-import com.android.wm.shell.common.SyncTransactionQueue;
-
-import java.io.PrintWriter;
-
-/**
- * Base class that handle common task org. related for split-screen stages.
- * Note that this class and its sub-class do not directly perform hierarchy operations.
- * They only serve to hold a collection of tasks and provide APIs like
- * {@link #setBounds(Rect, WindowContainerTransaction)} for the centralized {@link StageCoordinator}
- * to perform operations in-sync with other containers.
- *
- * @see StageCoordinator
- */
-class StageTaskListener implements ShellTaskOrganizer.TaskListener {
-    private static final String TAG = StageTaskListener.class.getSimpleName();
-
-    protected static final int[] CONTROLLED_ACTIVITY_TYPES = {ACTIVITY_TYPE_STANDARD};
-    protected static final int[] CONTROLLED_WINDOWING_MODES =
-            {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED};
-    protected static final int[] CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE =
-            {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED, WINDOWING_MODE_MULTI_WINDOW};
-
-    /** Callback interface for listening to changes in a split-screen stage. */
-    public interface StageListenerCallbacks {
-        void onRootTaskAppeared();
-
-        void onStatusChanged(boolean visible, boolean hasChildren);
-
-        void onChildTaskStatusChanged(int taskId, boolean present, boolean visible);
-
-        void onRootTaskVanished();
-        void onNoLongerSupportMultiWindow();
-    }
-
-    private final StageListenerCallbacks mCallbacks;
-    private final SurfaceSession mSurfaceSession;
-    protected final SyncTransactionQueue mSyncQueue;
-
-    protected ActivityManager.RunningTaskInfo mRootTaskInfo;
-    protected SurfaceControl mRootLeash;
-    protected SurfaceControl mDimLayer;
-    protected SparseArray<ActivityManager.RunningTaskInfo> mChildrenTaskInfo = new SparseArray<>();
-    private final SparseArray<SurfaceControl> mChildrenLeashes = new SparseArray<>();
-
-    private final StageTaskUnfoldController mStageTaskUnfoldController;
-
-    StageTaskListener(ShellTaskOrganizer taskOrganizer, int displayId,
-            StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
-            SurfaceSession surfaceSession,
-            @Nullable StageTaskUnfoldController stageTaskUnfoldController) {
-        mCallbacks = callbacks;
-        mSyncQueue = syncQueue;
-        mSurfaceSession = surfaceSession;
-        mStageTaskUnfoldController = stageTaskUnfoldController;
-        taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
-    }
-
-    int getChildCount() {
-        return mChildrenTaskInfo.size();
-    }
-
-    boolean containsTask(int taskId) {
-        return mChildrenTaskInfo.contains(taskId);
-    }
-
-    /**
-     * Returns the top activity uid for the top child task.
-     */
-    int getTopChildTaskUid() {
-        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
-            final ActivityManager.RunningTaskInfo info = mChildrenTaskInfo.valueAt(i);
-            if (info.topActivityInfo == null) {
-                continue;
-            }
-            return info.topActivityInfo.applicationInfo.uid;
-        }
-        return 0;
-    }
-
-    /** @return {@code true} if this listener contains the currently focused task. */
-    boolean isFocused() {
-        if (mRootTaskInfo == null) {
-            return false;
-        }
-
-        if (mRootTaskInfo.isFocused) {
-            return true;
-        }
-
-        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
-            if (mChildrenTaskInfo.valueAt(i).isFocused) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    @CallSuper
-    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
-        if (mRootTaskInfo == null && !taskInfo.hasParentTask()) {
-            mRootLeash = leash;
-            mRootTaskInfo = taskInfo;
-            mCallbacks.onRootTaskAppeared();
-            sendStatusChanged();
-            mSyncQueue.runInSync(t -> {
-                t.hide(mRootLeash);
-                mDimLayer =
-                        SurfaceUtils.makeDimLayer(t, mRootLeash, "Dim layer", mSurfaceSession);
-            });
-        } else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
-            final int taskId = taskInfo.taskId;
-            mChildrenLeashes.put(taskId, leash);
-            mChildrenTaskInfo.put(taskId, taskInfo);
-            updateChildTaskSurface(taskInfo, leash, true /* firstAppeared */);
-            mCallbacks.onChildTaskStatusChanged(taskId, true /* present */, taskInfo.isVisible);
-            if (ENABLE_SHELL_TRANSITIONS) {
-                // Status is managed/synchronized by the transition lifecycle.
-                return;
-            }
-            sendStatusChanged();
-        } else {
-            throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
-                    + "\n mRootTaskInfo: " + mRootTaskInfo);
-        }
-
-        if (mStageTaskUnfoldController != null) {
-            mStageTaskUnfoldController.onTaskAppeared(taskInfo, leash);
-        }
-    }
-
-    @Override
-    @CallSuper
-    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
-        if (!taskInfo.supportsMultiWindow) {
-            // Leave split screen if the task no longer supports multi window.
-            mCallbacks.onNoLongerSupportMultiWindow();
-            return;
-        }
-        if (mRootTaskInfo.taskId == taskInfo.taskId) {
-            mRootTaskInfo = taskInfo;
-        } else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {
-            mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
-            mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */,
-                    taskInfo.isVisible);
-            if (!ENABLE_SHELL_TRANSITIONS) {
-                updateChildTaskSurface(
-                        taskInfo, mChildrenLeashes.get(taskInfo.taskId), false /* firstAppeared */);
-            }
-        } else {
-            throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
-                    + "\n mRootTaskInfo: " + mRootTaskInfo);
-        }
-        if (ENABLE_SHELL_TRANSITIONS) {
-            // Status is managed/synchronized by the transition lifecycle.
-            return;
-        }
-        sendStatusChanged();
-    }
-
-    @Override
-    @CallSuper
-    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
-        final int taskId = taskInfo.taskId;
-        if (mRootTaskInfo.taskId == taskId) {
-            mCallbacks.onRootTaskVanished();
-            mSyncQueue.runInSync(t -> t.remove(mDimLayer));
-            mRootTaskInfo = null;
-        } else if (mChildrenTaskInfo.contains(taskId)) {
-            mChildrenTaskInfo.remove(taskId);
-            mChildrenLeashes.remove(taskId);
-            mCallbacks.onChildTaskStatusChanged(taskId, false /* present */, taskInfo.isVisible);
-            if (ENABLE_SHELL_TRANSITIONS) {
-                // Status is managed/synchronized by the transition lifecycle.
-                return;
-            }
-            sendStatusChanged();
-        } else {
-            throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
-                    + "\n mRootTaskInfo: " + mRootTaskInfo);
-        }
-
-        if (mStageTaskUnfoldController != null) {
-            mStageTaskUnfoldController.onTaskVanished(taskInfo);
-        }
-    }
-
-    @Override
-    public void attachChildSurfaceToTask(int taskId, SurfaceControl.Builder b) {
-        b.setParent(findTaskSurface(taskId));
-    }
-
-    @Override
-    public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
-            SurfaceControl.Transaction t) {
-        t.reparent(sc, findTaskSurface(taskId));
-    }
-
-    private SurfaceControl findTaskSurface(int taskId) {
-        if (mRootTaskInfo.taskId == taskId) {
-            return mRootLeash;
-        } else if (mChildrenLeashes.contains(taskId)) {
-            return mChildrenLeashes.get(taskId);
-        } else {
-            throw new IllegalArgumentException("There is no surface for taskId=" + taskId);
-        }
-    }
-
-    void setBounds(Rect bounds, WindowContainerTransaction wct) {
-        wct.setBounds(mRootTaskInfo.token, bounds);
-    }
-
-    void reorderChild(int taskId, boolean onTop, WindowContainerTransaction wct) {
-        if (!containsTask(taskId)) {
-            return;
-        }
-        wct.reorder(mChildrenTaskInfo.get(taskId).token, onTop /* onTop */);
-    }
-
-    void setVisibility(boolean visible, WindowContainerTransaction wct) {
-        wct.reorder(mRootTaskInfo.token, visible /* onTop */);
-    }
-
-    void onSplitScreenListenerRegistered(SplitScreen.SplitScreenListener listener,
-            @SplitScreen.StageType int stage) {
-        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
-            int taskId = mChildrenTaskInfo.keyAt(i);
-            listener.onTaskStageChanged(taskId, stage,
-                    mChildrenTaskInfo.get(taskId).isVisible);
-        }
-    }
-
-    private void updateChildTaskSurface(ActivityManager.RunningTaskInfo taskInfo,
-            SurfaceControl leash, boolean firstAppeared) {
-        final Point taskPositionInParent = taskInfo.positionInParent;
-        mSyncQueue.runInSync(t -> {
-            t.setWindowCrop(leash, null);
-            t.setPosition(leash, taskPositionInParent.x, taskPositionInParent.y);
-            if (firstAppeared && !ENABLE_SHELL_TRANSITIONS) {
-                t.setAlpha(leash, 1f);
-                t.setMatrix(leash, 1, 0, 0, 1);
-                t.show(leash);
-            }
-        });
-    }
-
-    private void sendStatusChanged() {
-        mCallbacks.onStatusChanged(mRootTaskInfo.isVisible, mChildrenTaskInfo.size() > 0);
-    }
-
-    @Override
-    @CallSuper
-    public void dump(@NonNull PrintWriter pw, String prefix) {
-        final String innerPrefix = prefix + "  ";
-        final String childPrefix = innerPrefix + "  ";
-        pw.println(prefix + this);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskUnfoldController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskUnfoldController.java
deleted file mode 100644
index 62b9da6..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageTaskUnfoldController.java
+++ /dev/null
@@ -1,224 +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.wm.shell.stagesplit;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import android.animation.RectEvaluator;
-import android.animation.TypeEvaluator;
-import android.annotation.NonNull;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.SparseArray;
-import android.view.InsetsSource;
-import android.view.InsetsState;
-import android.view.SurfaceControl;
-
-import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.wm.shell.common.DisplayInsetsController;
-import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener;
-import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
-import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener;
-import com.android.wm.shell.unfold.UnfoldBackgroundController;
-
-import java.util.concurrent.Executor;
-
-/**
- * Controls transformations of the split screen task surfaces in response
- * to the unfolding/folding action on foldable devices
- */
-public class StageTaskUnfoldController implements UnfoldListener, OnInsetsChangedListener {
-
-    private static final TypeEvaluator<Rect> RECT_EVALUATOR = new RectEvaluator(new Rect());
-    private static final float CROPPING_START_MARGIN_FRACTION = 0.05f;
-
-    private final SparseArray<AnimationContext> mAnimationContextByTaskId = new SparseArray<>();
-    private final ShellUnfoldProgressProvider mUnfoldProgressProvider;
-    private final DisplayInsetsController mDisplayInsetsController;
-    private final UnfoldBackgroundController mBackgroundController;
-    private final Executor mExecutor;
-    private final int mExpandedTaskBarHeight;
-    private final float mWindowCornerRadiusPx;
-    private final Rect mStageBounds = new Rect();
-    private final TransactionPool mTransactionPool;
-
-    private InsetsSource mTaskbarInsetsSource;
-    private boolean mBothStagesVisible;
-
-    public StageTaskUnfoldController(@NonNull Context context,
-            @NonNull TransactionPool transactionPool,
-            @NonNull ShellUnfoldProgressProvider unfoldProgressProvider,
-            @NonNull DisplayInsetsController displayInsetsController,
-            @NonNull UnfoldBackgroundController backgroundController,
-            @NonNull Executor executor) {
-        mUnfoldProgressProvider = unfoldProgressProvider;
-        mTransactionPool = transactionPool;
-        mExecutor = executor;
-        mBackgroundController = backgroundController;
-        mDisplayInsetsController = displayInsetsController;
-        mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(context);
-        mExpandedTaskBarHeight = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.taskbar_frame_height);
-    }
-
-    /**
-     * Initializes the controller, starts listening for the external events
-     */
-    public void init() {
-        mUnfoldProgressProvider.addListener(mExecutor, this);
-        mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY, this);
-    }
-
-    @Override
-    public void insetsChanged(InsetsState insetsState) {
-        mTaskbarInsetsSource = insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-            context.update();
-        }
-    }
-
-    /**
-     * Called when split screen task appeared
-     * @param taskInfo info for the appeared task
-     * @param leash surface leash for the appeared task
-     */
-    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
-        AnimationContext context = new AnimationContext(leash);
-        mAnimationContextByTaskId.put(taskInfo.taskId, context);
-    }
-
-    /**
-     * Called when a split screen task vanished
-     * @param taskInfo info for the vanished task
-     */
-    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
-        AnimationContext context = mAnimationContextByTaskId.get(taskInfo.taskId);
-        if (context != null) {
-            final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-            resetSurface(transaction, context);
-            transaction.apply();
-            mTransactionPool.release(transaction);
-        }
-        mAnimationContextByTaskId.remove(taskInfo.taskId);
-    }
-
-    @Override
-    public void onStateChangeProgress(float progress) {
-        if (mAnimationContextByTaskId.size() == 0 || !mBothStagesVisible) return;
-
-        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-        mBackgroundController.ensureBackground(transaction);
-
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-
-            context.mCurrentCropRect.set(RECT_EVALUATOR
-                    .evaluate(progress, context.mStartCropRect, context.mEndCropRect));
-
-            transaction.setWindowCrop(context.mLeash, context.mCurrentCropRect)
-                    .setCornerRadius(context.mLeash, mWindowCornerRadiusPx);
-        }
-
-        transaction.apply();
-
-        mTransactionPool.release(transaction);
-    }
-
-    @Override
-    public void onStateChangeFinished() {
-        resetTransformations();
-    }
-
-    /**
-     * Called when split screen visibility changes
-     * @param bothStagesVisible true if both stages of the split screen are visible
-     */
-    public void onSplitVisibilityChanged(boolean bothStagesVisible) {
-        mBothStagesVisible = bothStagesVisible;
-        if (!bothStagesVisible) {
-            resetTransformations();
-        }
-    }
-
-    /**
-     * Called when split screen stage bounds changed
-     * @param bounds new bounds for this stage
-     */
-    public void onLayoutChanged(Rect bounds) {
-        mStageBounds.set(bounds);
-
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-            context.update();
-        }
-    }
-
-    private void resetTransformations() {
-        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-            resetSurface(transaction, context);
-        }
-        mBackgroundController.removeBackground(transaction);
-        transaction.apply();
-
-        mTransactionPool.release(transaction);
-    }
-
-    private void resetSurface(SurfaceControl.Transaction transaction, AnimationContext context) {
-        transaction
-                .setWindowCrop(context.mLeash, null)
-                .setCornerRadius(context.mLeash, 0.0F);
-    }
-
-    private class AnimationContext {
-        final SurfaceControl mLeash;
-        final Rect mStartCropRect = new Rect();
-        final Rect mEndCropRect = new Rect();
-        final Rect mCurrentCropRect = new Rect();
-
-        private AnimationContext(SurfaceControl leash) {
-            this.mLeash = leash;
-            update();
-        }
-
-        private void update() {
-            mStartCropRect.set(mStageBounds);
-
-            if (mTaskbarInsetsSource != null) {
-                // Only insets the cropping window with taskbar when taskbar is expanded
-                if (mTaskbarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight) {
-                    mStartCropRect.inset(mTaskbarInsetsSource
-                            .calculateVisibleInsets(mStartCropRect));
-                }
-            }
-
-            // Offset to surface coordinates as layout bounds are in screen coordinates
-            mStartCropRect.offsetTo(0, 0);
-
-            mEndCropRect.set(mStartCropRect);
-
-            int maxSize = Math.max(mEndCropRect.width(), mEndCropRect.height());
-            int margin = (int) (maxSize * CROPPING_START_MARGIN_FRACTION);
-            mStartCropRect.inset(margin, margin, margin, margin);
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 54d62ed..a0e176c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -261,7 +261,8 @@
                 WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
         params.setFitInsetsSides(0);
         params.setFitInsetsTypes(0);
-        params.format = PixelFormat.TRANSLUCENT;
+        params.format = suggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN
+                ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
         int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
                 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
index 95bc579..19d3acb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
@@ -20,10 +20,8 @@
 import static android.graphics.Color.WHITE;
 import static android.graphics.Color.alpha;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.view.ViewRootImpl.LOCAL_LAYOUT;
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
-import static android.view.WindowLayout.UNSPECIFIED_LENGTH;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
 import static android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
@@ -53,7 +51,6 @@
 import android.app.ActivityManager;
 import android.app.ActivityManager.TaskDescription;
 import android.app.ActivityThread;
-import android.app.WindowConfiguration;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -80,7 +77,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowInsets;
-import android.view.WindowLayout;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.window.ClientWindowFrames;
@@ -212,8 +208,6 @@
         final IWindowSession session = WindowManagerGlobal.getWindowSession();
         final SurfaceControl surfaceControl = new SurfaceControl();
         final ClientWindowFrames tmpFrames = new ClientWindowFrames();
-        final WindowLayout windowLayout = new WindowLayout();
-        final Rect displayCutoutSafe = new Rect();
 
         final InsetsSourceControl[] tmpControls = new InsetsSourceControl[0];
         final MergedConfiguration tmpMergedConfiguration = new MergedConfiguration();
@@ -238,7 +232,8 @@
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "TaskSnapshot#addToDisplay");
             final int res = session.addToDisplay(window, layoutParams, View.GONE, displayId,
-                    info.requestedVisibilities, tmpInputChannel, tmpInsetsState, tmpControls);
+                    info.requestedVisibilities, tmpInputChannel, tmpInsetsState, tmpControls,
+                    new Rect());
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             if (res < 0) {
                 Slog.w(TAG, "Failed to add snapshot starting window res=" + res);
@@ -250,25 +245,9 @@
         window.setOuter(snapshotSurface);
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "TaskSnapshot#relayout");
-            if (LOCAL_LAYOUT) {
-                if (!surfaceControl.isValid()) {
-                    session.updateVisibility(window, layoutParams, View.VISIBLE,
-                            tmpMergedConfiguration, surfaceControl, tmpInsetsState, tmpControls);
-                }
-                tmpInsetsState.getDisplayCutoutSafe(displayCutoutSafe);
-                final WindowConfiguration winConfig =
-                        tmpMergedConfiguration.getMergedConfiguration().windowConfiguration;
-                windowLayout.computeFrames(layoutParams, tmpInsetsState, displayCutoutSafe,
-                        winConfig.getBounds(), winConfig.getWindowingMode(), UNSPECIFIED_LENGTH,
-                        UNSPECIFIED_LENGTH, info.requestedVisibilities,
-                        null /* attachedWindowFrame */, 1f /* compatScale */, tmpFrames);
-                session.updateLayout(window, layoutParams, 0 /* flags */, tmpFrames,
-                        UNSPECIFIED_LENGTH, UNSPECIFIED_LENGTH);
-            } else {
-                session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0,
-                        tmpFrames, tmpMergedConfiguration, surfaceControl, tmpInsetsState,
-                        tmpControls, new Bundle());
-            }
+            session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0,
+                    tmpFrames, tmpMergedConfiguration, surfaceControl, tmpInsetsState,
+                    tmpControls, new Bundle());
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         } catch (RemoteException e) {
             snapshotSurface.clearWindowSynced();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
new file mode 100644
index 0000000..7234d55
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.transition;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
+
+import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
+import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP;
+import static com.android.wm.shell.splitscreen.StageCoordinator.FLAG_IS_DIVIDER_BAR;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.view.SurfaceControl;
+import android.view.WindowManager;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
+import android.window.WindowContainerTransaction;
+
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.pip.PipTransitionController;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.splitscreen.StageCoordinator;
+
+import java.util.ArrayList;
+
+/**
+ * A handler for dealing with transitions involving multiple other handlers. For example: an
+ * activity in split-screen going into PiP.
+ */
+public class DefaultMixedHandler implements Transitions.TransitionHandler {
+
+    private final Transitions mPlayer;
+    private final PipTransitionController mPipHandler;
+    private final StageCoordinator mSplitHandler;
+
+    private static class MixedTransition {
+        static final int TYPE_ENTER_PIP_FROM_SPLIT = 1;
+
+        /** The default animation for this mixed transition. */
+        static final int ANIM_TYPE_DEFAULT = 0;
+
+        /** For ENTER_PIP_FROM_SPLIT, indicates that this is a to-home animation. */
+        static final int ANIM_TYPE_GOING_HOME = 1;
+
+        final int mType;
+        int mAnimType = 0;
+        final IBinder mTransition;
+
+        Transitions.TransitionFinishCallback mFinishCallback = null;
+        Transitions.TransitionHandler mLeftoversHandler = null;
+
+        /**
+         * Mixed transitions are made up of multiple "parts". This keeps track of how many
+         * parts are currently animating.
+         */
+        int mInFlightSubAnimations = 0;
+
+        MixedTransition(int type, IBinder transition) {
+            mType = type;
+            mTransition = transition;
+        }
+    }
+    private final ArrayList<MixedTransition> mActiveTransitions = new ArrayList<>();
+
+    public DefaultMixedHandler(@NonNull Transitions player,
+            @NonNull PipTransitionController pipHandler, @NonNull StageCoordinator splitHandler) {
+        mPlayer = player;
+        mPipHandler = pipHandler;
+        mSplitHandler = splitHandler;
+    }
+
+    @Nullable
+    @Override
+    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
+            @NonNull TransitionRequestInfo request) {
+        if (mPipHandler.requestHasPipEnter(request) && mSplitHandler.isSplitActive()) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a PiP-enter request while "
+                    + "Split-Screen is active, so treat it as Mixed.");
+            if (request.getRemoteTransition() != null) {
+                throw new IllegalStateException("Unexpected remote transition in"
+                        + "pip-enter-from-split request");
+            }
+            mActiveTransitions.add(new MixedTransition(MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT,
+                    transition));
+
+            WindowContainerTransaction out = new WindowContainerTransaction();
+            mPipHandler.augmentRequest(transition, request, out);
+            mSplitHandler.addEnterOrExitIfNeeded(request, out);
+            return out;
+        }
+        return null;
+    }
+
+    private TransitionInfo subCopy(@NonNull TransitionInfo info,
+            @WindowManager.TransitionType int newType) {
+        final TransitionInfo out = new TransitionInfo(newType, info.getFlags());
+        for (int i = 0; i < info.getChanges().size(); ++i) {
+            out.getChanges().add(info.getChanges().get(i));
+        }
+        out.setRootLeash(info.getRootLeash(), info.getRootOffset().x, info.getRootOffset().y);
+        out.setAnimationOptions(info.getAnimationOptions());
+        return out;
+    }
+
+    private boolean isHomeOpening(@NonNull TransitionInfo.Change change) {
+        return change.getTaskInfo() != null
+                && change.getTaskInfo().getActivityType() != ACTIVITY_TYPE_HOME;
+    }
+
+    private boolean isWallpaper(@NonNull TransitionInfo.Change change) {
+        return (change.getFlags() & FLAG_IS_WALLPAPER) != 0;
+    }
+
+    @Override
+    public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        MixedTransition mixed = null;
+        for (int i = mActiveTransitions.size() - 1; i >= 0; --i) {
+            if (mActiveTransitions.get(i).mTransition != transition) continue;
+            mixed = mActiveTransitions.get(i);
+            break;
+        }
+        if (mixed == null) return false;
+
+        if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
+            return animateEnterPipFromSplit(mixed, info, startTransaction, finishTransaction,
+                    finishCallback);
+        } else {
+            mActiveTransitions.remove(mixed);
+            throw new IllegalStateException("Starting mixed animation without a known mixed type? "
+                    + mixed.mType);
+        }
+    }
+
+    private boolean animateEnterPipFromSplit(@NonNull final MixedTransition mixed,
+            @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull SurfaceControl.Transaction finishTransaction,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animating a mixed transition for "
+                + "entering PIP while Split-Screen is active.");
+        TransitionInfo.Change pipChange = null;
+        TransitionInfo.Change wallpaper = null;
+        final TransitionInfo everythingElse = subCopy(info, TRANSIT_TO_BACK);
+        boolean homeIsOpening = false;
+        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+            TransitionInfo.Change change = info.getChanges().get(i);
+            if (mPipHandler.isEnteringPip(change, info.getType())) {
+                if (pipChange != null) {
+                    throw new IllegalStateException("More than 1 pip-entering changes in one"
+                            + " transition? " + info);
+                }
+                pipChange = change;
+                // going backwards, so remove-by-index is fine.
+                everythingElse.getChanges().remove(i);
+            } else if (isHomeOpening(change)) {
+                homeIsOpening = true;
+            } else if (isWallpaper(change)) {
+                wallpaper = change;
+            }
+        }
+        if (pipChange == null) {
+            // um, something probably went wrong.
+            return false;
+        }
+        final boolean isGoingHome = homeIsOpening;
+        mixed.mFinishCallback = finishCallback;
+        Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
+            --mixed.mInFlightSubAnimations;
+            if (mixed.mInFlightSubAnimations > 0) return;
+            mActiveTransitions.remove(mixed);
+            if (isGoingHome) {
+                mSplitHandler.onTransitionAnimationComplete();
+            }
+            mixed.mFinishCallback.onTransitionFinished(wct, wctCB);
+        };
+        if (isGoingHome) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animation is actually mixed "
+                    + "since entering-PiP caused us to leave split and return home.");
+            // We need to split the transition into 2 parts: the pip part (animated by pip)
+            // and the dismiss-part (animated by launcher).
+            mixed.mInFlightSubAnimations = 2;
+            // immediately make the wallpaper visible (so that we don't see it pop-in during
+            // the time it takes to start recents animation (which is remote).
+            if (wallpaper != null) {
+                startTransaction.show(wallpaper.getLeash()).setAlpha(wallpaper.getLeash(), 1.f);
+            }
+            // make a new startTransaction because pip's startEnterAnimation "consumes" it so
+            // we need a separate one to send over to launcher.
+            SurfaceControl.Transaction otherStartT = new SurfaceControl.Transaction();
+            // Let split update internal state for dismiss.
+            mSplitHandler.prepareDismissAnimation(STAGE_TYPE_UNDEFINED,
+                    EXIT_REASON_CHILD_TASK_ENTER_PIP, everythingElse, otherStartT,
+                    finishTransaction);
+
+            // We are trying to accommodate launcher's close animation which can't handle the
+            // divider-bar, so if split-handler is closing the divider-bar, just hide it and remove
+            // from transition info.
+            for (int i = everythingElse.getChanges().size() - 1; i >= 0; --i) {
+                if ((everythingElse.getChanges().get(i).getFlags() & FLAG_IS_DIVIDER_BAR) != 0) {
+                    everythingElse.getChanges().remove(i);
+                    break;
+                }
+            }
+
+            mPipHandler.startEnterAnimation(pipChange, startTransaction, finishTransaction,
+                    finishCB);
+            // Dispatch the rest of the transition normally. This will most-likely be taken by
+            // recents or default handler.
+            mixed.mLeftoversHandler = mPlayer.dispatchTransition(mixed.mTransition, everythingElse,
+                    otherStartT, finishTransaction, finishCB, this);
+        } else {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  Not leaving split, so just "
+                    + "forward animation to Pip-Handler.");
+            // This happens if the pip-ing activity is in a multi-activity task (and thus a
+            // new pip task is spawned). In this case, we don't actually exit split so we can
+            // just let pip transition handle the animation verbatim.
+            mixed.mInFlightSubAnimations = 1;
+            mPipHandler.startAnimation(mixed.mTransition, info, startTransaction, finishTransaction,
+                    finishCB);
+        }
+        return true;
+    }
+
+    @Override
+    public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        for (int i = 0; i < mActiveTransitions.size(); ++i) {
+            if (mActiveTransitions.get(i) != mergeTarget) continue;
+            MixedTransition mixed = mActiveTransitions.get(i);
+            if (mixed.mInFlightSubAnimations <= 0) {
+                // Already done, so no need to end it.
+                return;
+            }
+            if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
+                if (mixed.mAnimType == MixedTransition.ANIM_TYPE_GOING_HOME) {
+                    boolean ended = mSplitHandler.end();
+                    // If split couldn't end (because it is remote), then don't end everything else
+                    // since we have to play out the animation anyways.
+                    if (!ended) return;
+                    mPipHandler.end();
+                    if (mixed.mLeftoversHandler != null) {
+                        mixed.mLeftoversHandler.mergeAnimation(transition, info, t, mergeTarget,
+                                finishCallback);
+                    }
+                } else {
+                    mPipHandler.end();
+                }
+            } else {
+                throw new IllegalStateException("Playing a mixed transition with unknown type? "
+                        + mixed.mType);
+            }
+        }
+    }
+
+    @Override
+    public void onTransitionMerged(@NonNull IBinder transition) {
+        MixedTransition mixed = null;
+        for (int i = mActiveTransitions.size() - 1; i >= 0; --i) {
+            if (mActiveTransitions.get(i).mTransition != transition) continue;
+            mixed = mActiveTransitions.remove(i);
+            break;
+        }
+        if (mixed == null) return;
+        if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
+            mPipHandler.onTransitionMerged(transition);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 9154226..dcd6277 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -24,6 +24,7 @@
 import static android.app.ActivityOptions.ANIM_SCALE_UP;
 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
 import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE;
@@ -42,6 +43,7 @@
 import static android.view.WindowManager.TRANSIT_RELAUNCH;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.view.WindowManager.transitTypeToString;
 import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
 import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
 import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION;
@@ -470,8 +472,9 @@
                 }
 
                 final Rect clipRect = Transitions.isClosingType(change.getMode())
-                        ? mRotator.getEndBoundsInStartRotation(change)
-                        : change.getEndAbsBounds();
+                        ? new Rect(mRotator.getEndBoundsInStartRotation(change))
+                        : new Rect(change.getEndAbsBounds());
+                clipRect.offsetTo(0, 0);
 
                 if (delayedEdgeExtension) {
                     // If the edge extension needs to happen after the startTransition has been
@@ -520,6 +523,18 @@
         return true;
     }
 
+    @Override
+    public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
+            @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        ArrayList<Animator> anims = mAnimations.get(mergeTarget);
+        if (anims == null) return;
+        for (int i = anims.size() - 1; i >= 0; --i) {
+            final Animator anim = anims.get(i);
+            mAnimExecutor.execute(anim::end);
+        }
+    }
+
     private void edgeExtendWindow(TransitionInfo.Change change,
             Animation a, SurfaceControl.Transaction startTransaction,
             SurfaceControl.Transaction finishTransaction) {
@@ -684,6 +699,8 @@
         final Rect endBounds = Transitions.isClosingType(changeMode)
                 ? mRotator.getEndBoundsInStartRotation(change)
                 : change.getEndAbsBounds();
+        final boolean isDream =
+                isTask && change.getTaskInfo().topActivityType == ACTIVITY_TYPE_DREAM;
 
         if (info.isKeyguardGoingAway()) {
             a = mTransitionAnimation.loadKeyguardExitAnimation(flags,
@@ -726,7 +743,17 @@
         } else {
             int animAttr = 0;
             boolean translucent = false;
-            if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_OPEN) {
+            if (isDream) {
+                if (type == TRANSIT_OPEN) {
+                    animAttr = enter
+                            ? R.styleable.WindowAnimation_dreamActivityOpenEnterAnimation
+                            : R.styleable.WindowAnimation_dreamActivityOpenExitAnimation;
+                } else if (type == TRANSIT_CLOSE) {
+                    animAttr = enter
+                            ? 0
+                            : R.styleable.WindowAnimation_dreamActivityCloseExitAnimation;
+                }
+            } else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_OPEN) {
                 animAttr = enter
                         ? R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
                         : R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
@@ -790,6 +817,11 @@
                     a = mTransitionAnimation.loadDefaultAnimationAttr(animAttr, translucent);
                 }
             }
+
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+                    "loadAnimation: anim=%s animAttr=0x%x type=%s isEntrance=%b", a, animAttr,
+                    transitTypeToString(type),
+                    enter);
         }
 
         if (a != null) {
@@ -834,13 +866,19 @@
             });
         };
         va.addListener(new AnimatorListenerAdapter() {
+            private boolean mFinished = false;
+
             @Override
             public void onAnimationEnd(Animator animation) {
+                if (mFinished) return;
+                mFinished = true;
                 finisher.run();
             }
 
             @Override
             public void onAnimationCancel(Animator animation) {
+                if (mFinished) return;
+                mFinished = true;
                 finisher.run();
             }
         });
@@ -954,7 +992,7 @@
 
     private static void applyTransformation(long time, SurfaceControl.Transaction t,
             SurfaceControl leash, Animation anim, Transformation transformation, float[] matrix,
-            Point position, float cornerRadius, @Nullable Rect clipRect) {
+            Point position, float cornerRadius, @Nullable Rect immutableClipRect) {
         anim.getTransformation(time, transformation);
         if (position != null) {
             transformation.getMatrix().postTranslate(position.x, position.y);
@@ -962,6 +1000,7 @@
         t.setMatrix(leash, transformation.getMatrix(), matrix);
         t.setAlpha(leash, transformation.getAlpha());
 
+        final Rect clipRect = immutableClipRect == null ? null : new Rect(immutableClipRect);
         Insets extensionInsets = Insets.min(transformation.getInsets(), Insets.NONE);
         if (!extensionInsets.equals(Insets.NONE) && clipRect != null && !clipRect.isEmpty()) {
             // Clip out any overflowing edge extension
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index 435d670..de0f47f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -23,6 +23,7 @@
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
 
@@ -287,12 +288,14 @@
                     finishT.setAlpha(leash, 1.f);
                 }
             } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) {
-                // Wallpaper is a bit of an anomaly: it's visibility is tied to other WindowStates.
-                // As a result, we actually can't hide it's WindowToken because there may not be a
-                // transition associated with it becoming visible again. Fortunately, since it is
-                // always z-ordered to the back, we don't have to worry about it flickering to the
-                // front during reparenting, so the hide here isn't necessary for it.
-                if ((change.getFlags() & FLAG_IS_WALLPAPER) == 0) {
+                // Wallpaper/IME are anomalies: their visibility is tied to other WindowStates.
+                // As a result, we actually can't hide their WindowTokens because there may not be a
+                // transition associated with them becoming visible again. Fortunately, since
+                // wallpapers are always z-ordered to the back, we don't have to worry about it
+                // flickering to the front during reparenting. Similarly, the IME is reparented to
+                // the associated app, so its visibility is coupled. So, an explicit hide is not
+                // needed visually anyways.
+                if ((change.getFlags() & (FLAG_IS_WALLPAPER | FLAG_IS_INPUT_METHOD)) == 0) {
                     finishT.hide(leash);
                 }
             }
@@ -309,13 +312,14 @@
         if (info.getRootLeash().isValid()) {
             t.show(info.getRootLeash());
         }
+        final int numChanges = info.getChanges().size();
         // Put animating stuff above this line and put static stuff below it.
-        int zSplitLine = info.getChanges().size();
+        final int zSplitLine = numChanges + 1;
         // changes should be ordered top-to-bottom in z
-        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+        for (int i = numChanges - 1; i >= 0; --i) {
             final TransitionInfo.Change change = info.getChanges().get(i);
             final SurfaceControl leash = change.getLeash();
-            final int mode = info.getChanges().get(i).getMode();
+            final int mode = change.getMode();
 
             // Don't reparent anything that isn't independent within its parents
             if (!TransitionInfo.isIndependent(change, info)) {
@@ -329,26 +333,31 @@
                 t.setPosition(leash, change.getStartAbsBounds().left - info.getRootOffset().x,
                         change.getStartAbsBounds().top - info.getRootOffset().y);
             }
+            final int layer;
             // Put all the OPEN/SHOW on top
-            if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
+            if ((change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
+                // Wallpaper is always at the bottom.
+                layer = 0;
+            } else if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
                 if (isOpening) {
                     // put on top
-                    t.setLayer(leash, zSplitLine + info.getChanges().size() - i);
+                    layer = zSplitLine + numChanges - i;
                 } else {
                     // put on bottom
-                    t.setLayer(leash, zSplitLine - i);
+                    layer = zSplitLine - i;
                 }
             } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) {
                 if (isOpening) {
                     // put on bottom and leave visible
-                    t.setLayer(leash, zSplitLine - i);
+                    layer = zSplitLine - i;
                 } else {
                     // put on top
-                    t.setLayer(leash, zSplitLine + info.getChanges().size() - i);
+                    layer = zSplitLine + numChanges - i;
                 }
             } else { // CHANGE or other
-                t.setLayer(leash, zSplitLine + info.getChanges().size() - i);
+                layer = zSplitLine + numChanges - i;
             }
+            t.setLayer(leash, layer);
         }
     }
 
@@ -377,6 +386,7 @@
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Invalid root leash (%s): %s",
                     transitionToken, info);
             t.apply();
+            finishT.apply();
             onAbort(transitionToken);
             return;
         }
@@ -400,6 +410,7 @@
             }
             if (nonTaskChange && transferStartingWindow) {
                 t.apply();
+                finishT.apply();
                 // Treat this as an abort since we are bypassing any merge logic and effectively
                 // finishing immediately.
                 onAbort(transitionToken);
@@ -435,33 +446,42 @@
                 playing.mToken, (wct, cb) -> onFinish(merging.mToken, wct, cb));
     }
 
-    boolean startAnimation(@NonNull ActiveTransition active, TransitionHandler handler) {
-        return handler.startAnimation(active.mToken, active.mInfo, active.mStartT, active.mFinishT,
-                (wct, cb) -> onFinish(active.mToken, wct, cb));
-    }
-
-    void playTransition(@NonNull ActiveTransition active) {
+    private void playTransition(@NonNull ActiveTransition active) {
         setupAnimHierarchy(active.mInfo, active.mStartT, active.mFinishT);
 
         // If a handler already chose to run this animation, try delegating to it first.
         if (active.mHandler != null) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " try firstHandler %s",
                     active.mHandler);
-            if (startAnimation(active, active.mHandler)) {
+            boolean consumed = active.mHandler.startAnimation(active.mToken, active.mInfo,
+                    active.mStartT, active.mFinishT, (wct, cb) -> onFinish(active.mToken, wct, cb));
+            if (consumed) {
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by firstHandler");
                 return;
             }
         }
-        // Otherwise give every other handler a chance (in order)
+        // Otherwise give every other handler a chance
+        active.mHandler = dispatchTransition(active.mToken, active.mInfo, active.mStartT,
+                active.mFinishT, (wct, cb) -> onFinish(active.mToken, wct, cb), active.mHandler);
+    }
+
+    /**
+     * Gives every handler (in order) a chance to animate until one consumes the transition.
+     * @return the handler which consumed the transition.
+     */
+    TransitionHandler dispatchTransition(@NonNull IBinder transition, @NonNull TransitionInfo info,
+            @NonNull SurfaceControl.Transaction startT, @NonNull SurfaceControl.Transaction finishT,
+            @NonNull TransitionFinishCallback finishCB, @Nullable TransitionHandler skip) {
         for (int i = mHandlers.size() - 1; i >= 0; --i) {
-            if (mHandlers.get(i) == active.mHandler) continue;
+            if (mHandlers.get(i) == skip) continue;
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " try handler %s",
                     mHandlers.get(i));
-            if (startAnimation(active, mHandlers.get(i))) {
+            boolean consumed = mHandlers.get(i).startAnimation(transition, info, startT, finishT,
+                    finishCB);
+            if (consumed) {
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by %s",
                         mHandlers.get(i));
-                active.mHandler = mHandlers.get(i);
-                return;
+                return mHandlers.get(i);
             }
         }
         throw new IllegalStateException(
@@ -615,8 +635,9 @@
                 if (wct == null) {
                     wct = new WindowContainerTransaction();
                 }
-                mDisplayController.getChangeController().dispatchOnRotateDisplay(wct,
-                        change.getDisplayId(), change.getStartRotation(), change.getEndRotation());
+                mDisplayController.getChangeController().dispatchOnDisplayChange(wct,
+                        change.getDisplayId(), change.getStartRotation(), change.getEndRotation(),
+                        null /* newDisplayAreaInfo */);
             }
         }
         active.mToken = mOrganizer.startTransition(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldAnimationController.java
new file mode 100644
index 0000000..05a024a
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldAnimationController.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.unfold;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
+import android.annotation.NonNull;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.TaskInfo;
+import android.util.SparseArray;
+import android.view.SurfaceControl;
+
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener;
+import com.android.wm.shell.unfold.animation.UnfoldTaskAnimator;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.Executor;
+
+import dagger.Lazy;
+
+/**
+ * Manages fold/unfold animations of tasks on foldable devices.
+ * When folding or unfolding a foldable device we play animations that
+ * transform task cropping/scaling/rounded corners.
+ *
+ * This controller manages:
+ *  1) Folding/unfolding when Shell transitions disabled
+ *  2) Folding when Shell transitions enabled, unfolding is managed by
+ *    {@link com.android.wm.shell.unfold.UnfoldTransitionHandler}
+ */
+public class UnfoldAnimationController implements UnfoldListener {
+
+    private final ShellUnfoldProgressProvider mUnfoldProgressProvider;
+    private final Executor mExecutor;
+    private final TransactionPool mTransactionPool;
+    private final List<UnfoldTaskAnimator> mAnimators;
+    private final Lazy<Optional<UnfoldTransitionHandler>> mUnfoldTransitionHandler;
+
+    private final SparseArray<SurfaceControl> mTaskSurfaces = new SparseArray<>();
+    private final SparseArray<UnfoldTaskAnimator> mAnimatorsByTaskId = new SparseArray<>();
+
+    public UnfoldAnimationController(@NonNull TransactionPool transactionPool,
+            @NonNull ShellUnfoldProgressProvider unfoldProgressProvider,
+            @NonNull List<UnfoldTaskAnimator> animators,
+            @NonNull Lazy<Optional<UnfoldTransitionHandler>> unfoldTransitionHandler,
+            @NonNull Executor executor) {
+        mUnfoldProgressProvider = unfoldProgressProvider;
+        mUnfoldTransitionHandler = unfoldTransitionHandler;
+        mTransactionPool = transactionPool;
+        mExecutor = executor;
+        mAnimators = animators;
+    }
+
+    /**
+     * Initializes the controller, starts listening for the external events
+     */
+    public void init() {
+        mUnfoldProgressProvider.addListener(mExecutor, this);
+
+        for (int i = 0; i < mAnimators.size(); i++) {
+            final UnfoldTaskAnimator animator = mAnimators.get(i);
+            animator.init();
+            animator.start();
+        }
+    }
+
+    /**
+     * Called when a task appeared
+     * @param taskInfo info for the appeared task
+     * @param leash surface leash for the appeared task
+     */
+    public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
+        mTaskSurfaces.put(taskInfo.taskId, leash);
+
+        // Find the first matching animator
+        for (int i = 0; i < mAnimators.size(); i++) {
+            final UnfoldTaskAnimator animator = mAnimators.get(i);
+            if (animator.isApplicableTask(taskInfo)) {
+                mAnimatorsByTaskId.put(taskInfo.taskId, animator);
+                animator.onTaskAppeared(taskInfo, leash);
+                break;
+            }
+        }
+    }
+
+    /**
+     * Called when task info changed
+     * @param taskInfo info for the changed task
+     */
+    public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
+        final UnfoldTaskAnimator animator = mAnimatorsByTaskId.get(taskInfo.taskId);
+        final boolean isCurrentlyApplicable = animator != null;
+
+        if (isCurrentlyApplicable) {
+            final boolean isApplicable = animator.isApplicableTask(taskInfo);
+            if (isApplicable) {
+                // Still applicable, send update
+                animator.onTaskChanged(taskInfo);
+            } else {
+                // Became inapplicable
+                resetTask(animator, taskInfo);
+                animator.onTaskVanished(taskInfo);
+                mAnimatorsByTaskId.remove(taskInfo.taskId);
+            }
+        } else {
+            // Find the first matching animator
+            for (int i = 0; i < mAnimators.size(); i++) {
+                final UnfoldTaskAnimator currentAnimator = mAnimators.get(i);
+                if (currentAnimator.isApplicableTask(taskInfo)) {
+                    // Became applicable
+                    mAnimatorsByTaskId.put(taskInfo.taskId, currentAnimator);
+
+                    SurfaceControl leash = mTaskSurfaces.get(taskInfo.taskId);
+                    currentAnimator.onTaskAppeared(taskInfo, leash);
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Called when a task vanished
+     * @param taskInfo info for the vanished task
+     */
+    public void onTaskVanished(RunningTaskInfo taskInfo) {
+        mTaskSurfaces.remove(taskInfo.taskId);
+
+        final UnfoldTaskAnimator animator = mAnimatorsByTaskId.get(taskInfo.taskId);
+        final boolean isCurrentlyApplicable = animator != null;
+
+        if (isCurrentlyApplicable) {
+            resetTask(animator, taskInfo);
+            animator.onTaskVanished(taskInfo);
+            mAnimatorsByTaskId.remove(taskInfo.taskId);
+        }
+    }
+
+    @Override
+    public void onStateChangeStarted() {
+        if (mUnfoldTransitionHandler.get().get().willHandleTransition()) {
+            return;
+        }
+
+        SurfaceControl.Transaction transaction = null;
+        for (int i = 0; i < mAnimators.size(); i++) {
+            final UnfoldTaskAnimator animator = mAnimators.get(i);
+            if (animator.hasActiveTasks()) {
+                if (transaction == null) transaction = mTransactionPool.acquire();
+                animator.prepareStartTransaction(transaction);
+            }
+        }
+
+        if (transaction != null) {
+            transaction.apply();
+            mTransactionPool.release(transaction);
+        }
+    }
+
+    @Override
+    public void onStateChangeProgress(float progress) {
+        if (mUnfoldTransitionHandler.get().get().willHandleTransition()) {
+            return;
+        }
+
+        SurfaceControl.Transaction transaction = null;
+        for (int i = 0; i < mAnimators.size(); i++) {
+            final UnfoldTaskAnimator animator = mAnimators.get(i);
+            if (animator.hasActiveTasks()) {
+                if (transaction == null) transaction = mTransactionPool.acquire();
+                animator.applyAnimationProgress(progress, transaction);
+            }
+        }
+
+        if (transaction != null) {
+            transaction.apply();
+            mTransactionPool.release(transaction);
+        }
+    }
+
+    @Override
+    public void onStateChangeFinished() {
+        if (mUnfoldTransitionHandler.get().get().willHandleTransition()) {
+            return;
+        }
+
+        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
+
+        for (int i = 0; i < mAnimators.size(); i++) {
+            final UnfoldTaskAnimator animator = mAnimators.get(i);
+            animator.resetAllSurfaces(transaction);
+            animator.prepareFinishTransaction(transaction);
+        }
+
+        transaction.apply();
+
+        mTransactionPool.release(transaction);
+    }
+
+    private void resetTask(UnfoldTaskAnimator animator, TaskInfo taskInfo) {
+        if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) {
+            // PiP task has its own cleanup path, ignore surface reset to avoid conflict.
+            return;
+        }
+        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
+        animator.resetSurface(taskInfo, transaction);
+        transaction.apply();
+        mTransactionPool.release(transaction);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
index 9faf454..86ca292 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
@@ -79,7 +79,7 @@
     }
 
     private float[] getBackgroundColor(Context context) {
-        int colorInt = context.getResources().getColor(R.color.unfold_transition_background);
+        int colorInt = context.getResources().getColor(R.color.taskbar_background);
         return new float[]{
                 (float) red(colorInt) / 255.0F,
                 (float) green(colorInt) / 255.0F,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
index 6396039..9bf32fa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
@@ -16,8 +16,6 @@
 
 package com.android.wm.shell.unfold;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 
 import android.os.IBinder;
@@ -34,11 +32,19 @@
 import com.android.wm.shell.transition.Transitions.TransitionFinishCallback;
 import com.android.wm.shell.transition.Transitions.TransitionHandler;
 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener;
+import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator;
+import com.android.wm.shell.unfold.animation.SplitTaskUnfoldAnimator;
+import com.android.wm.shell.unfold.animation.UnfoldTaskAnimator;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Executor;
 
+/**
+ * Transition handler that is responsible for animating app surfaces when unfolding of foldable
+ * devices. It does not handle the folding animation, which is done in
+ * {@link UnfoldAnimationController}.
+ */
 public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListener {
 
     private final ShellUnfoldProgressProvider mUnfoldProgressProvider;
@@ -51,17 +57,26 @@
     @Nullable
     private IBinder mTransition;
 
-    private final List<TransitionInfo.Change> mAnimatedFullscreenTasks = new ArrayList<>();
+    private final List<UnfoldTaskAnimator> mAnimators = new ArrayList<>();
 
     public UnfoldTransitionHandler(ShellUnfoldProgressProvider unfoldProgressProvider,
-            TransactionPool transactionPool, Executor executor, Transitions transitions) {
+            FullscreenUnfoldTaskAnimator fullscreenUnfoldAnimator,
+            SplitTaskUnfoldAnimator splitUnfoldTaskAnimator,
+            TransactionPool transactionPool,
+            Executor executor, Transitions transitions) {
         mUnfoldProgressProvider = unfoldProgressProvider;
         mTransactionPool = transactionPool;
         mExecutor = executor;
         mTransitions = transitions;
+
+        mAnimators.add(splitUnfoldTaskAnimator);
+        mAnimators.add(fullscreenUnfoldAnimator);
     }
 
     public void init() {
+        for (int i = 0; i < mAnimators.size(); i++) {
+            mAnimators.get(i).init();
+        }
         mTransitions.addHandler(this);
         mUnfoldProgressProvider.addListener(mExecutor, this);
     }
@@ -71,49 +86,69 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull TransitionFinishCallback finishCallback) {
-
         if (transition != mTransition) return false;
 
-        startTransaction.apply();
+        for (int i = 0; i < mAnimators.size(); i++) {
+            final UnfoldTaskAnimator animator = mAnimators.get(i);
+            animator.clearTasks();
 
-        mAnimatedFullscreenTasks.clear();
-        info.getChanges().forEach(change -> {
-            final boolean allowedToAnimate = change.getTaskInfo() != null
-                    && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
-                    && change.getTaskInfo().getActivityType() != ACTIVITY_TYPE_HOME
-                    && change.getMode() == TRANSIT_CHANGE;
+            info.getChanges().forEach(change -> {
+                if (change.getTaskInfo() != null
+                        && change.getMode() == TRANSIT_CHANGE
+                        && animator.isApplicableTask(change.getTaskInfo())) {
+                    animator.onTaskAppeared(change.getTaskInfo(), change.getLeash());
+                }
+            });
 
-            if (allowedToAnimate) {
-                mAnimatedFullscreenTasks.add(change);
+            if (animator.hasActiveTasks()) {
+                animator.prepareStartTransaction(startTransaction);
+                animator.prepareFinishTransaction(finishTransaction);
+                animator.start();
             }
-        });
+        }
 
+        startTransaction.apply();
         mFinishCallback = finishCallback;
-        mTransition = null;
         return true;
     }
 
     @Override
     public void onStateChangeProgress(float progress) {
-        mAnimatedFullscreenTasks.forEach(change -> {
-            final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
+        if (mTransition == null) return;
 
-            // TODO: this is a placeholder animation, replace with a spec version in the next CLs
-            final float testScale = 0.8f + 0.2f * progress;
-            transaction.setScale(change.getLeash(), testScale, testScale);
+        SurfaceControl.Transaction transaction = null;
 
+        for (int i = 0; i < mAnimators.size(); i++) {
+            final UnfoldTaskAnimator animator = mAnimators.get(i);
+
+            if (animator.hasActiveTasks()) {
+                if (transaction == null) {
+                    transaction = mTransactionPool.acquire();
+                }
+
+                animator.applyAnimationProgress(progress, transaction);
+            }
+        }
+
+        if (transaction != null) {
             transaction.apply();
             mTransactionPool.release(transaction);
-        });
+        }
     }
 
     @Override
     public void onStateChangeFinished() {
-        if (mFinishCallback != null) {
-            mFinishCallback.onTransitionFinished(null, null);
-            mFinishCallback = null;
-            mAnimatedFullscreenTasks.clear();
+        if (mFinishCallback == null) return;
+
+        for (int i = 0; i < mAnimators.size(); i++) {
+            final UnfoldTaskAnimator animator = mAnimators.get(i);
+            animator.clearTasks();
+            animator.stop();
         }
+
+        mFinishCallback.onTransitionFinished(null, null);
+        mFinishCallback = null;
+        mTransition = null;
     }
 
     @Nullable
@@ -127,4 +162,8 @@
         }
         return null;
     }
+
+    public boolean willHandleTransition() {
+        return mTransition != null;
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
similarity index 66%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
index aa3868c..eab82f0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.fullscreen;
+package com.android.wm.shell.unfold.animation;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.util.MathUtils.lerp;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.animation.RectEvaluator;
 import android.animation.TypeEvaluator;
 import android.annotation.NonNull;
-import android.app.ActivityManager;
 import android.app.TaskInfo;
 import android.content.Context;
 import android.graphics.Matrix;
@@ -32,22 +32,26 @@
 import android.view.InsetsSource;
 import android.view.InsetsState;
 import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
 
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.wm.shell.common.DisplayInsetsController;
-import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener;
-import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
-import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener;
+import com.android.wm.shell.unfold.UnfoldAnimationController;
 import com.android.wm.shell.unfold.UnfoldBackgroundController;
 
-import java.util.concurrent.Executor;
-
 /**
- * Controls full screen app unfold transition: animating cropping window and scaling when
- * folding or unfolding a foldable device.
+ * This helper class contains logic that calculates scaling and cropping parameters
+ * for the folding/unfolding animation. As an input it receives TaskInfo objects and
+ * surfaces leashes and as an output it could fill surface transactions with required
+ * transformations.
+ *
+ * This class is used by
+ * {@link com.android.wm.shell.unfold.UnfoldTransitionHandler} and
+ * {@link UnfoldAnimationController}. They use independent
+ * instances of FullscreenUnfoldTaskAnimator.
  */
-public final class FullscreenUnfoldController implements UnfoldListener,
-        OnInsetsChangedListener {
+public class FullscreenUnfoldTaskAnimator implements UnfoldTaskAnimator,
+        DisplayInsetsController.OnInsetsChangedListener {
 
     private static final float[] FLOAT_9 = new float[9];
     private static final TypeEvaluator<Rect> RECT_EVALUATOR = new RectEvaluator(new Rect());
@@ -57,80 +61,29 @@
     private static final float END_SCALE = 1f;
     private static final float START_SCALE = END_SCALE - VERTICAL_START_MARGIN * 2;
 
-    private final Executor mExecutor;
-    private final ShellUnfoldProgressProvider mProgressProvider;
-    private final DisplayInsetsController mDisplayInsetsController;
-
     private final SparseArray<AnimationContext> mAnimationContextByTaskId = new SparseArray<>();
+    private final int mExpandedTaskBarHeight;
+    private final float mWindowCornerRadiusPx;
+    private final DisplayInsetsController mDisplayInsetsController;
     private final UnfoldBackgroundController mBackgroundController;
 
     private InsetsSource mTaskbarInsetsSource;
 
-    private final float mWindowCornerRadiusPx;
-    private final float mExpandedTaskBarHeight;
-
-    private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
-
-    public FullscreenUnfoldController(
-            @NonNull Context context,
-            @NonNull Executor executor,
+    public FullscreenUnfoldTaskAnimator(Context context,
             @NonNull UnfoldBackgroundController backgroundController,
-            @NonNull ShellUnfoldProgressProvider progressProvider,
-            @NonNull DisplayInsetsController displayInsetsController
-    ) {
-        mExecutor = executor;
-        mProgressProvider = progressProvider;
+            DisplayInsetsController displayInsetsController) {
         mDisplayInsetsController = displayInsetsController;
-        mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(context);
+        mBackgroundController = backgroundController;
         mExpandedTaskBarHeight = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.taskbar_frame_height);
-        mBackgroundController = backgroundController;
+        mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(context);
     }
 
-    /**
-     * Initializes the controller
-     */
     public void init() {
-        mProgressProvider.addListener(mExecutor, this);
         mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY, this);
     }
 
     @Override
-    public void onStateChangeProgress(float progress) {
-        if (mAnimationContextByTaskId.size() == 0) return;
-
-        mBackgroundController.ensureBackground(mTransaction);
-
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-
-            context.mCurrentCropRect.set(RECT_EVALUATOR
-                    .evaluate(progress, context.mStartCropRect, context.mEndCropRect));
-
-            float scale = lerp(START_SCALE, END_SCALE, progress);
-            context.mMatrix.setScale(scale, scale, context.mCurrentCropRect.exactCenterX(),
-                    context.mCurrentCropRect.exactCenterY());
-
-            mTransaction.setWindowCrop(context.mLeash, context.mCurrentCropRect)
-                    .setMatrix(context.mLeash, context.mMatrix, FLOAT_9)
-                    .setCornerRadius(context.mLeash, mWindowCornerRadiusPx);
-        }
-
-        mTransaction.apply();
-    }
-
-    @Override
-    public void onStateChangeFinished() {
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-            resetSurface(context);
-        }
-
-        mBackgroundController.removeBackground(mTransaction);
-        mTransaction.apply();
-    }
-
-    @Override
     public void insetsChanged(InsetsState insetsState) {
         mTaskbarInsetsSource = insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
         for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
@@ -139,47 +92,92 @@
         }
     }
 
-    /**
-     * Called when a new matching task appeared
-     */
-    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
+    public boolean hasActiveTasks() {
+        return mAnimationContextByTaskId.size() > 0;
+    }
+
+    @Override
+    public void onTaskAppeared(TaskInfo taskInfo, SurfaceControl leash) {
         AnimationContext animationContext = new AnimationContext(leash, mTaskbarInsetsSource,
                 taskInfo);
         mAnimationContextByTaskId.put(taskInfo.taskId, animationContext);
     }
 
-    /**
-     * Called when matching task changed
-     */
-    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+    @Override
+    public void onTaskChanged(TaskInfo taskInfo) {
         AnimationContext animationContext = mAnimationContextByTaskId.get(taskInfo.taskId);
         if (animationContext != null) {
             animationContext.update(mTaskbarInsetsSource, taskInfo);
         }
     }
 
-    /**
-     * Called when matching task vanished
-     */
-    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
-        AnimationContext animationContext = mAnimationContextByTaskId.get(taskInfo.taskId);
-        if (animationContext != null) {
-            // PiP task has its own cleanup path, ignore surface reset to avoid conflict.
-            if (taskInfo.getWindowingMode() != WINDOWING_MODE_PINNED) {
-                resetSurface(animationContext);
-            }
-            mAnimationContextByTaskId.remove(taskInfo.taskId);
-        }
-
-        if (mAnimationContextByTaskId.size() == 0) {
-            mBackgroundController.removeBackground(mTransaction);
-        }
-
-        mTransaction.apply();
+    @Override
+    public void onTaskVanished(TaskInfo taskInfo) {
+        mAnimationContextByTaskId.remove(taskInfo.taskId);
     }
 
-    private void resetSurface(AnimationContext context) {
-        mTransaction
+    @Override
+    public void clearTasks() {
+        mAnimationContextByTaskId.clear();
+    }
+
+    @Override
+    public void resetSurface(TaskInfo taskInfo, Transaction transaction) {
+        final AnimationContext context = mAnimationContextByTaskId.get(taskInfo.taskId);
+        if (context != null) {
+            resetSurface(context, transaction);
+        }
+    }
+
+    @Override
+    public void applyAnimationProgress(float progress, Transaction transaction) {
+        if (mAnimationContextByTaskId.size() == 0) return;
+
+        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
+            final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
+
+            context.mCurrentCropRect.set(RECT_EVALUATOR
+                    .evaluate(progress, context.mStartCropRect, context.mEndCropRect));
+
+            float scale = lerp(START_SCALE, END_SCALE, progress);
+            context.mMatrix.setScale(scale, scale, context.mCurrentCropRect.exactCenterX(),
+                    context.mCurrentCropRect.exactCenterY());
+
+            transaction.setWindowCrop(context.mLeash, context.mCurrentCropRect)
+                    .setMatrix(context.mLeash, context.mMatrix, FLOAT_9)
+                    .setCornerRadius(context.mLeash, mWindowCornerRadiusPx)
+                    .show(context.mLeash);
+        }
+    }
+
+    @Override
+    public void prepareStartTransaction(Transaction transaction) {
+        mBackgroundController.ensureBackground(transaction);
+    }
+
+    @Override
+    public void prepareFinishTransaction(Transaction transaction) {
+        mBackgroundController.removeBackground(transaction);
+    }
+
+    @Override
+    public boolean isApplicableTask(TaskInfo taskInfo) {
+        return taskInfo != null && taskInfo.isVisible()
+                && taskInfo.realActivity != null // to filter out parents created by organizer
+                && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+                && taskInfo.getActivityType() != ACTIVITY_TYPE_HOME;
+    }
+
+    @Override
+    public void resetAllSurfaces(Transaction transaction) {
+        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
+            final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
+            resetSurface(context, transaction);
+        }
+    }
+
+    private void resetSurface(AnimationContext context, Transaction transaction) {
+        transaction
                 .setWindowCrop(context.mLeash, null)
                 .setCornerRadius(context.mLeash, 0.0F)
                 .setMatrix(context.mLeash, 1.0F, 0.0F, 0.0F, 1.0F)
@@ -197,10 +195,9 @@
 
         TaskInfo mTaskInfo;
 
-        private AnimationContext(SurfaceControl leash,
-                                InsetsSource taskBarInsetsSource,
-                                TaskInfo taskInfo) {
-            this.mLeash = leash;
+        private AnimationContext(SurfaceControl leash, InsetsSource taskBarInsetsSource,
+                TaskInfo taskInfo) {
+            mLeash = leash;
             update(taskBarInsetsSource, taskInfo);
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
new file mode 100644
index 0000000..6e10ebe
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.unfold.animation;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
+import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
+import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
+
+import android.animation.RectEvaluator;
+import android.animation.TypeEvaluator;
+import android.app.TaskInfo;
+import android.content.Context;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.util.SparseArray;
+import android.view.InsetsSource;
+import android.view.InsetsState;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
+
+import com.android.internal.policy.ScreenDecorationsUtils;
+import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
+import com.android.wm.shell.splitscreen.SplitScreen;
+import com.android.wm.shell.splitscreen.SplitScreen.SplitScreenListener;
+import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.unfold.UnfoldAnimationController;
+import com.android.wm.shell.unfold.UnfoldBackgroundController;
+
+import java.util.Optional;
+import java.util.concurrent.Executor;
+
+import dagger.Lazy;
+
+/**
+ * This helper class contains logic that calculates scaling and cropping parameters
+ * for the folding/unfolding animation. As an input it receives TaskInfo objects and
+ * surfaces leashes and as an output it could fill surface transactions with required
+ * transformations.
+ *
+ * This class is used by
+ * {@link com.android.wm.shell.unfold.UnfoldTransitionHandler} and
+ * {@link UnfoldAnimationController}.
+ * They use independent instances of SplitTaskUnfoldAnimator.
+ */
+public class SplitTaskUnfoldAnimator implements UnfoldTaskAnimator,
+        DisplayInsetsController.OnInsetsChangedListener, SplitScreenListener {
+
+    private static final TypeEvaluator<Rect> RECT_EVALUATOR = new RectEvaluator(new Rect());
+    private static final float CROPPING_START_MARGIN_FRACTION = 0.05f;
+
+    private final Executor mExecutor;
+    private final DisplayInsetsController mDisplayInsetsController;
+    private final SparseArray<AnimationContext> mAnimationContextByTaskId = new SparseArray<>();
+    private final int mExpandedTaskBarHeight;
+    private final float mWindowCornerRadiusPx;
+    private final Lazy<Optional<SplitScreenController>> mSplitScreenController;
+    private final UnfoldBackgroundController mUnfoldBackgroundController;
+
+    private final Rect mMainStageBounds = new Rect();
+    private final Rect mSideStageBounds = new Rect();
+    private final Rect mRootStageBounds = new Rect();
+
+    private InsetsSource mTaskbarInsetsSource;
+
+    @SplitPosition
+    private int mMainStagePosition = SPLIT_POSITION_UNDEFINED;
+    @SplitPosition
+    private int mSideStagePosition = SPLIT_POSITION_UNDEFINED;
+
+    public SplitTaskUnfoldAnimator(Context context, Executor executor,
+            Lazy<Optional<SplitScreenController>> splitScreenController,
+            UnfoldBackgroundController unfoldBackgroundController,
+            DisplayInsetsController displayInsetsController) {
+        mDisplayInsetsController = displayInsetsController;
+        mExecutor = executor;
+        mUnfoldBackgroundController = unfoldBackgroundController;
+        mSplitScreenController = splitScreenController;
+        mExpandedTaskBarHeight = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.taskbar_frame_height);
+        mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(context);
+    }
+
+    /** Initializes the animator, this should be called only once */
+    @Override
+    public void init() {
+        mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY, this);
+    }
+
+    /**
+     * Starts listening for split-screen changes and gets initial split-screen
+     * layout information through the listener
+     */
+    @Override
+    public void start() {
+        mSplitScreenController.get().get().asSplitScreen()
+                .registerSplitScreenListener(this, mExecutor);
+    }
+
+    /**
+     * Stops listening for the split-screen layout changes
+     */
+    @Override
+    public void stop() {
+        mSplitScreenController.get().get().asSplitScreen()
+                .unregisterSplitScreenListener(this);
+    }
+
+    @Override
+    public void insetsChanged(InsetsState insetsState) {
+        mTaskbarInsetsSource = insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
+        updateContexts();
+    }
+
+    @Override
+    public void onTaskStageChanged(int taskId, int stage, boolean visible) {
+        final AnimationContext context = mAnimationContextByTaskId.get(taskId);
+        if (context != null) {
+            context.mStageType = stage;
+            context.update();
+        }
+    }
+
+    @Override
+    public void onStagePositionChanged(int stage, int position) {
+        if (stage == STAGE_TYPE_MAIN) {
+            mMainStagePosition = position;
+        } else {
+            mSideStagePosition = position;
+        }
+        updateContexts();
+    }
+
+    @Override
+    public void onSplitBoundsChanged(Rect rootBounds, Rect mainBounds, Rect sideBounds) {
+        mRootStageBounds.set(rootBounds);
+        mMainStageBounds.set(mainBounds);
+        mSideStageBounds.set(sideBounds);
+        updateContexts();
+    }
+
+    private void updateContexts() {
+        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
+            AnimationContext context = mAnimationContextByTaskId.valueAt(i);
+            context.update();
+        }
+    }
+
+    /**
+     * Register a split task in the animator
+     * @param taskInfo info of the task
+     * @param leash the surface of the task
+     */
+    @Override
+    public void onTaskAppeared(TaskInfo taskInfo, SurfaceControl leash) {
+        AnimationContext context = new AnimationContext(leash);
+        mAnimationContextByTaskId.put(taskInfo.taskId, context);
+    }
+
+    /**
+     * Unregister the task from the unfold animation
+     * @param taskInfo info of the task
+     */
+    @Override
+    public void onTaskVanished(TaskInfo taskInfo) {
+        mAnimationContextByTaskId.remove(taskInfo.taskId);
+    }
+
+    @Override
+    public boolean isApplicableTask(TaskInfo taskInfo) {
+        return taskInfo.hasParentTask()
+                && taskInfo.isVisible
+                && taskInfo.realActivity != null // to filter out parents created by organizer
+                && taskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW;
+    }
+
+    /**
+     * Clear all registered tasks
+     */
+    @Override
+    public void clearTasks() {
+        mAnimationContextByTaskId.clear();
+    }
+
+    /**
+     * Reset transformations of the task that could have been applied by the animator
+     * @param taskInfo task to reset
+     * @param transaction a transaction to write the changes to
+     */
+    @Override
+    public void resetSurface(TaskInfo taskInfo, Transaction transaction) {
+        AnimationContext context = mAnimationContextByTaskId.get(taskInfo.taskId);
+        if (context != null) {
+            resetSurface(transaction, context);
+        }
+    }
+
+    /**
+     * Reset all surface transformation that could have been introduced by the animator
+     * @param transaction to write changes to
+     */
+    @Override
+    public void resetAllSurfaces(Transaction transaction) {
+        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
+            final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
+            resetSurface(transaction, context);
+        }
+    }
+
+    @Override
+    public void applyAnimationProgress(float progress, Transaction transaction) {
+        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
+            AnimationContext context = mAnimationContextByTaskId.valueAt(i);
+            if (context.mStageType == STAGE_TYPE_UNDEFINED) {
+                continue;
+            }
+
+            context.mCurrentCropRect.set(RECT_EVALUATOR
+                    .evaluate(progress, context.mStartCropRect, context.mEndCropRect));
+
+            transaction.setWindowCrop(context.mLeash, context.mCurrentCropRect)
+                    .setCornerRadius(context.mLeash, mWindowCornerRadiusPx);
+        }
+    }
+
+    @Override
+    public void prepareStartTransaction(Transaction transaction) {
+        mUnfoldBackgroundController.ensureBackground(transaction);
+        mSplitScreenController.get().get().updateSplitScreenSurfaces(transaction);
+    }
+
+    @Override
+    public void prepareFinishTransaction(Transaction transaction) {
+        mUnfoldBackgroundController.removeBackground(transaction);
+    }
+
+    /**
+     * @return true if there are tasks to animate
+     */
+    @Override
+    public boolean hasActiveTasks() {
+        return mAnimationContextByTaskId.size() > 0;
+    }
+
+    private void resetSurface(SurfaceControl.Transaction transaction, AnimationContext context) {
+        transaction
+                .setWindowCrop(context.mLeash, null)
+                .setCornerRadius(context.mLeash, 0.0F);
+    }
+
+    private class AnimationContext {
+        final SurfaceControl mLeash;
+
+        final Rect mStartCropRect = new Rect();
+        final Rect mEndCropRect = new Rect();
+        final Rect mCurrentCropRect = new Rect();
+
+        @SplitScreen.StageType
+        int mStageType = STAGE_TYPE_UNDEFINED;
+
+        private AnimationContext(SurfaceControl leash) {
+            mLeash = leash;
+            update();
+        }
+
+        private void update() {
+            final Rect stageBounds = mStageType == STAGE_TYPE_MAIN
+                    ? mMainStageBounds : mSideStageBounds;
+
+            mStartCropRect.set(stageBounds);
+
+            boolean taskbarExpanded = isTaskbarExpanded();
+            if (taskbarExpanded) {
+                // Only insets the cropping window with taskbar when taskbar is expanded
+                mStartCropRect.inset(mTaskbarInsetsSource.calculateVisibleInsets(mStartCropRect));
+            }
+
+            // Offset to surface coordinates as layout bounds are in screen coordinates
+            mStartCropRect.offsetTo(0, 0);
+
+            mEndCropRect.set(mStartCropRect);
+
+            int maxSize = Math.max(mEndCropRect.width(), mEndCropRect.height());
+            int margin = (int) (maxSize * CROPPING_START_MARGIN_FRACTION);
+
+            // Sides adjacent to split bar or task bar are not be animated.
+            Insets margins;
+            final boolean isLandscape = mRootStageBounds.width() > mRootStageBounds.height();
+            if (isLandscape) { // Left and right splits.
+                margins = getLandscapeMargins(margin, taskbarExpanded);
+            } else { // Top and bottom splits.
+                margins = getPortraitMargins(margin, taskbarExpanded);
+            }
+            mStartCropRect.inset(margins);
+        }
+
+        private Insets getLandscapeMargins(int margin, boolean taskbarExpanded) {
+            int left = margin;
+            int right = margin;
+            int bottom = taskbarExpanded ? 0 : margin; // Taskbar margin.
+            final int splitPosition = mStageType == STAGE_TYPE_MAIN
+                    ? mMainStagePosition : mSideStagePosition;
+            if (splitPosition == SPLIT_POSITION_TOP_OR_LEFT) {
+                right = 0; // Divider margin.
+            } else {
+                left = 0; // Divider margin.
+            }
+            return Insets.of(left, /* top= */ margin, right, bottom);
+        }
+
+        private Insets getPortraitMargins(int margin, boolean taskbarExpanded) {
+            int bottom = margin;
+            int top = margin;
+            final int splitPosition = mStageType == STAGE_TYPE_MAIN
+                    ? mMainStagePosition : mSideStagePosition;
+            if (splitPosition == SPLIT_POSITION_TOP_OR_LEFT) {
+                bottom = 0; // Divider margin.
+            } else { // Bottom split.
+                top = 0; // Divider margin.
+                if (taskbarExpanded) {
+                    bottom = 0; // Taskbar margin.
+                }
+            }
+            return Insets.of(/* left= */ margin, top, /* right= */ margin, bottom);
+        }
+
+        private boolean isTaskbarExpanded() {
+            return mTaskbarInsetsSource != null
+                    && mTaskbarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight;
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/UnfoldTaskAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/UnfoldTaskAnimator.java
new file mode 100644
index 0000000..e1e3663
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/UnfoldTaskAnimator.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.unfold.animation;
+
+import android.app.TaskInfo;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
+
+/**
+ * Interface for classes that handle animations of tasks when folding or unfolding
+ * foldable devices.
+ */
+public interface UnfoldTaskAnimator {
+    /**
+     * Initializes the animator, this should be called once in the lifetime of the animator
+     */
+    default void init() {}
+
+    /**
+     * Starts the animator, it might start listening for some events from the system.
+     * Applying animation should be done only when animator is started.
+     * Animator could be started/stopped several times.
+     */
+    default void start() {}
+
+    /**
+     * Stops the animator, it could unsubscribe from system events.
+     */
+    default void stop() {}
+
+    /**
+     * If this method returns true then task updates will be propagated to
+     * the animator using the onTaskAppeared/Changed/Vanished callbacks.
+     * @return true if this task should be animated by this animator
+     */
+    default boolean isApplicableTask(TaskInfo taskInfo) {
+        return false;
+    }
+
+    /**
+     * Called whenever a task applicable to this animator appeared
+     * (isApplicableTask returns true for this task)
+     *
+     * @param taskInfo info of the appeared task
+     * @param leash surface of the task
+     */
+    default void onTaskAppeared(TaskInfo taskInfo, SurfaceControl leash) {}
+
+    /**
+     * Called whenever a task applicable to this animator changed
+     * @param taskInfo info of the changed task
+     */
+    default void onTaskChanged(TaskInfo taskInfo) {}
+
+    /**
+     * Called whenever a task applicable to this animator vanished
+     * @param taskInfo info of the vanished task
+     */
+    default void onTaskVanished(TaskInfo taskInfo) {}
+
+    /**
+     * @return true if there tasks that could be potentially animated
+     */
+    default boolean hasActiveTasks() {
+        return false;
+    }
+
+    /**
+     * Clears all registered tasks in the animator
+     */
+    default void clearTasks() {}
+
+    /**
+     * Apply task surfaces transformations based on the current unfold progress
+     * @param progress unfold transition progress
+     * @param transaction to write changes to
+     */
+    default void applyAnimationProgress(float progress, Transaction transaction) {}
+
+    /**
+     * Apply task surfaces transformations that should be set before starting the animation
+     * @param transaction to write changes to
+     */
+    default void prepareStartTransaction(Transaction transaction) {}
+
+    /**
+     * Apply task surfaces transformations that should be set after finishing the animation
+     * @param transaction to write changes to
+     */
+    default void prepareFinishTransaction(Transaction transaction) {}
+
+    /**
+     * Resets task surface to its initial transformation
+     * @param transaction to write changes to
+     */
+    default void resetSurface(TaskInfo taskInfo, Transaction transaction) {}
+
+    /**
+     * Resets all task surfaces to their initial transformations
+     * @param transaction to write changes to
+     */
+    default void resetAllSurfaces(Transaction transaction) {}
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/qualifier/UnfoldShellTransition.java
similarity index 60%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerState.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/unfold/qualifier/UnfoldShellTransition.java
index af2ab15..4c868305 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/qualifier/UnfoldShellTransition.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,12 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.legacysplitscreen;
+package com.android.wm.shell.unfold.qualifier;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Qualifier;
 
 /**
- * Class to hold state of divider that needs to persist across configuration changes.
+ * Indicates that this class is used for the shell unfold transition
  */
-final class DividerState {
-    public boolean animateAfterRecentsDrawn;
-    public float mRatioPositionBeforeMinimized;
-}
+@Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UnfoldShellTransition {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/qualifier/UnfoldTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/qualifier/UnfoldTransition.java
new file mode 100644
index 0000000..4d2b3e6
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/qualifier/UnfoldTransition.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.unfold.qualifier;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.inject.Qualifier;
+
+/**
+ * Indicates that this class is used for unfold transition implemented
+ * without using Shell transitions
+ */
+@Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UnfoldTransition {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/GroupedRecentTaskInfo.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/GroupedRecentTaskInfo.java
index 603d05d..2cff171 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/GroupedRecentTaskInfo.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/GroupedRecentTaskInfo.java
@@ -30,7 +30,7 @@
 public class GroupedRecentTaskInfo implements Parcelable {
     public @NonNull ActivityManager.RecentTaskInfo mTaskInfo1;
     public @Nullable ActivityManager.RecentTaskInfo mTaskInfo2;
-    public @Nullable StagedSplitBounds mStagedSplitBounds;
+    public @Nullable SplitBounds mSplitBounds;
 
     public GroupedRecentTaskInfo(@NonNull ActivityManager.RecentTaskInfo task1) {
         this(task1, null, null);
@@ -38,24 +38,24 @@
 
     public GroupedRecentTaskInfo(@NonNull ActivityManager.RecentTaskInfo task1,
             @Nullable ActivityManager.RecentTaskInfo task2,
-            @Nullable StagedSplitBounds stagedSplitBounds) {
+            @Nullable SplitBounds splitBounds) {
         mTaskInfo1 = task1;
         mTaskInfo2 = task2;
-        mStagedSplitBounds = stagedSplitBounds;
+        mSplitBounds = splitBounds;
     }
 
     GroupedRecentTaskInfo(Parcel parcel) {
         mTaskInfo1 = parcel.readTypedObject(ActivityManager.RecentTaskInfo.CREATOR);
         mTaskInfo2 = parcel.readTypedObject(ActivityManager.RecentTaskInfo.CREATOR);
-        mStagedSplitBounds = parcel.readTypedObject(StagedSplitBounds.CREATOR);
+        mSplitBounds = parcel.readTypedObject(SplitBounds.CREATOR);
     }
 
     @Override
     public String toString() {
         String taskString = "Task1: " + getTaskInfo(mTaskInfo1)
                 + ", Task2: " + getTaskInfo(mTaskInfo2);
-        if (mStagedSplitBounds != null) {
-            taskString += ", SplitBounds: " + mStagedSplitBounds.toString();
+        if (mSplitBounds != null) {
+            taskString += ", SplitBounds: " + mSplitBounds.toString();
         }
         return taskString;
     }
@@ -76,7 +76,7 @@
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeTypedObject(mTaskInfo1, flags);
         parcel.writeTypedObject(mTaskInfo2, flags);
-        parcel.writeTypedObject(mStagedSplitBounds, flags);
+        parcel.writeTypedObject(mSplitBounds, flags);
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/StagedSplitBounds.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java
similarity index 88%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/util/StagedSplitBounds.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java
index a0c84cc..e903897 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/StagedSplitBounds.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/SplitBounds.java
@@ -25,7 +25,7 @@
  * Container of various information needed to display split screen
  * tasks/leashes/etc in Launcher
  */
-public class StagedSplitBounds implements Parcelable {
+public class SplitBounds implements Parcelable {
     public final Rect leftTopBounds;
     public final Rect rightBottomBounds;
     /** This rect represents the actual gap between the two apps */
@@ -43,7 +43,7 @@
     public final int leftTopTaskId;
     public final int rightBottomTaskId;
 
-    public StagedSplitBounds(Rect leftTopBounds, Rect rightBottomBounds,
+    public SplitBounds(Rect leftTopBounds, Rect rightBottomBounds,
             int leftTopTaskId, int rightBottomTaskId) {
         this.leftTopBounds = leftTopBounds;
         this.rightBottomBounds = rightBottomBounds;
@@ -66,7 +66,7 @@
         topTaskPercent = this.leftTopBounds.height() / (float) rightBottomBounds.bottom;
     }
 
-    public StagedSplitBounds(Parcel parcel) {
+    public SplitBounds(Parcel parcel) {
         leftTopBounds = parcel.readTypedObject(Rect.CREATOR);
         rightBottomBounds = parcel.readTypedObject(Rect.CREATOR);
         visualDividerBounds = parcel.readTypedObject(Rect.CREATOR);
@@ -96,11 +96,11 @@
 
     @Override
     public boolean equals(Object obj) {
-        if (!(obj instanceof StagedSplitBounds)) {
+        if (!(obj instanceof SplitBounds)) {
             return false;
         }
         // Only need to check the base fields (the other fields are derived from these)
-        final StagedSplitBounds other = (StagedSplitBounds) obj;
+        final SplitBounds other = (SplitBounds) obj;
         return Objects.equals(leftTopBounds, other.leftTopBounds)
                 && Objects.equals(rightBottomBounds, other.rightBottomBounds)
                 && leftTopTaskId == other.leftTopTaskId
@@ -120,15 +120,15 @@
                 + "AppsVertical? " + appsStackedVertically;
     }
 
-    public static final Creator<StagedSplitBounds> CREATOR = new Creator<StagedSplitBounds>() {
+    public static final Creator<SplitBounds> CREATOR = new Creator<SplitBounds>() {
         @Override
-        public StagedSplitBounds createFromParcel(Parcel in) {
-            return new StagedSplitBounds(in);
+        public SplitBounds createFromParcel(Parcel in) {
+            return new SplitBounds(in);
         }
 
         @Override
-        public StagedSplitBounds[] newArray(int size) {
-            return new StagedSplitBounds[size];
+        public SplitBounds[] newArray(int size) {
+            return new SplitBounds[size];
         }
     };
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
new file mode 100644
index 0000000..6d28d73
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityTaskManager;
+import android.content.Context;
+import android.os.Handler;
+import android.view.MotionEvent;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+/**
+ * View model for the window decoration with a caption and shadows. Works with
+ * {@link CaptionWindowDecoration}.
+ */
+public class CaptionWindowDecorViewModel implements WindowDecorViewModel<CaptionWindowDecoration> {
+    private final ActivityTaskManager mActivityTaskManager;
+    private final ShellTaskOrganizer mTaskOrganizer;
+    private final Context mContext;
+    private final Handler mMainHandler;
+    private final DisplayController mDisplayController;
+    private final SyncTransactionQueue mSyncQueue;
+
+    public CaptionWindowDecorViewModel(
+            Context context,
+            Handler mainHandler,
+            ShellTaskOrganizer taskOrganizer,
+            DisplayController displayController,
+            SyncTransactionQueue syncQueue) {
+        mContext = context;
+        mMainHandler = mainHandler;
+        mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class);
+        mTaskOrganizer = taskOrganizer;
+        mDisplayController = displayController;
+        mSyncQueue = syncQueue;
+    }
+
+    @Override
+    public CaptionWindowDecoration createWindowDecoration(
+            ActivityManager.RunningTaskInfo taskInfo, SurfaceControl taskSurface) {
+        final CaptionWindowDecoration windowDecoration = new CaptionWindowDecoration(
+                mContext,
+                mDisplayController,
+                mTaskOrganizer,
+                taskInfo,
+                taskSurface,
+                mMainHandler,
+                mSyncQueue);
+        TaskPositioner taskPositioner = new TaskPositioner(mTaskOrganizer, windowDecoration);
+        CaptionTouchEventListener touchEventListener =
+                new CaptionTouchEventListener(taskInfo, taskPositioner);
+        windowDecoration.setCaptionListeners(touchEventListener, touchEventListener);
+        windowDecoration.setDragResizeCallback(taskPositioner);
+        onTaskInfoChanged(taskInfo, windowDecoration);
+        return windowDecoration;
+    }
+
+    @Override
+    public void onTaskInfoChanged(RunningTaskInfo taskInfo, CaptionWindowDecoration decoration) {
+        decoration.relayout(taskInfo);
+
+        int statusBarColor = taskInfo.taskDescription.getStatusBarColor();
+        decoration.setCaptionColor(statusBarColor);
+    }
+
+    private class CaptionTouchEventListener implements
+            View.OnClickListener, View.OnTouchListener {
+
+        private final int mTaskId;
+        private final WindowContainerToken mTaskToken;
+        private final DragResizeCallback mDragResizeCallback;
+
+        private int mDragPointerId = -1;
+
+        private CaptionTouchEventListener(
+                RunningTaskInfo taskInfo, DragResizeCallback dragResizeCallback) {
+            mTaskId = taskInfo.taskId;
+            mTaskToken = taskInfo.token;
+            mDragResizeCallback = dragResizeCallback;
+        }
+
+        @Override
+        public void onClick(View v) {
+            int id = v.getId();
+            if (id == R.id.close_window) {
+                mActivityTaskManager.removeTask(mTaskId);
+            } else if (id == R.id.maximize_window) {
+                WindowContainerTransaction wct = new WindowContainerTransaction();
+                RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
+                int targetWindowingMode = taskInfo.getWindowingMode() != WINDOWING_MODE_FULLSCREEN
+                        ? WINDOWING_MODE_FULLSCREEN : WINDOWING_MODE_FREEFORM;
+                int displayWindowingMode =
+                        taskInfo.configuration.windowConfiguration.getDisplayWindowingMode();
+                wct.setWindowingMode(mTaskToken,
+                        targetWindowingMode == displayWindowingMode
+                            ? WINDOWING_MODE_UNDEFINED : targetWindowingMode);
+                if (targetWindowingMode == WINDOWING_MODE_FULLSCREEN) {
+                    wct.setBounds(mTaskToken, null);
+                }
+                mSyncQueue.queue(wct);
+            }
+        }
+
+        @Override
+        public boolean onTouch(View v, MotionEvent e) {
+            if (v.getId() != R.id.caption) {
+                return false;
+            }
+            handleEventForMove(e);
+
+            if (e.getAction() != MotionEvent.ACTION_DOWN) {
+                return false;
+            }
+            RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
+            if (taskInfo.isFocused) {
+                return false;
+            }
+            WindowContainerTransaction wct = new WindowContainerTransaction();
+            wct.reorder(mTaskToken, true /* onTop */);
+            mSyncQueue.queue(wct);
+            return true;
+        }
+
+        private void handleEventForMove(MotionEvent e) {
+            switch (e.getActionMasked()) {
+                case MotionEvent.ACTION_DOWN:
+                    mDragPointerId  = e.getPointerId(0);
+                    mDragResizeCallback.onDragResizeStart(
+                            0 /* ctrlType */, e.getRawX(0), e.getRawY(0));
+                    break;
+                case MotionEvent.ACTION_MOVE: {
+                    int dragPointerIdx = e.findPointerIndex(mDragPointerId);
+                    mDragResizeCallback.onDragResizeMove(
+                            e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
+                    break;
+                }
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_CANCEL: {
+                    int dragPointerIdx = e.findPointerIndex(mDragPointerId);
+                    mDragResizeCallback.onDragResizeEnd(
+                            e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
new file mode 100644
index 0000000..572516d
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import android.app.ActivityManager;
+import android.app.WindowConfiguration;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.VectorDrawable;
+import android.os.Handler;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.SyncTransactionQueue;
+
+/**
+ * Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
+ * {@link CaptionWindowDecorViewModel}. The caption bar contains maximize and close buttons.
+ *
+ * {@link CaptionWindowDecorViewModel} can change the color of the caption bar based on the foremost
+ * app's request through {@link #setCaptionColor(int)}, in which it changes the foreground color of
+ * caption buttons according to the luminance of the background.
+ *
+ * The shadow's thickness is 20dp when the window is in focus and 5dp when the window isn't.
+ */
+public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
+    // The thickness of shadows of a window that has focus in DIP.
+    private static final int DECOR_SHADOW_FOCUSED_THICKNESS_IN_DIP = 20;
+    // The thickness of shadows of a window that doesn't have focus in DIP.
+    private static final int DECOR_SHADOW_UNFOCUSED_THICKNESS_IN_DIP = 5;
+
+    // Height of button (32dp)  + 2 * margin (5dp each)
+    private static final int DECOR_CAPTION_HEIGHT_IN_DIP = 42;
+    private static final int RESIZE_HANDLE_IN_DIP = 30;
+
+    private static final Rect EMPTY_OUTSET = new Rect();
+    private static final Rect RESIZE_HANDLE_OUTSET = new Rect(
+            RESIZE_HANDLE_IN_DIP, RESIZE_HANDLE_IN_DIP, RESIZE_HANDLE_IN_DIP, RESIZE_HANDLE_IN_DIP);
+
+    private final Handler mHandler;
+    private final SyncTransactionQueue mSyncQueue;
+
+    private View.OnClickListener mOnCaptionButtonClickListener;
+    private View.OnTouchListener mOnCaptionTouchListener;
+    private DragResizeCallback mDragResizeCallback;
+
+    private DragResizeInputListener mDragResizeListener;
+
+    private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult =
+            new WindowDecoration.RelayoutResult<>();
+
+    CaptionWindowDecoration(
+            Context context,
+            DisplayController displayController,
+            ShellTaskOrganizer taskOrganizer,
+            ActivityManager.RunningTaskInfo taskInfo,
+            SurfaceControl taskSurface,
+            Handler handler,
+            SyncTransactionQueue syncQueue) {
+        super(context, displayController, taskOrganizer, taskInfo, taskSurface);
+
+        mHandler = handler;
+        mSyncQueue = syncQueue;
+    }
+
+    void setCaptionListeners(
+            View.OnClickListener onCaptionButtonClickListener,
+            View.OnTouchListener onCaptionTouchListener) {
+        mOnCaptionButtonClickListener = onCaptionButtonClickListener;
+        mOnCaptionTouchListener = onCaptionTouchListener;
+    }
+
+    void setDragResizeCallback(DragResizeCallback dragResizeCallback) {
+        mDragResizeCallback = dragResizeCallback;
+    }
+
+    void relayout(ActivityManager.RunningTaskInfo taskInfo) {
+        final int shadowRadiusDp = taskInfo.isFocused
+                ? DECOR_SHADOW_FOCUSED_THICKNESS_IN_DIP : DECOR_SHADOW_UNFOCUSED_THICKNESS_IN_DIP;
+        final boolean isFreeform = mTaskInfo.configuration.windowConfiguration.getWindowingMode()
+                == WindowConfiguration.WINDOWING_MODE_FREEFORM;
+        final boolean isDragResizeable = isFreeform && mTaskInfo.isResizeable;
+        final Rect outset = isDragResizeable ? RESIZE_HANDLE_OUTSET : EMPTY_OUTSET;
+
+        WindowDecorLinearLayout oldRootView = mResult.mRootView;
+        final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
+        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        relayout(taskInfo, R.layout.caption_window_decoration, oldRootView,
+                DECOR_CAPTION_HEIGHT_IN_DIP, outset, shadowRadiusDp, t, wct, mResult);
+        taskInfo = null; // Clear it just in case we use it accidentally
+
+        mSyncQueue.runInSync(transaction -> {
+            transaction.merge(t);
+            t.close();
+
+            mTaskOrganizer.applyTransaction(wct);
+        });
+
+        if (mResult.mRootView == null) {
+            // This means the task is hidden. Nothing is set up in this case including the
+            // decoration surface.
+            return;
+        }
+        if (oldRootView != mResult.mRootView) {
+            setupRootView();
+        }
+
+        if (!isDragResizeable) {
+            closeDragResizeListener();
+            return;
+        }
+
+        if (oldDecorationSurface != mDecorationContainerSurface) {
+            closeDragResizeListener();
+            mDragResizeListener = new DragResizeInputListener(
+                    mContext,
+                    mHandler,
+                    mDisplay.getDisplayId(),
+                    mDecorationContainerSurface,
+                    mDragResizeCallback);
+        }
+
+        mDragResizeListener.setGeometry(
+                mResult.mWidth, mResult.mHeight, (int) (mResult.mDensity * RESIZE_HANDLE_IN_DIP));
+    }
+
+    /**
+     * Sets up listeners when a new root view is created.
+     */
+    private void setupRootView() {
+        View caption = mResult.mRootView.findViewById(R.id.caption);
+
+        caption.setOnTouchListener(mOnCaptionTouchListener);
+        View maximize = caption.findViewById(R.id.maximize_window);
+        maximize.setOnClickListener(mOnCaptionButtonClickListener);
+        View close = caption.findViewById(R.id.close_window);
+        close.setOnClickListener(mOnCaptionButtonClickListener);
+    }
+
+    void setCaptionColor(int captionColor) {
+        if (mResult.mRootView == null) {
+            return;
+        }
+
+        View caption = mResult.mRootView.findViewById(R.id.caption);
+        GradientDrawable captionDrawable = (GradientDrawable) caption.getBackground();
+        captionDrawable.setColor(captionColor);
+
+        int buttonTintColorRes =
+                Color.valueOf(captionColor).luminance() < 0.5
+                        ? R.color.decor_button_light_color
+                        : R.color.decor_button_dark_color;
+        ColorStateList buttonTintColor =
+                caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
+        View maximize = caption.findViewById(R.id.maximize_window);
+        VectorDrawable maximizeBackground = (VectorDrawable) maximize.getBackground();
+        maximizeBackground.setTintList(buttonTintColor);
+
+        View close = caption.findViewById(R.id.close_window);
+        VectorDrawable closeBackground = (VectorDrawable) close.getBackground();
+        closeBackground.setTintList(buttonTintColor);
+    }
+
+    private void closeDragResizeListener() {
+        if (mDragResizeListener == null) {
+            return;
+        }
+        mDragResizeListener.close();
+        mDragResizeListener = null;
+    }
+
+    @Override
+    public void close() {
+        closeDragResizeListener();
+        super.close();
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeCallback.java
new file mode 100644
index 0000000..ee160a1
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeCallback.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+/**
+ * Callback called when receiving drag-resize or drag-move related input events.
+ */
+public interface DragResizeCallback {
+    /**
+     * Called when a drag resize starts.
+     *
+     * @param ctrlType {@link TaskPositioner.CtrlType} indicating the direction of resizing, use
+     *                 {@code 0} to indicate it's a move
+     * @param x x coordinate in window decoration coordinate system where the drag resize starts
+     * @param y y coordinate in window decoration coordinate system where the drag resize starts
+     */
+    void onDragResizeStart(@TaskPositioner.CtrlType int ctrlType, float x, float y);
+
+    /**
+     * Called when the pointer moves during a drag resize.
+     * @param x x coordinate in window decoration coordinate system of the new pointer location
+     * @param y y coordinate in window decoration coordinate system of the new pointer location
+     */
+    void onDragResizeMove(float x, float y);
+
+    /**
+     * Called when a drag resize stops.
+     * @param x x coordinate in window decoration coordinate system where the drag resize stops
+     * @param y y coordinate in window decoration coordinate system where the drag resize stops
+     */
+    void onDragResizeEnd(float x, float y);
+}
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
new file mode 100644
index 0000000..c6bbb02
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.hardware.input.InputManager;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.view.IWindowSession;
+import android.view.InputChannel;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
+import android.view.MotionEvent;
+import android.view.PointerIcon;
+import android.view.SurfaceControl;
+import android.view.WindowManagerGlobal;
+
+import com.android.internal.view.BaseIWindow;
+
+/**
+ * An input event listener registered to InputDispatcher to receive input events on task edges and
+ * convert them to drag resize requests.
+ */
+class DragResizeInputListener implements AutoCloseable {
+    private static final String TAG = "DragResizeInputListener";
+
+    private final IWindowSession mWindowSession = WindowManagerGlobal.getWindowSession();
+    private final Handler mHandler;
+    private final InputManager mInputManager;
+
+    private final int mDisplayId;
+    private final BaseIWindow mFakeWindow;
+    private final IBinder mFocusGrantToken;
+    private final SurfaceControl mDecorationSurface;
+    private final InputChannel mInputChannel;
+    private final TaskResizeInputEventReceiver mInputEventReceiver;
+    private final com.android.wm.shell.windowdecor.DragResizeCallback mCallback;
+
+    private int mWidth;
+    private int mHeight;
+    private int mResizeHandleThickness;
+
+    private int mDragPointerId = -1;
+
+    DragResizeInputListener(
+            Context context,
+            Handler handler,
+            int displayId,
+            SurfaceControl decorationSurface,
+            DragResizeCallback callback) {
+        mInputManager = context.getSystemService(InputManager.class);
+        mHandler = handler;
+        mDisplayId = displayId;
+        mDecorationSurface = decorationSurface;
+        // 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);
+        mFocusGrantToken = new Binder();
+        mInputChannel = new InputChannel();
+        try {
+            mWindowSession.grantInputChannel(
+                    mDisplayId,
+                    new SurfaceControl(mDecorationSurface, TAG),
+                    mFakeWindow,
+                    null /* hostInputToken */,
+                    FLAG_NOT_FOCUSABLE,
+                    PRIVATE_FLAG_TRUSTED_OVERLAY,
+                    TYPE_APPLICATION,
+                    mFocusGrantToken,
+                    TAG + " of " + decorationSurface.toString(),
+                    mInputChannel);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        mInputEventReceiver = new TaskResizeInputEventReceiver(mInputChannel, mHandler.getLooper());
+        mCallback = callback;
+    }
+
+    /**
+     * Updates geometry of this drag resize handler. Needs to be called every time there is a size
+     * change to notify the input event receiver it's ready to take the next input event. Otherwise
+     * it'll keep batching move events and the drag resize process is stalled.
+     *
+     * This is also used to update the touch regions of this handler every event dispatched here is
+     * a potential resize request.
+     *
+     * @param width The width of the drag resize handler in pixels, including resize handle
+     *              thickness. That is task width + 2 * resize handle thickness.
+     * @param height The height of the drag resize handler in pixels, including resize handle
+     *               thickness. That is task height + 2 * resize handle thickness.
+     * @param resizeHandleThickness The thickness of the resize handle in pixels.
+     */
+    void setGeometry(int width, int height, int resizeHandleThickness) {
+        if (mWidth == width && mHeight == height
+                && mResizeHandleThickness == resizeHandleThickness) {
+            return;
+        }
+
+        mWidth = width;
+        mHeight = height;
+        mResizeHandleThickness = resizeHandleThickness;
+
+        Region touchRegion = new Region();
+        final Rect topInputBounds = new Rect(0, 0, mWidth, mResizeHandleThickness);
+        touchRegion.union(topInputBounds);
+
+        final Rect leftInputBounds = new Rect(0, mResizeHandleThickness,
+                mResizeHandleThickness, mHeight - mResizeHandleThickness);
+        touchRegion.union(leftInputBounds);
+
+        final Rect rightInputBounds = new Rect(
+                mWidth - mResizeHandleThickness, mResizeHandleThickness,
+                mWidth, mHeight - mResizeHandleThickness);
+        touchRegion.union(rightInputBounds);
+
+        final Rect bottomInputBounds = new Rect(0, mHeight - mResizeHandleThickness,
+                mWidth, mHeight);
+        touchRegion.union(bottomInputBounds);
+
+        try {
+            mWindowSession.updateInputChannel(
+                    mInputChannel.getToken(),
+                    mDisplayId,
+                    new SurfaceControl(
+                            mDecorationSurface, "DragResizeInputListener#setTouchRegion"),
+                    FLAG_NOT_FOCUSABLE,
+                    PRIVATE_FLAG_TRUSTED_OVERLAY,
+                    touchRegion);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        // This marks all relevant components have handled the previous resize event and can take
+        // the next one now.
+        mInputEventReceiver.onHandledLastResizeEvent();
+    }
+
+    @Override
+    public void close() {
+        mInputChannel.dispose();
+        try {
+            mWindowSession.remove(mFakeWindow);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    private class TaskResizeInputEventReceiver extends InputEventReceiver {
+        private boolean mWaitingForLastResizeEventHandled;
+
+        private TaskResizeInputEventReceiver(InputChannel inputChannel, Looper looper) {
+            super(inputChannel, looper);
+        }
+
+        private void onHandledLastResizeEvent() {
+            mWaitingForLastResizeEventHandled = false;
+            consumeBatchedInputEvents(-1);
+        }
+
+        @Override
+        public void onBatchedInputEventPending(int source) {
+            // InputEventReceiver keeps continuous move events in a batched event until explicitly
+            // consuming it or an incompatible event shows up (likely an up event in this case). We
+            // continue to keep move events in the next batched event until we receive a geometry
+            // update so that we don't put too much pressure on the framework with excessive number
+            // of input events if it can't handle them fast enough. It's more responsive to always
+            // resize the task to the latest received coordinates.
+            if (!mWaitingForLastResizeEventHandled) {
+                consumeBatchedInputEvents(-1);
+            }
+        }
+
+        @Override
+        public void onInputEvent(InputEvent inputEvent) {
+            finishInputEvent(inputEvent, handleInputEvent(inputEvent));
+        }
+
+        private boolean handleInputEvent(InputEvent inputEvent) {
+            if (!(inputEvent instanceof MotionEvent)) {
+                return false;
+            }
+
+            MotionEvent e = (MotionEvent) inputEvent;
+            switch (e.getActionMasked()) {
+                case MotionEvent.ACTION_DOWN: {
+                    mDragPointerId = e.getPointerId(0);
+                    mCallback.onDragResizeStart(
+                            calculateCtrlType(e.getX(0), e.getY(0)), e.getRawX(0), e.getRawY(0));
+                    mWaitingForLastResizeEventHandled = false;
+                    break;
+                }
+                case MotionEvent.ACTION_MOVE: {
+                    int dragPointerIndex = e.findPointerIndex(mDragPointerId);
+                    mCallback.onDragResizeMove(
+                            e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex));
+                    mWaitingForLastResizeEventHandled = true;
+                    break;
+                }
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_CANCEL: {
+                    int dragPointerIndex = e.findPointerIndex(mDragPointerId);
+                    mCallback.onDragResizeEnd(
+                            e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex));
+                    mWaitingForLastResizeEventHandled = false;
+                    mDragPointerId = -1;
+                    break;
+                }
+                case MotionEvent.ACTION_HOVER_ENTER:
+                case MotionEvent.ACTION_HOVER_MOVE: {
+                    updateCursorType(e.getXCursorPosition(), e.getYCursorPosition());
+                    break;
+                }
+                case MotionEvent.ACTION_HOVER_EXIT:
+                    mInputManager.setPointerIconType(PointerIcon.TYPE_DEFAULT);
+                    break;
+            }
+            return true;
+        }
+
+        @TaskPositioner.CtrlType
+        private int calculateCtrlType(float x, float y) {
+            int ctrlType = 0;
+            if (x < mResizeHandleThickness) {
+                ctrlType |= TaskPositioner.CTRL_TYPE_LEFT;
+            }
+            if (x > mWidth - mResizeHandleThickness) {
+                ctrlType |= TaskPositioner.CTRL_TYPE_RIGHT;
+            }
+            if (y < mResizeHandleThickness) {
+                ctrlType |= TaskPositioner.CTRL_TYPE_TOP;
+            }
+            if (y > mHeight - mResizeHandleThickness) {
+                ctrlType |= TaskPositioner.CTRL_TYPE_BOTTOM;
+            }
+            return ctrlType;
+        }
+
+        private void updateCursorType(float x, float y) {
+            @TaskPositioner.CtrlType int ctrlType = calculateCtrlType(x, y);
+
+            int cursorType = PointerIcon.TYPE_DEFAULT;
+            switch (ctrlType) {
+                case TaskPositioner.CTRL_TYPE_LEFT:
+                case TaskPositioner.CTRL_TYPE_RIGHT:
+                    cursorType = PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
+                    break;
+                case TaskPositioner.CTRL_TYPE_TOP:
+                case TaskPositioner.CTRL_TYPE_BOTTOM:
+                    cursorType = PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
+                    break;
+                case TaskPositioner.CTRL_TYPE_LEFT | TaskPositioner.CTRL_TYPE_TOP:
+                case TaskPositioner.CTRL_TYPE_RIGHT | TaskPositioner.CTRL_TYPE_BOTTOM:
+                    cursorType = PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW;
+                    break;
+                case TaskPositioner.CTRL_TYPE_LEFT | TaskPositioner.CTRL_TYPE_BOTTOM:
+                case TaskPositioner.CTRL_TYPE_RIGHT | TaskPositioner.CTRL_TYPE_TOP:
+                    cursorType = PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW;
+                    break;
+            }
+            mInputManager.setPointerIconType(cursorType);
+        }
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskFocusStateConsumer.java
similarity index 73%
copy from packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
copy to libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskFocusStateConsumer.java
index 5b187b3..1c61802b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskFocusStateConsumer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,9 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.unfold.config
 
-interface UnfoldTransitionConfig {
-    val isEnabled: Boolean
-    val isHingeAngleEnabled: Boolean
+package com.android.wm.shell.windowdecor;
+
+interface TaskFocusStateConsumer {
+    void setTaskFocusState(boolean focused);
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
new file mode 100644
index 0000000..280569b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskPositioner.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import android.annotation.IntDef;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+
+class TaskPositioner implements DragResizeCallback {
+
+    @IntDef({CTRL_TYPE_LEFT, CTRL_TYPE_RIGHT, CTRL_TYPE_TOP, CTRL_TYPE_BOTTOM})
+    @interface CtrlType {}
+
+    static final int CTRL_TYPE_LEFT = 1;
+    static final int CTRL_TYPE_RIGHT = 2;
+    static final int CTRL_TYPE_TOP = 4;
+    static final int CTRL_TYPE_BOTTOM = 8;
+
+    private final ShellTaskOrganizer mTaskOrganizer;
+    private final WindowDecoration mWindowDecoration;
+
+    private final Rect mTaskBoundsAtDragStart = new Rect();
+    private final PointF mResizeStartPoint = new PointF();
+    private final Rect mResizeTaskBounds = new Rect();
+
+    private int mCtrlType;
+
+    TaskPositioner(ShellTaskOrganizer taskOrganizer, WindowDecoration windowDecoration) {
+        mTaskOrganizer = taskOrganizer;
+        mWindowDecoration = windowDecoration;
+    }
+
+    @Override
+    public void onDragResizeStart(int ctrlType, float x, float y) {
+        mCtrlType = ctrlType;
+
+        mTaskBoundsAtDragStart.set(
+                mWindowDecoration.mTaskInfo.configuration.windowConfiguration.getBounds());
+        mResizeStartPoint.set(x, y);
+    }
+
+    @Override
+    public void onDragResizeMove(float x, float y) {
+        changeBounds(x, y);
+    }
+
+    @Override
+    public void onDragResizeEnd(float x, float y) {
+        changeBounds(x, y);
+
+        mCtrlType = 0;
+        mTaskBoundsAtDragStart.setEmpty();
+        mResizeStartPoint.set(0, 0);
+    }
+
+    private void changeBounds(float x, float y) {
+        float deltaX = x - mResizeStartPoint.x;
+        mResizeTaskBounds.set(mTaskBoundsAtDragStart);
+        if ((mCtrlType & CTRL_TYPE_LEFT) != 0) {
+            mResizeTaskBounds.left += deltaX;
+        }
+        if ((mCtrlType & CTRL_TYPE_RIGHT) != 0) {
+            mResizeTaskBounds.right += deltaX;
+        }
+        float deltaY = y - mResizeStartPoint.y;
+        if ((mCtrlType & CTRL_TYPE_TOP) != 0) {
+            mResizeTaskBounds.top += deltaY;
+        }
+        if ((mCtrlType & CTRL_TYPE_BOTTOM) != 0) {
+            mResizeTaskBounds.bottom += deltaY;
+        }
+        if (mCtrlType == 0) {
+            mResizeTaskBounds.offset((int) deltaX, (int) deltaY);
+        }
+
+        if (!mResizeTaskBounds.isEmpty()) {
+            final WindowContainerTransaction wct = new WindowContainerTransaction();
+            wct.setBounds(mWindowDecoration.mTaskInfo.token, mResizeTaskBounds);
+            mTaskOrganizer.applyTransaction(wct);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorLinearLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorLinearLayout.java
new file mode 100644
index 0000000..6d8001a
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorLinearLayout.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+import androidx.annotation.Nullable;
+
+import com.android.wm.shell.R;
+
+/**
+ * A {@link LinearLayout} that takes an additional task focused drawable state. The new state is
+ * used to select the correct background color for views in the window decoration.
+ */
+public class WindowDecorLinearLayout extends LinearLayout implements TaskFocusStateConsumer {
+    private static final int[] TASK_FOCUSED_STATE = { R.attr.state_task_focused };
+
+    private boolean mIsTaskFocused;
+
+    public WindowDecorLinearLayout(Context context) {
+        super(context);
+    }
+
+    public WindowDecorLinearLayout(Context context,
+            @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public WindowDecorLinearLayout(Context context, @Nullable AttributeSet attrs,
+            int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public WindowDecorLinearLayout(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public void setTaskFocusState(boolean focused) {
+        mIsTaskFocused = focused;
+
+        refreshDrawableState();
+    }
+
+    @Override
+    protected int[] onCreateDrawableState(int extraSpace) {
+        if (!mIsTaskFocused) {
+            return super.onCreateDrawableState(extraSpace);
+        }
+
+        final int[] states = super.onCreateDrawableState(extraSpace + 1);
+        mergeDrawableStates(states, TASK_FOCUSED_STATE);
+        return states;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
new file mode 100644
index 0000000..6f9ceff
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import android.app.ActivityManager;
+import android.view.SurfaceControl;
+
+/**
+ * The interface used by some {@link com.android.wm.shell.ShellTaskOrganizer.TaskListener} to help
+ * customize {@link WindowDecoration}. Its implementations are responsible to interpret user's
+ * interactions with UI widgets in window decorations and send corresponding requests to system
+ * servers.
+ *
+ * @param <T> The actual decoration type
+ */
+public interface WindowDecorViewModel<T extends AutoCloseable> {
+
+    /**
+     * Creates a window decoration for the given task.
+     *
+     * @param taskInfo the initial task info of the task
+     * @param taskSurface the surface of the task
+     * @return the window decoration object
+     */
+    T createWindowDecoration(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl taskSurface);
+
+    /**
+     * Notifies a task info update on the given task, with the window decoration created previously
+     * for this task by {@link #createWindowDecoration}.
+     *
+     * @param taskInfo the new task info of the task
+     * @param windowDecoration the window decoration created for the task
+     */
+    void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo, T windowDecoration);
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
new file mode 100644
index 0000000..0c502283
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.InsetsState;
+import android.view.LayoutInflater;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+import android.view.ViewRootImpl;
+import android.view.WindowManager;
+import android.view.WindowlessWindowManager;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+
+/**
+ * Manages a container surface and a windowless window to show window decoration. Responsible to
+ * update window decoration window state and layout parameters on task info changes and so that
+ * window decoration is in correct state and bounds.
+ *
+ * The container surface is a child of the task display area in the same display, so that window
+ * decorations can be drawn out of the task bounds and receive input events from out of the task
+ * bounds to support drag resizing.
+ *
+ * The windowless window that hosts window decoration is positioned in front of all activities, to
+ * allow the foreground activity to draw its own background behind window decorations, such as
+ * the window captions.
+ *
+ * @param <T> The type of the root view
+ */
+public class WindowDecoration<T extends View & TaskFocusStateConsumer> implements AutoCloseable {
+    private static final int[] CAPTION_INSETS_TYPES = { InsetsState.ITYPE_CAPTION_BAR };
+
+    /**
+     * System-wide context. Only used to create context with overridden configurations.
+     */
+    final Context mContext;
+    final DisplayController mDisplayController;
+    final ShellTaskOrganizer mTaskOrganizer;
+
+    RunningTaskInfo mTaskInfo;
+    final SurfaceControl mTaskSurface;
+
+    Display mDisplay;
+    Context mDecorWindowContext;
+    SurfaceControl mDecorationContainerSurface;
+    SurfaceControl mTaskBackgroundSurface;
+
+    private CaptionWindowManager mCaptionWindowManager;
+    private SurfaceControlViewHost mViewHost;
+
+    private final Rect mCaptionInsetsRect = new Rect();
+    private final Rect mTaskSurfaceCrop = new Rect();
+    private final float[] mTmpColor = new float[3];
+
+    WindowDecoration(
+            Context context,
+            DisplayController displayController,
+            ShellTaskOrganizer taskOrganizer,
+            RunningTaskInfo taskInfo,
+            SurfaceControl taskSurface) {
+        mContext = context;
+        mDisplayController = displayController;
+        mTaskOrganizer = taskOrganizer;
+        mTaskInfo = taskInfo;
+        mTaskSurface = taskSurface;
+
+        mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId);
+        mDecorWindowContext = mContext.createConfigurationContext(mTaskInfo.getConfiguration());
+
+        // Put caption under task surface because ViewRootImpl sets the destination frame of
+        // windowless window layers and BLASTBufferQueue#update() doesn't support offset.
+        mCaptionWindowManager =
+                new CaptionWindowManager(mTaskInfo.getConfiguration(), mTaskSurface);
+    }
+
+    void relayout(RunningTaskInfo taskInfo, int layoutResId, T rootView, float captionHeightDp,
+            Rect outsetsDp, float shadowRadiusDp, SurfaceControl.Transaction t,
+            WindowContainerTransaction wct, RelayoutResult<T> outResult) {
+        outResult.reset();
+
+        final Configuration oldTaskConfig = mTaskInfo.getConfiguration();
+        if (taskInfo != null) {
+            mTaskInfo = taskInfo;
+        }
+
+        if (!mTaskInfo.isVisible) {
+            close();
+            t.hide(mTaskSurface);
+            return;
+        }
+
+        if (rootView == null && layoutResId == 0) {
+            throw new IllegalArgumentException("layoutResId and rootView can't both be invalid.");
+        }
+
+        outResult.mRootView = rootView;
+        rootView = null; // Clear it just in case we use it accidentally
+        final Configuration taskConfig = mTaskInfo.getConfiguration();
+        if (oldTaskConfig.densityDpi != taskConfig.densityDpi
+                || mDisplay.getDisplayId() != mTaskInfo.displayId) {
+            close();
+
+            mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId);
+            mDecorWindowContext = mContext.createConfigurationContext(taskConfig);
+            if (layoutResId != 0) {
+                outResult.mRootView =
+                        (T) LayoutInflater.from(mDecorWindowContext).inflate(layoutResId, null);
+            }
+        }
+
+        if (outResult.mRootView == null) {
+            outResult.mRootView =
+                    (T) LayoutInflater.from(mDecorWindowContext).inflate(layoutResId, null);
+        }
+
+        // DecorationContainerSurface
+        if (mDecorationContainerSurface == null) {
+            final SurfaceControl.Builder builder = new SurfaceControl.Builder();
+            mDecorationContainerSurface = builder
+                    .setName("Decor container of Task=" + mTaskInfo.taskId)
+                    .setContainerLayer()
+                    .setParent(mTaskSurface)
+                    .build();
+
+            t.setTrustedOverlay(mDecorationContainerSurface, true);
+        }
+
+        final Rect taskBounds = taskConfig.windowConfiguration.getBounds();
+        outResult.mDensity = taskConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+        final int decorContainerOffsetX = -(int) (outsetsDp.left * outResult.mDensity);
+        final int decorContainerOffsetY = -(int) (outsetsDp.top * outResult.mDensity);
+        outResult.mWidth = taskBounds.width()
+                + (int) (outsetsDp.right * outResult.mDensity)
+                - decorContainerOffsetX;
+        outResult.mHeight = taskBounds.height()
+                + (int) (outsetsDp.bottom * outResult.mDensity)
+                - decorContainerOffsetY;
+        t.setPosition(mDecorationContainerSurface, decorContainerOffsetX, decorContainerOffsetY)
+                .setWindowCrop(mDecorationContainerSurface, outResult.mWidth, outResult.mHeight)
+                .setLayer(mDecorationContainerSurface, mTaskInfo.numActivities + 1)
+                .show(mDecorationContainerSurface);
+
+        // TaskBackgroundSurface
+        if (mTaskBackgroundSurface == null) {
+            final SurfaceControl.Builder builder = new SurfaceControl.Builder();
+            mTaskBackgroundSurface = builder
+                    .setName("Background of Task=" + mTaskInfo.taskId)
+                    .setEffectLayer()
+                    .setParent(mTaskSurface)
+                    .build();
+        }
+
+        float shadowRadius = outResult.mDensity * shadowRadiusDp;
+        int backgroundColorInt = mTaskInfo.taskDescription.getBackgroundColor();
+        mTmpColor[0] = Color.red(backgroundColorInt);
+        mTmpColor[1] = Color.green(backgroundColorInt);
+        mTmpColor[2] = Color.blue(backgroundColorInt);
+        t.setCrop(mTaskBackgroundSurface, taskBounds)
+                .setShadowRadius(mTaskBackgroundSurface, shadowRadius)
+                .setColor(mTaskBackgroundSurface, mTmpColor);
+
+        // Caption view
+        mCaptionWindowManager.setConfiguration(taskConfig);
+        final int captionHeight = (int) Math.ceil(captionHeightDp * outResult.mDensity);
+        final WindowManager.LayoutParams lp =
+                new WindowManager.LayoutParams(taskBounds.width(), captionHeight,
+                        WindowManager.LayoutParams.TYPE_APPLICATION,
+                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
+        lp.setTitle("Caption of Task=" + mTaskInfo.taskId);
+        lp.setTrustedOverlay();
+        if (mViewHost == null) {
+            mViewHost = new SurfaceControlViewHost(mDecorWindowContext, mDisplay,
+                    mCaptionWindowManager, true);
+            mViewHost.setView(outResult.mRootView, lp);
+        } else {
+            mViewHost.relayout(lp);
+        }
+
+        if (ViewRootImpl.CAPTION_ON_SHELL) {
+            outResult.mRootView.setTaskFocusState(mTaskInfo.isFocused);
+
+            // Caption insets
+            mCaptionInsetsRect.set(taskBounds);
+            mCaptionInsetsRect.bottom = mCaptionInsetsRect.top + captionHeight;
+            wct.addRectInsetsProvider(mTaskInfo.token, mCaptionInsetsRect, CAPTION_INSETS_TYPES);
+        } else {
+            outResult.mRootView.setVisibility(View.GONE);
+        }
+
+        // Task surface itself
+        Point taskPosition = mTaskInfo.positionInParent;
+        mTaskSurfaceCrop.set(
+                decorContainerOffsetX,
+                decorContainerOffsetY,
+                outResult.mWidth + decorContainerOffsetX,
+                outResult.mHeight + decorContainerOffsetY);
+        t.setPosition(mTaskSurface, taskPosition.x, taskPosition.y)
+                .setCrop(mTaskSurface, mTaskSurfaceCrop)
+                .show(mTaskSurface);
+    }
+
+    @Override
+    public void close() {
+        if (mViewHost != null) {
+            mViewHost.release();
+            mViewHost = null;
+        }
+
+        if (mDecorationContainerSurface != null) {
+            mDecorationContainerSurface.release();
+            mDecorationContainerSurface = null;
+        }
+
+        if (mTaskBackgroundSurface != null) {
+            mTaskBackgroundSurface.release();
+            mTaskBackgroundSurface = null;
+        }
+    }
+
+    static class RelayoutResult<T extends View & TaskFocusStateConsumer> {
+        int mWidth;
+        int mHeight;
+        float mDensity;
+        T mRootView;
+
+        void reset() {
+            mWidth = 0;
+            mHeight = 0;
+            mDensity = 0;
+            mRootView = null;
+        }
+    }
+
+    private static class CaptionWindowManager extends WindowlessWindowManager {
+        CaptionWindowManager(Configuration config, SurfaceControl rootSurface) {
+            super(config, rootSurface, null /* hostInputToken */);
+        }
+
+        @Override
+        public void setConfiguration(Configuration configuration) {
+            super.setConfiguration(configuration);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
index cb478c8..cba396a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -43,6 +43,84 @@
     }
 }
 
+fun FlickerTestParameter.splitScreenDividerBecomesVisible() {
+    layerBecomesVisible(SPLIT_SCREEN_DIVIDER_COMPONENT)
+}
+
+fun FlickerTestParameter.layerBecomesVisible(
+    component: FlickerComponentName
+) {
+    assertLayers {
+        this.isInvisible(component)
+            .then()
+            .isVisible(component)
+    }
+}
+
+fun FlickerTestParameter.layerIsVisibleAtEnd(
+    component: FlickerComponentName
+) {
+    assertLayersEnd {
+        this.isVisible(component)
+    }
+}
+
+fun FlickerTestParameter.splitAppLayerBoundsBecomesVisible(
+    rotation: Int,
+    component: FlickerComponentName,
+    splitLeftTop: Boolean
+) {
+    assertLayers {
+        val dividerRegion = this.last().layer(SPLIT_SCREEN_DIVIDER_COMPONENT).visibleRegion.region
+        this.isInvisible(component)
+            .then()
+            .invoke("splitAppLayerBoundsBecomesVisible") {
+                it.visibleRegion(component).overlaps(
+                    if (splitLeftTop) {
+                        getSplitLeftTopRegion(dividerRegion, rotation)
+                    } else {
+                        getSplitRightBottomRegion(dividerRegion, rotation)
+                    }
+                )
+            }
+    }
+}
+
+fun FlickerTestParameter.splitAppLayerBoundsIsVisibleAtEnd(
+    rotation: Int,
+    component: FlickerComponentName,
+    splitLeftTop: Boolean
+) {
+    assertLayersEnd {
+        val dividerRegion = layer(SPLIT_SCREEN_DIVIDER_COMPONENT).visibleRegion.region
+        visibleRegion(component).overlaps(
+            if (splitLeftTop) {
+                getSplitLeftTopRegion(dividerRegion, rotation)
+            } else {
+                getSplitRightBottomRegion(dividerRegion, rotation)
+            }
+        )
+    }
+}
+
+fun FlickerTestParameter.appWindowBecomesVisible(
+    component: FlickerComponentName
+) {
+    assertWm {
+        this.isAppWindowInvisible(component)
+            .then()
+            .isAppWindowVisible(component)
+    }
+}
+
+fun FlickerTestParameter.appWindowIsVisibleAtEnd(
+    component: FlickerComponentName
+) {
+    assertWmEnd {
+        this.isAppWindowVisible(component)
+    }
+}
+
 fun FlickerTestParameter.dockedStackDividerIsVisibleAtEnd() {
     assertLayersEnd {
         this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT)
@@ -118,21 +196,53 @@
 fun getPrimaryRegion(dividerRegion: Region, rotation: Int): Region {
     val displayBounds = WindowUtils.getDisplayBounds(rotation)
     return if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
-        Region.from(0, 0, displayBounds.bounds.right,
-            dividerRegion.bounds.top + WindowUtils.dockedStackDividerInset)
+        Region.from(
+            0, 0, displayBounds.bounds.right,
+            dividerRegion.bounds.top + WindowUtils.dockedStackDividerInset
+        )
     } else {
-        Region.from(0, 0, dividerRegion.bounds.left + WindowUtils.dockedStackDividerInset,
-            displayBounds.bounds.bottom)
+        Region.from(
+            0, 0, dividerRegion.bounds.left + WindowUtils.dockedStackDividerInset,
+            displayBounds.bounds.bottom
+        )
     }
 }
 
 fun getSecondaryRegion(dividerRegion: Region, rotation: Int): Region {
     val displayBounds = WindowUtils.getDisplayBounds(rotation)
     return if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
-        Region.from(0, dividerRegion.bounds.bottom - WindowUtils.dockedStackDividerInset,
-            displayBounds.bounds.right, displayBounds.bounds.bottom)
+        Region.from(
+            0, dividerRegion.bounds.bottom - WindowUtils.dockedStackDividerInset,
+            displayBounds.bounds.right, displayBounds.bounds.bottom
+        )
     } else {
-        Region.from(dividerRegion.bounds.right - WindowUtils.dockedStackDividerInset, 0,
-            displayBounds.bounds.right, displayBounds.bounds.bottom)
+        Region.from(
+            dividerRegion.bounds.right - WindowUtils.dockedStackDividerInset, 0,
+            displayBounds.bounds.right, displayBounds.bounds.bottom
+        )
     }
-}
\ No newline at end of file
+}
+
+fun getSplitLeftTopRegion(dividerRegion: Region, rotation: Int): Region {
+    val displayBounds = WindowUtils.getDisplayBounds(rotation)
+    return if (displayBounds.width > displayBounds.height) {
+        Region.from(0, 0, dividerRegion.bounds.left, displayBounds.bounds.bottom)
+    } else {
+        Region.from(0, 0, displayBounds.bounds.right, dividerRegion.bounds.top)
+    }
+}
+
+fun getSplitRightBottomRegion(dividerRegion: Region, rotation: Int): Region {
+    val displayBounds = WindowUtils.getDisplayBounds(rotation)
+    return if (displayBounds.width > displayBounds.height) {
+        Region.from(
+            dividerRegion.bounds.right, 0, displayBounds.bounds.right,
+            displayBounds.bounds.bottom
+        )
+    } else {
+        Region.from(
+            0, dividerRegion.bounds.bottom, displayBounds.bounds.right,
+            displayBounds.bounds.bottom
+        )
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
index 40891f3..f56eb6e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
@@ -21,4 +21,5 @@
 
 const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
 val APP_PAIR_SPLIT_DIVIDER_COMPONENT = FlickerComponentName("", "AppPairSplitDivider#")
-val DOCKED_STACK_DIVIDER_COMPONENT = FlickerComponentName("", "DockedStackDivider#")
\ No newline at end of file
+val DOCKED_STACK_DIVIDER_COMPONENT = FlickerComponentName("", "DockedStackDivider#")
+val SPLIT_SCREEN_DIVIDER_COMPONENT = FlickerComponentName("", "StageCoordinatorSplitDivider#")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt
deleted file mode 100644
index c9cab39..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.apppairs
-
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group1
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.wm.shell.flicker.appPairsDividerIsInvisibleAtEnd
-import com.android.wm.shell.flicker.helpers.AppPairsHelper
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
-import org.junit.After
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test cold launch app from launcher. When the device doesn't support non-resizable in multi window
- * {@link Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW}, app pairs should not pair
- * non-resizable apps.
- *
- * To run this test: `atest WMShellFlickerTests:AppPairsTestCannotPairNonResizeableApps`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group1
-class AppPairsTestCannotPairNonResizeableApps(
-    testSpec: FlickerTestParameter
-) : AppPairsTransition(testSpec) {
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                nonResizeableApp?.launchViaIntent(wmHelper)
-                // TODO pair apps through normal UX flow
-                executeShellCommand(
-                    composePairsCommand(primaryTaskId, nonResizeableTaskId, pair = true))
-                nonResizeableApp?.run { wmHelper.waitForFullScreenApp(nonResizeableApp.component) }
-            }
-        }
-
-    @Before
-    override fun setup() {
-        super.setup()
-        setSupportsNonResizableMultiWindow(instrumentation, -1)
-    }
-
-    @After
-    override fun teardown() {
-        super.teardown()
-        resetMultiWindowConfig(instrumentation)
-    }
-
-    @Ignore
-    @Test
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
-    @Ignore
-    @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
-    @Ignore
-    @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    @Ignore
-    @Test
-    fun appPairsDividerIsInvisibleAtEnd() = testSpec.appPairsDividerIsInvisibleAtEnd()
-
-    @Ignore
-    @Test
-    fun onlyResizeableAppWindowVisible() {
-        val nonResizeableApp = nonResizeableApp
-        require(nonResizeableApp != null) {
-            "Non resizeable app not initialized"
-        }
-        testSpec.assertWmEnd {
-            isAppWindowVisible(nonResizeableApp.component)
-            isAppWindowInvisible(primaryApp.component)
-        }
-    }
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = AppPairsHelper.TEST_REPETITIONS)
-        }
-    }
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
deleted file mode 100644
index 60c32c99..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.apppairs
-
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group1
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.wm.shell.flicker.APP_PAIR_SPLIT_DIVIDER_COMPONENT
-import com.android.wm.shell.flicker.appPairsDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.AppPairsHelper
-import com.android.wm.shell.flicker.helpers.AppPairsHelper.Companion.waitAppsShown
-import org.junit.FixMethodOrder
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test cold launch app from launcher.
- * To run this test: `atest WMShellFlickerTests:AppPairsTestPairPrimaryAndSecondaryApps`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group1
-class AppPairsTestPairPrimaryAndSecondaryApps(
-    testSpec: FlickerTestParameter
-) : AppPairsTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                // TODO pair apps through normal UX flow
-                executeShellCommand(
-                    composePairsCommand(primaryTaskId, secondaryTaskId, pair = true))
-                waitAppsShown(primaryApp, secondaryApp)
-            }
-        }
-
-    @Ignore
-    @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    @Ignore
-    @Test
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
-    @Ignore
-    @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
-    @Ignore
-    @Test
-    fun appPairsDividerIsVisibleAtEnd() = testSpec.appPairsDividerIsVisibleAtEnd()
-
-    @Ignore
-    @Test
-    fun bothAppWindowsVisible() {
-        testSpec.assertWmEnd {
-            isAppWindowVisible(primaryApp.component)
-            isAppWindowVisible(secondaryApp.component)
-        }
-    }
-
-    @Ignore
-    @Test
-    fun appsEndingBounds() {
-        testSpec.assertLayersEnd {
-            val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region
-            visibleRegion(primaryApp.component)
-                .coversExactly(appPairsHelper.getPrimaryBounds(dividerRegion))
-            visibleRegion(secondaryApp.component)
-                .coversExactly(appPairsHelper.getSecondaryBounds(dividerRegion))
-        }
-    }
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = AppPairsHelper.TEST_REPETITIONS)
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestSupportPairNonResizeableApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestSupportPairNonResizeableApps.kt
deleted file mode 100644
index 24869a8..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestSupportPairNonResizeableApps.kt
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.apppairs
-
-import android.view.Display
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group1
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.traces.common.WindowManagerConditionsFactory
-import com.android.wm.shell.flicker.appPairsDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.AppPairsHelper
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
-import org.junit.After
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test cold launch app from launcher. When the device supports non-resizable in multi window
- * {@link Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW}, app pairs can pair
- * non-resizable apps.
- *
- * To run this test: `atest WMShellFlickerTests:AppPairsTestSupportPairNonResizeableApps`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group1
-class AppPairsTestSupportPairNonResizeableApps(
-    testSpec: FlickerTestParameter
-) : AppPairsTransition(testSpec) {
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                nonResizeableApp?.launchViaIntent(wmHelper)
-                // TODO pair apps through normal UX flow
-                executeShellCommand(
-                        composePairsCommand(primaryTaskId, nonResizeableTaskId, pair = true))
-                val waitConditions = mutableListOf(
-                    WindowManagerConditionsFactory.isWindowVisible(primaryApp.component),
-                    WindowManagerConditionsFactory.isLayerVisible(primaryApp.component),
-                    WindowManagerConditionsFactory.isAppTransitionIdle(Display.DEFAULT_DISPLAY))
-
-                nonResizeableApp?.let {
-                    waitConditions.add(
-                        WindowManagerConditionsFactory.isWindowVisible(nonResizeableApp.component))
-                    waitConditions.add(
-                        WindowManagerConditionsFactory.isLayerVisible(nonResizeableApp.component))
-                }
-                wmHelper.waitFor(*waitConditions.toTypedArray())
-            }
-        }
-
-    @Before
-    override fun setup() {
-        super.setup()
-        setSupportsNonResizableMultiWindow(instrumentation, 1)
-    }
-
-    @After
-    override fun teardown() {
-        super.teardown()
-        resetMultiWindowConfig(instrumentation)
-    }
-
-    @Ignore
-    @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    @Ignore
-    @Test
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
-    @Ignore
-    @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
-    @Ignore
-    @Test
-    fun appPairsDividerIsVisibleAtEnd() = testSpec.appPairsDividerIsVisibleAtEnd()
-
-    @Ignore
-    @Test
-    fun bothAppWindowVisible() {
-        val nonResizeableApp = nonResizeableApp
-        require(nonResizeableApp != null) {
-            "Non resizeable app not initialized"
-        }
-        testSpec.assertWmEnd {
-            isAppWindowVisible(nonResizeableApp.component)
-            isAppWindowVisible(primaryApp.component)
-        }
-    }
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                    repetitions = AppPairsHelper.TEST_REPETITIONS)
-        }
-    }
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
deleted file mode 100644
index 007415d..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.apppairs
-
-import android.os.SystemClock
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group1
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.wm.shell.flicker.APP_PAIR_SPLIT_DIVIDER_COMPONENT
-import com.android.wm.shell.flicker.appPairsDividerIsInvisibleAtEnd
-import com.android.wm.shell.flicker.helpers.AppPairsHelper
-import com.android.wm.shell.flicker.helpers.AppPairsHelper.Companion.waitAppsShown
-import org.junit.FixMethodOrder
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test cold launch app from launcher.
- * To run this test: `atest WMShellFlickerTests:AppPairsTestUnpairPrimaryAndSecondaryApps`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group1
-class AppPairsTestUnpairPrimaryAndSecondaryApps(
-    testSpec: FlickerTestParameter
-) : AppPairsTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            setup {
-                eachRun {
-                    executeShellCommand(
-                            composePairsCommand(primaryTaskId, secondaryTaskId, pair = true))
-                    waitAppsShown(primaryApp, secondaryApp)
-                }
-            }
-            transitions {
-                // TODO pair apps through normal UX flow
-                executeShellCommand(
-                    composePairsCommand(primaryTaskId, secondaryTaskId, pair = false))
-                SystemClock.sleep(AppPairsHelper.TIMEOUT_MS)
-            }
-        }
-
-    @Ignore
-    @Test
-    override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales()
-
-    @Ignore
-    @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
-    @Ignore
-    @Test
-    fun appPairsDividerIsInvisibleAtEnd() = testSpec.appPairsDividerIsInvisibleAtEnd()
-
-    @Ignore
-    @Test
-    fun bothAppWindowsInvisible() {
-        testSpec.assertWmEnd {
-            isAppWindowInvisible(primaryApp.component)
-            isAppWindowInvisible(secondaryApp.component)
-        }
-    }
-
-    @Ignore
-    @Test
-    fun appsStartingBounds() {
-        testSpec.assertLayersStart {
-            val dividerRegion = layer(APP_PAIR_SPLIT_DIVIDER_COMPONENT).visibleRegion.region
-            visibleRegion(primaryApp.component)
-                .coversExactly(appPairsHelper.getPrimaryBounds(dividerRegion))
-            visibleRegion(secondaryApp.component)
-                .coversExactly(appPairsHelper.getSecondaryBounds(dividerRegion))
-        }
-    }
-
-    @Ignore
-    @Test
-    fun appsEndingBounds() {
-        testSpec.assertLayersEnd {
-            notContains(primaryApp.component)
-            notContains(secondaryApp.component)
-        }
-    }
-
-    @Ignore
-    @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = AppPairsHelper.TEST_REPETITIONS)
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTransition.kt
deleted file mode 100644
index 3e17948b..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTransition.kt
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.apppairs
-
-import android.app.Instrumentation
-import android.content.Context
-import android.system.helpers.ActivityHelper
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.parser.toFlickerComponent
-import com.android.wm.shell.flicker.helpers.AppPairsHelper
-import com.android.wm.shell.flicker.helpers.BaseAppHelper
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.getDevEnableNonResizableMultiWindow
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setDevEnableNonResizableMultiWindow
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import com.android.wm.shell.flicker.testapp.Components
-import org.junit.After
-import org.junit.Before
-import org.junit.Ignore
-import org.junit.Test
-
-abstract class AppPairsTransition(protected val testSpec: FlickerTestParameter) {
-    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-    protected val context: Context = instrumentation.context
-    protected val activityHelper = ActivityHelper.getInstance()
-    protected val appPairsHelper = AppPairsHelper(instrumentation,
-        Components.SplitScreenActivity.LABEL,
-        Components.SplitScreenActivity.COMPONENT.toFlickerComponent())
-
-    protected val primaryApp = SplitScreenHelper.getPrimary(instrumentation)
-    protected val secondaryApp = SplitScreenHelper.getSecondary(instrumentation)
-    protected open val nonResizeableApp: SplitScreenHelper? =
-        SplitScreenHelper.getNonResizeable(instrumentation)
-    protected var primaryTaskId = ""
-    protected var secondaryTaskId = ""
-    protected var nonResizeableTaskId = ""
-    private var prevDevEnableNonResizableMultiWindow = 0
-
-    @Before
-    open fun setup() {
-        prevDevEnableNonResizableMultiWindow = getDevEnableNonResizableMultiWindow(context)
-        if (prevDevEnableNonResizableMultiWindow != 0) {
-            // Turn off the development option
-            setDevEnableNonResizableMultiWindow(context, 0)
-        }
-    }
-
-    @After
-    open fun teardown() {
-        setDevEnableNonResizableMultiWindow(context, prevDevEnableNonResizableMultiWindow)
-    }
-
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            transition(this)
-        }
-    }
-
-    internal open val transition: FlickerBuilder.() -> Unit
-        get() = {
-            setup {
-                test {
-                    device.wakeUpAndGoToHomeScreen()
-                }
-                eachRun {
-                    this.setRotation(testSpec.startRotation)
-                    primaryApp.launchViaIntent(wmHelper)
-                    secondaryApp.launchViaIntent(wmHelper)
-                    nonResizeableApp?.launchViaIntent(wmHelper)
-                    updateTasksId()
-                }
-            }
-            teardown {
-                eachRun {
-                    executeShellCommand(composePairsCommand(
-                        primaryTaskId, secondaryTaskId, pair = false))
-                    executeShellCommand(composePairsCommand(
-                        primaryTaskId, nonResizeableTaskId, pair = false))
-                    primaryApp.exit(wmHelper)
-                    secondaryApp.exit(wmHelper)
-                    nonResizeableApp?.exit(wmHelper)
-                }
-            }
-        }
-
-    protected fun updateTasksId() {
-        primaryTaskId = getTaskIdForActivity(
-            primaryApp.component.packageName, primaryApp.component.className).toString()
-        secondaryTaskId = getTaskIdForActivity(
-            secondaryApp.component.packageName, secondaryApp.component.className).toString()
-        val nonResizeableApp = nonResizeableApp
-        if (nonResizeableApp != null) {
-            nonResizeableTaskId = getTaskIdForActivity(
-                nonResizeableApp.component.packageName,
-                nonResizeableApp.component.className).toString()
-        }
-    }
-
-    private fun getTaskIdForActivity(pkgName: String, activityName: String): Int {
-        return activityHelper.getTaskIdForActivity(pkgName, activityName)
-    }
-
-    internal fun executeShellCommand(cmd: String) {
-        BaseAppHelper.executeShellCommand(instrumentation, cmd)
-    }
-
-    internal fun composePairsCommand(
-        primaryApp: String,
-        secondaryApp: String,
-        pair: Boolean
-    ): String = buildString {
-        // dumpsys activity service SystemUIService WMShell {pair|unpair} ${TASK_ID_1} ${TASK_ID_2}
-        append("dumpsys activity service SystemUIService WMShell ")
-        if (pair) {
-            append("pair ")
-        } else {
-            append("unpair ")
-        }
-        append("$primaryApp $secondaryApp")
-    }
-
-    @Ignore
-    @Test
-    open fun navBarLayerIsVisible() {
-        testSpec.navBarLayerIsVisible()
-    }
-
-    @Ignore
-    @Test
-    open fun statusBarLayerIsVisible() {
-        testSpec.statusBarLayerIsVisible()
-    }
-
-    @Ignore
-    @Test
-    open fun navBarWindowIsVisible() {
-        testSpec.navBarWindowIsVisible()
-    }
-
-    @Ignore
-    @Test
-    open fun statusBarWindowIsVisible() {
-        testSpec.statusBarWindowIsVisible()
-    }
-
-    @Ignore
-    @Test
-    open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @Ignore
-    @Test
-    open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/OWNERS b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/OWNERS
deleted file mode 100644
index 8446b37..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# window manager > wm shell > Split Screen
-# Bug component: 928697
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt
deleted file mode 100644
index b0c3ba2..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt
+++ /dev/null
@@ -1,109 +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.wm.shell.flicker.apppairs
-
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group1
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.wm.shell.flicker.appPairsDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.appPairsPrimaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.appPairsSecondaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.AppPairsHelper.Companion.waitAppsShown
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open apps to app pairs and rotate.
- * To run this test: `atest WMShellFlickerTests:RotateTwoLaunchedAppsInAppPairsMode`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group1
-class RotateTwoLaunchedAppsInAppPairsMode(
-    testSpec: FlickerTestParameter
-) : RotateTwoLaunchedAppsTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                executeShellCommand(composePairsCommand(
-                    primaryTaskId, secondaryTaskId, true /* pair */))
-                waitAppsShown(primaryApp, secondaryApp)
-                setRotation(testSpec.endRotation)
-            }
-        }
-
-    @Ignore
-    @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    @Ignore
-    @Test
-    override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
-
-    @Ignore
-    @Test
-    fun bothAppWindowsVisible() {
-        testSpec.assertWmEnd {
-            isAppWindowVisible(primaryApp.component)
-            isAppWindowVisible(secondaryApp.component)
-        }
-    }
-
-    @Ignore
-    @Test
-    fun appPairsDividerIsVisibleAtEnd() = testSpec.appPairsDividerIsVisibleAtEnd()
-
-    @Ignore
-    @Test
-    fun appPairsPrimaryBoundsIsVisibleAtEnd() =
-        testSpec.appPairsPrimaryBoundsIsVisibleAtEnd(testSpec.endRotation,
-            primaryApp.component)
-
-    @Ignore
-    @Test
-    fun appPairsSecondaryBoundsIsVisibleAtEnd() =
-        testSpec.appPairsSecondaryBoundsIsVisibleAtEnd(testSpec.endRotation,
-            secondaryApp.component)
-
-    @Ignore
-    @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_90, Surface.ROTATION_270)
-            )
-        }
-    }
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt
deleted file mode 100644
index ae56c77..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt
+++ /dev/null
@@ -1,117 +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.wm.shell.flicker.apppairs
-
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group1
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.wm.shell.flicker.appPairsDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.appPairsPrimaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.appPairsSecondaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.AppPairsHelper.Companion.waitAppsShown
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open apps to app pairs and rotate.
- * To run this test: `atest WMShellFlickerTests:RotateTwoLaunchedAppsRotateAndEnterAppPairsMode`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group1
-class RotateTwoLaunchedAppsRotateAndEnterAppPairsMode(
-    testSpec: FlickerTestParameter
-) : RotateTwoLaunchedAppsTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                this.setRotation(testSpec.endRotation)
-                executeShellCommand(
-                    composePairsCommand(primaryTaskId, secondaryTaskId, pair = true))
-                waitAppsShown(primaryApp, secondaryApp)
-            }
-        }
-
-    @Ignore
-    @Test
-    fun appPairsDividerIsVisibleAtEnd() = testSpec.appPairsDividerIsVisibleAtEnd()
-
-    @Ignore
-    @Test
-    override fun navBarWindowIsVisible() = super.navBarWindowIsVisible()
-
-    @Ignore
-    @Test
-    override fun navBarLayerIsVisible() = super.navBarLayerIsVisible()
-
-    @Ignore
-    @Test
-    override fun statusBarWindowIsVisible() = super.statusBarWindowIsVisible()
-
-    @Ignore
-    @Test
-    override fun statusBarLayerIsVisible() = super.statusBarLayerIsVisible()
-
-    @Ignore
-    @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
-    @Ignore
-    @Test
-    fun bothAppWindowsVisible() {
-        testSpec.assertWmEnd {
-            isAppWindowVisible(primaryApp.component)
-            isAppWindowVisible(secondaryApp.component)
-        }
-    }
-
-    @Ignore
-    @Test
-    fun appPairsPrimaryBoundsIsVisibleAtEnd() =
-        testSpec.appPairsPrimaryBoundsIsVisibleAtEnd(testSpec.endRotation,
-            primaryApp.component)
-
-    @Ignore
-    @Test
-    fun appPairsSecondaryBoundsIsVisibleAtEnd() =
-        testSpec.appPairsSecondaryBoundsIsVisibleAtEnd(testSpec.endRotation,
-            secondaryApp.component)
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_90, Surface.ROTATION_270)
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsTransition.kt
deleted file mode 100644
index b1f1c9e5..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsTransition.kt
+++ /dev/null
@@ -1,76 +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.wm.shell.flicker.apppairs
-
-import android.view.Surface
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.wm.shell.flicker.helpers.BaseAppHelper.Companion.isShellTransitionsEnabled
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.Assume.assumeFalse
-import org.junit.Before
-import org.junit.Ignore
-import org.junit.Test
-
-abstract class RotateTwoLaunchedAppsTransition(
-    testSpec: FlickerTestParameter
-) : AppPairsTransition(testSpec) {
-    override val nonResizeableApp: SplitScreenHelper?
-        get() = null
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            setup {
-                test {
-                    device.wakeUpAndGoToHomeScreen()
-                    this.setRotation(Surface.ROTATION_0)
-                    primaryApp.launchViaIntent(wmHelper)
-                    secondaryApp.launchViaIntent(wmHelper)
-                    updateTasksId()
-                }
-            }
-            teardown {
-                eachRun {
-                    executeShellCommand(composePairsCommand(
-                        primaryTaskId, secondaryTaskId, pair = false))
-                    primaryApp.exit(wmHelper)
-                    secondaryApp.exit(wmHelper)
-                }
-            }
-        }
-
-    @Before
-    override fun setup() {
-        // AppPairs hasn't been updated to Shell Transition. There will be conflict on rotation.
-        assumeFalse(isShellTransitionsEnabled())
-        super.setup()
-    }
-
-    @Ignore
-    @Test
-    override fun navBarLayerIsVisible() {
-        super.navBarLayerIsVisible()
-    }
-
-    @Ignore
-    @Test
-    override fun navBarLayerRotatesAndScales() {
-        super.navBarLayerRotatesAndScales()
-    }
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
index e9d438a..f73d191 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
@@ -39,7 +39,7 @@
 ) {
     private val mediaSessionManager: MediaSessionManager
         get() = context.getSystemService(MediaSessionManager::class.java)
-                ?: error("Could not get MediaSessionManager")
+            ?: error("Could not get MediaSessionManager")
 
     private val mediaController: MediaController?
         get() = mediaSessionManager.getActiveSessions(null).firstOrNull {
@@ -69,8 +69,10 @@
         action: String? = null,
         stringExtras: Map<String, String>
     ) {
-        launchViaIntentAndWaitShown(wmHelper, expectedWindowName, action, stringExtras,
-            waitConditions = arrayOf(WindowManagerStateHelper.pipShownCondition))
+        launchViaIntentAndWaitShown(
+            wmHelper, expectedWindowName, action, stringExtras,
+            waitConditions = arrayOf(WindowManagerStateHelper.pipShownCondition)
+        )
     }
 
     /**
@@ -85,7 +87,7 @@
         // from "the bottom".
         repeat(FOCUS_ATTEMPTS) {
             uiDevice.findObject(selector)?.apply { if (isFocusedOrHasFocusedChild) return true }
-                    ?: error("The object we try to focus on is gone.")
+                ?: error("The object we try to focus on is gone.")
 
             uiDevice.pressDPadDown()
             uiDevice.waitForIdle()
@@ -100,29 +102,35 @@
         // Wait on WMHelper or simply wait for 3 seconds
         wmHelper?.waitPipShown() ?: SystemClock.sleep(3_000)
         // when entering pip, the dismiss button is visible at the start. to ensure the pip
-        // animation is complete, wait until the pip dismiss button is no longer visible. 
+        // animation is complete, wait until the pip dismiss button is no longer visible.
         // b/176822698: dismiss-only state will be removed in the future
         uiDevice.wait(Until.gone(By.res(SYSTEMUI_PACKAGE, "dismiss")), FIND_TIMEOUT)
     }
 
+    fun enableEnterPipOnUserLeaveHint() {
+        clickObject(ENTER_PIP_ON_USER_LEAVE_HINT)
+    }
+
     fun clickStartMediaSessionButton() {
         clickObject(MEDIA_SESSION_START_RADIO_BUTTON_ID)
     }
 
     fun checkWithCustomActionsCheckbox() = uiDevice
-            .findObject(By.res(component.packageName, WITH_CUSTOM_ACTIONS_BUTTON_ID))
-                ?.takeIf { it.isCheckable }
-                ?.apply { if (!isChecked) clickObject(WITH_CUSTOM_ACTIONS_BUTTON_ID) }
-                ?: error("'With custom actions' checkbox not found")
+        .findObject(By.res(component.packageName, WITH_CUSTOM_ACTIONS_BUTTON_ID))
+        ?.takeIf { it.isCheckable }
+        ?.apply { if (!isChecked) clickObject(WITH_CUSTOM_ACTIONS_BUTTON_ID) }
+        ?: error("'With custom actions' checkbox not found")
 
     fun pauseMedia() = mediaController?.transportControls?.pause()
-            ?: error("No active media session found")
+        ?: error("No active media session found")
 
     fun stopMedia() = mediaController?.transportControls?.stop()
-            ?: error("No active media session found")
+        ?: error("No active media session found")
 
-    @Deprecated("Use PipAppHelper.closePipWindow(wmHelper) instead",
-        ReplaceWith("closePipWindow(wmHelper)"))
+    @Deprecated(
+        "Use PipAppHelper.closePipWindow(wmHelper) instead",
+        ReplaceWith("closePipWindow(wmHelper)")
+    )
     fun closePipWindow() {
         if (isTelevision) {
             uiDevice.closeTvPipWindow()
@@ -152,7 +160,7 @@
             val dismissSelector = By.res(SYSTEMUI_PACKAGE, "dismiss")
             uiDevice.wait(Until.hasObject(dismissSelector), FIND_TIMEOUT)
             val dismissPipObject = uiDevice.findObject(dismissSelector)
-                    ?: error("PIP window dismiss button not found")
+                ?: error("PIP window dismiss button not found")
             val dismissButtonBounds = dismissPipObject.visibleBounds
             uiDevice.click(dismissButtonBounds.centerX(), dismissButtonBounds.centerY())
         }
@@ -172,7 +180,7 @@
         val expandSelector = By.res(SYSTEMUI_PACKAGE, "expand_button")
         uiDevice.wait(Until.hasObject(expandSelector), FIND_TIMEOUT)
         val expandPipObject = uiDevice.findObject(expandSelector)
-                ?: error("PIP window expand button not found")
+            ?: error("PIP window expand button not found")
         val expandButtonBounds = expandPipObject.visibleBounds
         uiDevice.click(expandButtonBounds.centerX(), expandButtonBounds.centerY())
         wmHelper.waitPipGone()
@@ -194,5 +202,6 @@
         private const val ENTER_PIP_BUTTON_ID = "enter_pip"
         private const val WITH_CUSTOM_ACTIONS_BUTTON_ID = "with_custom_actions"
         private const val MEDIA_SESSION_START_RADIO_BUTTON_ID = "media_session_start"
+        private const val ENTER_PIP_ON_USER_LEAVE_HINT = "enter_pip_on_leave_manual"
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
index 0ec9b2d..d4298b8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
@@ -17,9 +17,18 @@
 package com.android.wm.shell.flicker.helpers
 
 import android.app.Instrumentation
-import android.content.res.Resources
+import android.graphics.Point
+import android.os.SystemClock
+import android.view.InputDevice
+import android.view.MotionEvent
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.BySelector
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
 import com.android.server.wm.traces.common.FlickerComponentName
 import com.android.server.wm.traces.parser.toFlickerComponent
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
+import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
 import com.android.wm.shell.flicker.testapp.Components
 
 class SplitScreenHelper(
@@ -31,25 +40,152 @@
     companion object {
         const val TEST_REPETITIONS = 1
         const val TIMEOUT_MS = 3_000L
+        const val DRAG_DURATION_MS = 1_000L
+        const val NOTIFICATION_SCROLLER = "notification_stack_scroller"
+        const val GESTURE_STEP_MS = 16L
 
-        // TODO: remove all legacy split screen flicker tests when legacy split screen is fully
-        //  deprecated.
-        fun isUsingLegacySplit(): Boolean =
-                Resources.getSystem().getBoolean(com.android.internal.R.bool.config_useLegacySplit)
+        private val notificationScrollerSelector: BySelector
+            get() = By.res(SYSTEM_UI_PACKAGE_NAME, NOTIFICATION_SCROLLER)
+        private val notificationContentSelector: BySelector
+            get() = By.text("Notification content")
 
         fun getPrimary(instrumentation: Instrumentation): SplitScreenHelper =
-            SplitScreenHelper(instrumentation,
+            SplitScreenHelper(
+                instrumentation,
                 Components.SplitScreenActivity.LABEL,
-                Components.SplitScreenActivity.COMPONENT.toFlickerComponent())
+                Components.SplitScreenActivity.COMPONENT.toFlickerComponent()
+            )
 
         fun getSecondary(instrumentation: Instrumentation): SplitScreenHelper =
-            SplitScreenHelper(instrumentation,
+            SplitScreenHelper(
+                instrumentation,
                 Components.SplitScreenSecondaryActivity.LABEL,
-                Components.SplitScreenSecondaryActivity.COMPONENT.toFlickerComponent())
+                Components.SplitScreenSecondaryActivity.COMPONENT.toFlickerComponent()
+            )
 
         fun getNonResizeable(instrumentation: Instrumentation): SplitScreenHelper =
-            SplitScreenHelper(instrumentation,
+            SplitScreenHelper(
+                instrumentation,
                 Components.NonResizeableActivity.LABEL,
-                Components.NonResizeableActivity.COMPONENT.toFlickerComponent())
+                Components.NonResizeableActivity.COMPONENT.toFlickerComponent()
+            )
+
+        fun getSendNotification(instrumentation: Instrumentation): SplitScreenHelper =
+            SplitScreenHelper(
+                instrumentation,
+                Components.SendNotificationActivity.LABEL,
+                Components.SendNotificationActivity.COMPONENT.toFlickerComponent()
+            )
+
+        fun dragFromNotificationToSplit(
+            instrumentation: Instrumentation,
+            device: UiDevice,
+            wmHelper: WindowManagerStateHelper
+        ) {
+            val displayBounds = wmHelper.currentState.layerState
+                .displays.firstOrNull { !it.isVirtual }
+                ?.layerStackSpace
+                ?: error("Display not found")
+
+            // Pull down the notifications
+            device.swipe(
+                displayBounds.centerX(), 5,
+                displayBounds.centerX(), displayBounds.bottom, 20 /* steps */
+            )
+            SystemClock.sleep(TIMEOUT_MS)
+
+            // Find the target notification
+            val notificationScroller = device.wait(
+                Until.findObject(notificationScrollerSelector), TIMEOUT_MS
+            )
+            var notificationContent = notificationScroller.findObject(notificationContentSelector)
+
+            while (notificationContent == null) {
+                device.swipe(
+                    displayBounds.centerX(), displayBounds.centerY(),
+                    displayBounds.centerX(), displayBounds.centerY() - 150, 20 /* steps */
+                )
+                notificationContent = notificationScroller.findObject(notificationContentSelector)
+            }
+
+            // Drag to split
+            var dragStart = notificationContent.visibleCenter
+            var dragMiddle = Point(dragStart.x + 50, dragStart.y)
+            var dragEnd = Point(displayBounds.width / 4, displayBounds.width / 4)
+            val downTime = SystemClock.uptimeMillis()
+
+            touch(
+                instrumentation, MotionEvent.ACTION_DOWN, downTime, downTime,
+                TIMEOUT_MS, dragStart
+            )
+            // It needs a horizontal movement to trigger the drag
+            touchMove(
+                instrumentation, downTime, SystemClock.uptimeMillis(),
+                DRAG_DURATION_MS, dragStart, dragMiddle
+            )
+            touchMove(
+                instrumentation, downTime, SystemClock.uptimeMillis(),
+                DRAG_DURATION_MS, dragMiddle, dragEnd
+            )
+            // Wait for a while to start splitting
+            SystemClock.sleep(TIMEOUT_MS)
+            touch(
+                instrumentation, MotionEvent.ACTION_UP, downTime, SystemClock.uptimeMillis(),
+                GESTURE_STEP_MS, dragEnd
+            )
+            SystemClock.sleep(TIMEOUT_MS)
+        }
+
+        fun touch(
+            instrumentation: Instrumentation,
+            action: Int,
+            downTime: Long,
+            eventTime: Long,
+            duration: Long,
+            point: Point
+        ) {
+            val motionEvent = MotionEvent.obtain(
+                downTime, eventTime, action, point.x.toFloat(), point.y.toFloat(), 0
+            )
+            motionEvent.source = InputDevice.SOURCE_TOUCHSCREEN
+            instrumentation.uiAutomation.injectInputEvent(motionEvent, true)
+            motionEvent.recycle()
+            SystemClock.sleep(duration)
+        }
+
+        fun touchMove(
+            instrumentation: Instrumentation,
+            downTime: Long,
+            eventTime: Long,
+            duration: Long,
+            from: Point,
+            to: Point
+        ) {
+            val steps: Long = duration / GESTURE_STEP_MS
+            var currentTime = eventTime
+            var currentX = from.x.toFloat()
+            var currentY = from.y.toFloat()
+            val stepX = (to.x.toFloat() - from.x.toFloat()) / steps.toFloat()
+            val stepY = (to.y.toFloat() - from.y.toFloat()) / steps.toFloat()
+
+            for (i in 1..steps) {
+                val motionMove = MotionEvent.obtain(
+                    downTime, currentTime, MotionEvent.ACTION_MOVE, currentX, currentY, 0
+                )
+                motionMove.source = InputDevice.SOURCE_TOUCHSCREEN
+                instrumentation.uiAutomation.injectInputEvent(motionMove, true)
+                motionMove.recycle()
+
+                currentTime += GESTURE_STEP_MS
+                if (i == steps - 1) {
+                    currentX = to.x.toFloat()
+                    currentY = to.y.toFloat()
+                } else {
+                    currentX += stepX
+                    currentY += stepY
+                }
+                SystemClock.sleep(GESTURE_STEP_MS)
+            }
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt
deleted file mode 100644
index c86a122..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt
+++ /dev/null
@@ -1,116 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import android.view.WindowManagerPolicyConstants
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group4
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.dockedStackDividerBecomesVisible
-import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open activity and dock to primary split screen
- * To run this test: `atest WMShellFlickerTests:EnterSplitScreenDockActivity`
- */
-@Presubmit
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group4
-class EnterSplitScreenDockActivity(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                device.launchSplitScreen(wmHelper)
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(LAUNCHER_COMPONENT, LIVE_WALLPAPER_COMPONENT,
-            splitScreenApp.component, FlickerComponentName.SPLASH_SCREEN,
-                FlickerComponentName.SNAPSHOT, LAUNCHER_COMPONENT)
-
-    @Presubmit
-    @Test
-    fun dockedStackPrimaryBoundsIsVisibleAtEnd() =
-        testSpec.dockedStackPrimaryBoundsIsVisibleAtEnd(testSpec.startRotation,
-            splitScreenApp.component)
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerBecomesVisible() = testSpec.dockedStackDividerBecomesVisible()
-
-    @Presubmit
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun appWindowIsVisible() {
-        testSpec.assertWmEnd {
-            isAppWindowVisible(splitScreenApp.component)
-        }
-    }
-
-    @FlakyTest
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-        super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0), // bugId = 179116910
-                supportedNavigationModes = listOf(
-                        WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenFromDetachedRecentTask.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenFromDetachedRecentTask.kt
deleted file mode 100644
index 2f9244b..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenFromDetachedRecentTask.kt
+++ /dev/null
@@ -1,104 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group4
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.dockedStackDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test enter split screen from a detached recent task
- *
- * To run this test: `atest WMShellFlickerTests:EnterSplitScreenFromDetachedRecentTask`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@Group4
-class EnterSplitScreenFromDetachedRecentTask(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            cleanSetup(this)
-            setup {
-                eachRun {
-                    splitScreenApp.launchViaIntent(wmHelper)
-                    // Press back to remove the task, but it should still be shown in recent.
-                    device.pressBack()
-                }
-            }
-            transitions {
-                device.launchSplitScreen(wmHelper)
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(LAUNCHER_COMPONENT,
-                FlickerComponentName.SPLASH_SCREEN,
-                FlickerComponentName.SNAPSHOT,
-                splitScreenApp.component)
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerIsVisibleAtEnd() = testSpec.dockedStackDividerIsVisibleAtEnd()
-
-    @Presubmit
-    @Test
-    fun appWindowIsVisible() {
-        testSpec.assertWmEnd {
-            isAppWindowVisible(splitScreenApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                    repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                    supportedRotations = listOf(Surface.ROTATION_0) // bugId = 179116910
-            )
-        }
-    }
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt
deleted file mode 100644
index 1740c3e..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt
+++ /dev/null
@@ -1,126 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group4
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.reopenAppFromOverview
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.dockedStackDividerBecomesVisible
-import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.dockedStackSecondaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open activity to primary split screen and dock secondary activity to side
- * To run this test: `atest WMShellFlickerTests:EnterSplitScreenLaunchToSide`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group4
-class EnterSplitScreenLaunchToSide(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                device.launchSplitScreen(wmHelper)
-                device.reopenAppFromOverview(wmHelper)
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(LAUNCHER_COMPONENT, splitScreenApp.component,
-            secondaryApp.component, FlickerComponentName.SPLASH_SCREEN,
-            FlickerComponentName.SNAPSHOT)
-
-    @Presubmit
-    @Test
-    fun dockedStackPrimaryBoundsIsVisibleAtEnd() =
-        testSpec.dockedStackPrimaryBoundsIsVisibleAtEnd(testSpec.startRotation,
-            splitScreenApp.component)
-
-    @Presubmit
-    @Test
-    fun dockedStackSecondaryBoundsIsVisibleAtEnd() =
-        testSpec.dockedStackSecondaryBoundsIsVisibleAtEnd(testSpec.startRotation,
-            secondaryApp.component)
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerBecomesVisible() = testSpec.dockedStackDividerBecomesVisible()
-
-    @Presubmit
-    @Test
-    fun appWindowBecomesVisible() {
-        testSpec.assertWm {
-            // when the app is launched, first the activity becomes visible, then the
-            // SnapshotStartingWindow appears and then the app window becomes visible.
-            // Because we log WM once per frame, sometimes the activity and the window
-            // become visible in the same entry, sometimes not, thus it is not possible to
-            // assert the visibility of the activity here
-            this.isAppWindowInvisible(secondaryApp.component)
-                    .then()
-                    // during re-parenting, the window may disappear and reappear from the
-                    // trace, this occurs because we log only 1x per frame
-                    .notContains(secondaryApp.component, isOptional = true)
-                    .then()
-                    .isAppWindowVisible(secondaryApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0) // bugId = 175687842
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNotSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNotSupportNonResizable.kt
deleted file mode 100644
index 4c063b91..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNotSupportNonResizable.kt
+++ /dev/null
@@ -1,110 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group4
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.canSplitScreen
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.dockedStackDividerNotExistsAtEnd
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.After
-import org.junit.Assert
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test enter split screen from non-resizable activity. When the device doesn't support
- * non-resizable in multi window, there should be no button to enter split screen for non-resizable
- * activity.
- *
- * To run this test: `atest WMShellFlickerTests:EnterSplitScreenNotSupportNonResizable`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@Group4
-class EnterSplitScreenNotSupportNonResizable(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            cleanSetup(this)
-            setup {
-                eachRun {
-                    nonResizeableApp.launchViaIntent(wmHelper)
-                }
-            }
-            transitions {
-                if (device.canSplitScreen(wmHelper)) {
-                    Assert.fail("Non-resizeable app should not enter split screen")
-                }
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(LAUNCHER_COMPONENT,
-            FlickerComponentName.SPLASH_SCREEN,
-            FlickerComponentName.SNAPSHOT,
-            nonResizeableApp.component,
-            splitScreenApp.component)
-
-    @Before
-    override fun setup() {
-        super.setup()
-        setSupportsNonResizableMultiWindow(instrumentation, -1)
-    }
-
-    @After
-    override fun teardown() {
-        super.teardown()
-        resetMultiWindowConfig(instrumentation)
-    }
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerNotExistsAtEnd() = testSpec.dockedStackDividerNotExistsAtEnd()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0)) // b/178685668
-        }
-    }
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenSupportNonResizable.kt
deleted file mode 100644
index f75dee6..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenSupportNonResizable.kt
+++ /dev/null
@@ -1,115 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.dockedStackDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.After
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test enter split screen from non-resizable activity. When the device supports
- * non-resizable in multi window, there should be a button to enter split screen for non-resizable
- * activity.
- *
- * To run this test: `atest WMShellFlickerTests:EnterSplitScreenSupportNonResizable`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@Group2
-class EnterSplitScreenSupportNonResizable(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            cleanSetup(this)
-            setup {
-                eachRun {
-                    nonResizeableApp.launchViaIntent(wmHelper)
-                }
-            }
-            transitions {
-                device.launchSplitScreen(wmHelper)
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(LAUNCHER_COMPONENT,
-            FlickerComponentName.SPLASH_SCREEN,
-            FlickerComponentName.SNAPSHOT,
-            nonResizeableApp.component,
-            splitScreenApp.component)
-
-    @Before
-    override fun setup() {
-        super.setup()
-        setSupportsNonResizableMultiWindow(instrumentation, 1)
-    }
-
-    @After
-    override fun teardown() {
-        super.teardown()
-        resetMultiWindowConfig(instrumentation)
-    }
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerIsVisibleAtEnd() = testSpec.dockedStackDividerIsVisibleAtEnd()
-
-    @Presubmit
-    @Test
-    fun appWindowIsVisible() {
-        testSpec.assertWmEnd {
-            isAppWindowVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                    repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                    supportedRotations = listOf(Surface.ROTATION_0)) // b/178685668
-        }
-    }
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt
deleted file mode 100644
index ef7d65e..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.legacysplitscreen
-
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.exitSplitScreenFromBottom
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.DOCKED_STACK_DIVIDER_COMPONENT
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open resizeable activity split in primary, and drag divider to bottom exit split screen
- * To run this test: `atest WMShellFlickerTests:ExitLegacySplitScreenFromBottom`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class ExitLegacySplitScreenFromBottom(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            setup {
-                eachRun {
-                    splitScreenApp.launchViaIntent(wmHelper)
-                    device.launchSplitScreen(wmHelper)
-                }
-            }
-            teardown {
-                eachRun {
-                    splitScreenApp.exit(wmHelper)
-                }
-            }
-            transitions {
-                device.exitSplitScreenFromBottom(wmHelper)
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(LAUNCHER_COMPONENT, FlickerComponentName.SPLASH_SCREEN,
-            splitScreenApp.component, secondaryApp.component,
-            FlickerComponentName.SNAPSHOT)
-
-    @FlakyTest
-    @Test
-    fun layerBecomesInvisible() {
-        testSpec.assertLayers {
-            this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT)
-                    .then()
-                    .isInvisible(DOCKED_STACK_DIVIDER_COMPONENT)
-        }
-    }
-
-    @FlakyTest
-    @Test
-    fun appWindowBecomesInVisible() {
-        testSpec.assertWm {
-            this.isAppWindowVisible(secondaryApp.component)
-                    .then()
-                    .isAppWindowInvisible(secondaryApp.component)
-        }
-    }
-
-    @FlakyTest
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @FlakyTest
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @FlakyTest
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    @FlakyTest
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0) // b/175687842
-            )
-        }
-    }
-}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt
deleted file mode 100644
index d913a6d..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt
+++ /dev/null
@@ -1,129 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.reopenAppFromOverview
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.dockedStackDividerNotExistsAtEnd
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test dock activity to primary split screen, and open secondary to side, exit primary split
- * and test secondary activity become full screen.
- * To run this test: `atest WMShellFlickerTests:ExitPrimarySplitScreenShowSecondaryFullscreen`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class ExitPrimarySplitScreenShowSecondaryFullscreen(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            teardown {
-                eachRun {
-                    secondaryApp.exit(wmHelper)
-                }
-            }
-            transitions {
-                splitScreenApp.launchViaIntent(wmHelper)
-                secondaryApp.launchViaIntent(wmHelper)
-                device.launchSplitScreen(wmHelper)
-                device.reopenAppFromOverview(wmHelper)
-                // TODO(b/175687842) Can not find Split screen divider, use exit() instead
-                splitScreenApp.exit(wmHelper)
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(LAUNCHER_COMPONENT, FlickerComponentName.SPLASH_SCREEN,
-            splitScreenApp.component, secondaryApp.component,
-            FlickerComponentName.SNAPSHOT)
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerNotExistsAtEnd() = testSpec.dockedStackDividerNotExistsAtEnd()
-
-    @FlakyTest
-    @Test
-    fun layerBecomesInvisible() {
-        testSpec.assertLayers {
-            this.isVisible(splitScreenApp.component)
-                    .then()
-                    .isInvisible(splitScreenApp.component)
-        }
-    }
-
-    @FlakyTest
-    @Test
-    fun appWindowBecomesInVisible() {
-        testSpec.assertWm {
-            this.isAppWindowVisible(splitScreenApp.component)
-                    .then()
-                    .isAppWindowInvisible(splitScreenApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0) // bugId = 179116910
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentNotSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentNotSupportNonResizable.kt
deleted file mode 100644
index f3ff7b1..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentNotSupportNonResizable.kt
+++ /dev/null
@@ -1,196 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.DOCKED_STACK_DIVIDER_COMPONENT
-import com.android.wm.shell.flicker.dockedStackDividerNotExistsAtEnd
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.After
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test launch non-resizable activity via intent in split screen mode. When the device does not
- * support non-resizable in multi window, it should trigger exit split screen.
- * To run this test: `atest WMShellFlickerTests:LegacySplitScreenFromIntentNotSupportNonResizable`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class LegacySplitScreenFromIntentNotSupportNonResizable(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            cleanSetup(this)
-            setup {
-                eachRun {
-                    splitScreenApp.launchViaIntent(wmHelper)
-                    device.launchSplitScreen(wmHelper)
-                }
-            }
-            transitions {
-                nonResizeableApp.launchViaIntent(wmHelper)
-                wmHelper.waitForAppTransitionIdle()
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(DOCKED_STACK_DIVIDER_COMPONENT, LAUNCHER_COMPONENT, LETTERBOX_COMPONENT,
-            nonResizeableApp.component, splitScreenApp.component,
-            FlickerComponentName.SPLASH_SCREEN,
-            FlickerComponentName.SNAPSHOT)
-
-    @Before
-    override fun setup() {
-        super.setup()
-        setSupportsNonResizableMultiWindow(instrumentation, -1)
-    }
-
-    @After
-    override fun teardown() {
-        super.teardown()
-        resetMultiWindowConfig(instrumentation)
-    }
-
-    @Presubmit
-    @Test
-    fun resizableAppLayerBecomesInvisible() {
-        testSpec.assertLayers {
-            this.isVisible(splitScreenApp.component)
-                    .then()
-                    .isInvisible(splitScreenApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun nonResizableAppLayerBecomesVisible() {
-        testSpec.assertLayers {
-            this.notContains(nonResizeableApp.component)
-                    .then()
-                    .isInvisible(nonResizeableApp.component)
-                    .then()
-                    .isVisible(nonResizeableApp.component)
-        }
-    }
-
-    /**
-     * Assets that [splitScreenApp] exists at the start of the trace and, once it becomes
-     * invisible, it remains invisible until the end of the trace.
-     */
-    @Presubmit
-    @Test
-    fun resizableAppWindowBecomesInvisible() {
-        testSpec.assertWm {
-            // when the activity gets PAUSED the window may still be marked as visible
-            // it will be updated in the next log entry. This occurs because we record 1x
-            // per frame, thus ignore activity check here
-            this.isAppWindowVisible(splitScreenApp.component)
-                    .then()
-                    // immediately after the window (after onResume and before perform relayout)
-                    // the activity is invisible. This may or not be logged, since we record 1x
-                    // per frame, thus ignore activity check here
-                    .isAppWindowInvisible(splitScreenApp.component)
-        }
-    }
-
-    /**
-     * Assets that [nonResizeableApp] doesn't exist at the start of the trace, then
-     * [nonResizeableApp] is created (visible or not) and, once [nonResizeableApp] becomes
-     * visible, it remains visible until the end of the trace.
-     */
-    @Presubmit
-    @Test
-    fun nonResizableAppWindowBecomesVisible() {
-        testSpec.assertWm {
-            this.notContains(nonResizeableApp.component)
-                    .then()
-                    // we log once per frame, upon logging, window may be visible or not depending
-                    // on what was processed until that moment. Both behaviors are correct
-                    .isAppWindowInvisible(nonResizeableApp.component, isOptional = true)
-                    .then()
-                    // immediately after the window (after onResume and before perform relayout)
-                    // the activity is invisible. This may or not be logged, since we record 1x
-                    // per frame, thus ignore activity check here
-                    .isAppWindowVisible(nonResizeableApp.component)
-        }
-    }
-
-    /**
-     * Asserts that both the app window and the activity are visible at the end of the trace
-     */
-    @Presubmit
-    @Test
-    fun nonResizableAppWindowBecomesVisibleAtEnd() {
-        testSpec.assertWmEnd {
-            isAppWindowVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerNotExistsAtEnd() = testSpec.dockedStackDividerNotExistsAtEnd()
-
-    @Presubmit
-    @Test
-    fun onlyNonResizableAppWindowIsVisibleAtEnd() {
-        testSpec.assertWmEnd {
-            isAppWindowInvisible(splitScreenApp.component)
-            isAppWindowVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                    repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                    supportedRotations = listOf(Surface.ROTATION_0)) // b/178685668
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentSupportNonResizable.kt
deleted file mode 100644
index 42e707a..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentSupportNonResizable.kt
+++ /dev/null
@@ -1,153 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.DOCKED_STACK_DIVIDER_COMPONENT
-import com.android.wm.shell.flicker.dockedStackDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.After
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test launch non-resizable activity via intent in split screen mode. When the device supports
- * non-resizable in multi window, it should show the non-resizable app in split screen.
- * To run this test: `atest WMShellFlickerTests:LegacySplitScreenFromIntentSupportNonResizable`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class LegacySplitScreenFromIntentSupportNonResizable(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            cleanSetup(this)
-            setup {
-                eachRun {
-                    splitScreenApp.launchViaIntent(wmHelper)
-                    device.launchSplitScreen(wmHelper)
-                }
-            }
-            transitions {
-                nonResizeableApp.launchViaIntent(wmHelper)
-                wmHelper.waitForAppTransitionIdle()
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(DOCKED_STACK_DIVIDER_COMPONENT, LAUNCHER_COMPONENT, LETTERBOX_COMPONENT,
-            nonResizeableApp.component, splitScreenApp.component,
-            FlickerComponentName.SPLASH_SCREEN,
-            FlickerComponentName.SNAPSHOT)
-
-    @Before
-    override fun setup() {
-        super.setup()
-        setSupportsNonResizableMultiWindow(instrumentation, 1)
-    }
-
-    @After
-    override fun teardown() {
-        super.teardown()
-        resetMultiWindowConfig(instrumentation)
-    }
-
-    @Presubmit
-    @Test
-    fun nonResizableAppLayerBecomesVisible() {
-        testSpec.assertLayers {
-            this.isInvisible(nonResizeableApp.component)
-                    .then()
-                    .isVisible(nonResizeableApp.component)
-        }
-    }
-
-    /**
-     * Assets that [nonResizeableApp] doesn't exist at the start of the trace, then
-     * [nonResizeableApp] is created (visible or not) and, once [nonResizeableApp] becomes
-     * visible, it remains visible until the end of the trace.
-     */
-    @Presubmit
-    @Test
-    fun nonResizableAppWindowBecomesVisible() {
-        testSpec.assertWm {
-            this.notContains(nonResizeableApp.component)
-                    .then()
-                    // we log once per frame, upon logging, window may be visible or not depending
-                    // on what was processed until that moment. Both behaviors are correct
-                    .isAppWindowInvisible(nonResizeableApp.component, isOptional = true)
-                    .then()
-                    // immediately after the window (after onResume and before perform relayout)
-                    // the activity is invisible. This may or not be logged, since we record 1x
-                    // per frame, thus ignore activity check here
-                    .isAppWindowVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerIsVisibleAtEnd() = testSpec.dockedStackDividerIsVisibleAtEnd()
-
-    @Presubmit
-    @Test
-    fun bothAppsWindowsAreVisibleAtEnd() {
-        testSpec.assertWmEnd {
-            isAppWindowVisible(splitScreenApp.component)
-            isAppWindowVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0)) // b/178685668
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentNotSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentNotSupportNonResizable.kt
deleted file mode 100644
index c1fba7d..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentNotSupportNonResizable.kt
+++ /dev/null
@@ -1,169 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.reopenAppFromOverview
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.DOCKED_STACK_DIVIDER_COMPONENT
-import com.android.wm.shell.flicker.dockedStackDividerNotExistsAtEnd
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.After
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test launch non-resizable activity via recent overview in split screen mode. When the device does
- * not support non-resizable in multi window, it should trigger exit split screen.
- * To run this test: `atest WMShellFlickerTests:LegacySplitScreenFromRecentNotSupportNonResizable`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class LegacySplitScreenFromRecentNotSupportNonResizable(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            cleanSetup(this)
-            setup {
-                eachRun {
-                    nonResizeableApp.launchViaIntent(wmHelper)
-                    splitScreenApp.launchViaIntent(wmHelper)
-                    device.launchSplitScreen(wmHelper)
-                }
-            }
-            transitions {
-                device.reopenAppFromOverview(wmHelper)
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(DOCKED_STACK_DIVIDER_COMPONENT, LAUNCHER_COMPONENT, LETTERBOX_COMPONENT,
-            TOAST_COMPONENT, splitScreenApp.component, nonResizeableApp.component,
-            FlickerComponentName.SPLASH_SCREEN,
-            FlickerComponentName.SNAPSHOT)
-
-    @Before
-    override fun setup() {
-        super.setup()
-        setSupportsNonResizableMultiWindow(instrumentation, -1)
-    }
-
-    @After
-    override fun teardown() {
-        super.teardown()
-        resetMultiWindowConfig(instrumentation)
-    }
-
-    @Presubmit
-    @Test
-    fun resizableAppLayerBecomesInvisible() {
-        testSpec.assertLayers {
-            this.isVisible(splitScreenApp.component)
-                    .then()
-                    .isInvisible(splitScreenApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun nonResizableAppLayerBecomesVisible() {
-        testSpec.assertLayers {
-            this.isInvisible(nonResizeableApp.component)
-                    .then()
-                    .isVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun resizableAppWindowBecomesInvisible() {
-        testSpec.assertWm {
-            // when the activity gets PAUSED the window may still be marked as visible
-            // it will be updated in the next log entry. This occurs because we record 1x
-            // per frame, thus ignore activity check here
-            this.isAppWindowVisible(splitScreenApp.component)
-                    .then()
-                    // immediately after the window (after onResume and before perform relayout)
-                    // the activity is invisible. This may or not be logged, since we record 1x
-                    // per frame, thus ignore activity check here
-                    .isAppWindowInvisible(splitScreenApp.component)
-        }
-    }
-
-    @FlakyTest
-    @Test
-    fun nonResizableAppWindowBecomesVisible() {
-        testSpec.assertWm {
-            this.isAppWindowInvisible(nonResizeableApp.component)
-                    .then()
-                    .isAppWindowVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerNotExistsAtEnd() = testSpec.dockedStackDividerNotExistsAtEnd()
-
-    @Presubmit
-    @Test
-    fun onlyNonResizableAppWindowIsVisibleAtEnd() {
-        testSpec.assertWmEnd {
-            isAppWindowInvisible(splitScreenApp.component)
-            isAppWindowVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0)) // b/178685668
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentSupportNonResizable.kt
deleted file mode 100644
index 6ac8683..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentSupportNonResizable.kt
+++ /dev/null
@@ -1,155 +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.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.reopenAppFromOverview
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.DOCKED_STACK_DIVIDER_COMPONENT
-import com.android.wm.shell.flicker.dockedStackDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setSupportsNonResizableMultiWindow
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.After
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test launch non-resizable activity via recent overview in split screen mode. When the device
- * supports non-resizable in multi window, it should show the non-resizable app in split screen.
- * To run this test: `atest WMShellFlickerTests:LegacySplitScreenFromRecentSupportNonResizable`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class LegacySplitScreenFromRecentSupportNonResizable(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            cleanSetup(this)
-            setup {
-                eachRun {
-                    nonResizeableApp.launchViaIntent(wmHelper)
-                    splitScreenApp.launchViaIntent(wmHelper)
-                    device.launchSplitScreen(wmHelper)
-                }
-            }
-            transitions {
-                device.reopenAppFromOverview(wmHelper)
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(DOCKED_STACK_DIVIDER_COMPONENT, LAUNCHER_COMPONENT, LETTERBOX_COMPONENT,
-            TOAST_COMPONENT, splitScreenApp.component, nonResizeableApp.component,
-            FlickerComponentName.SPLASH_SCREEN,
-            FlickerComponentName.SNAPSHOT)
-
-    @Before
-    override fun setup() {
-        super.setup()
-        setSupportsNonResizableMultiWindow(instrumentation, 1)
-    }
-
-    @After
-    override fun teardown() {
-        super.teardown()
-        resetMultiWindowConfig(instrumentation)
-    }
-
-    @Presubmit
-    @Test
-    fun nonResizableAppLayerBecomesVisible() {
-        testSpec.assertLayers {
-            this.isInvisible(nonResizeableApp.component)
-                    .then()
-                    .isVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun nonResizableAppWindowBecomesVisible() {
-        testSpec.assertWm {
-            // when the app is launched, first the activity becomes visible, then the
-            // SnapshotStartingWindow appears and then the app window becomes visible.
-            // Because we log WM once per frame, sometimes the activity and the window
-            // become visible in the same entry, sometimes not, thus it is not possible to
-            // assert the visibility of the activity here
-            this.isAppWindowInvisible(nonResizeableApp.component)
-                    .then()
-                    // during re-parenting, the window may disappear and reappear from the
-                    // trace, this occurs because we log only 1x per frame
-                    .notContains(nonResizeableApp.component, isOptional = true)
-                    .then()
-                    // if the window reappears after re-parenting it will most likely not
-                    // be visible in the first log entry (because we log only 1x per frame)
-                    .isAppWindowInvisible(nonResizeableApp.component, isOptional = true)
-                    .then()
-                    .isAppWindowVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerIsVisibleAtEnd() = testSpec.dockedStackDividerIsVisibleAtEnd()
-
-    @Presubmit
-    @Test
-    fun bothAppsWindowsAreVisibleAtEnd() {
-        testSpec.assertWmEnd {
-            isAppWindowVisible(splitScreenApp.component)
-            isAppWindowVisible(nonResizeableApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0)) // b/178685668
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenRotateTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenRotateTransition.kt
deleted file mode 100644
index b01f41c..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenRotateTransition.kt
+++ /dev/null
@@ -1,47 +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.wm.shell.flicker.legacysplitscreen
-
-import android.view.Surface
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.openQuickStepAndClearRecentAppsFromOverview
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-
-abstract class LegacySplitScreenRotateTransition(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            setup {
-                eachRun {
-                    device.wakeUpAndGoToHomeScreen()
-                    device.openQuickStepAndClearRecentAppsFromOverview(wmHelper)
-                    secondaryApp.launchViaIntent(wmHelper)
-                    splitScreenApp.launchViaIntent(wmHelper)
-                }
-            }
-            teardown {
-                eachRun {
-                    splitScreenApp.exit(wmHelper)
-                    secondaryApp.exit(wmHelper)
-                    this.setRotation(Surface.ROTATION_0)
-                }
-            }
-        }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncher.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncher.kt
deleted file mode 100644
index fb1004b..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncher.kt
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
-import com.android.server.wm.flicker.helpers.exitSplitScreen
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.openQuickStepAndClearRecentAppsFromOverview
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.dockedStackDividerBecomesInvisible
-import com.android.wm.shell.flicker.helpers.SimpleAppHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:LegacySplitScreenToLauncher`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class LegacySplitScreenToLauncher(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-    private val testApp = SimpleAppHelper(instrumentation)
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            setup {
-                test {
-                    device.wakeUpAndGoToHomeScreen()
-                    device.openQuickStepAndClearRecentAppsFromOverview(wmHelper)
-                }
-                eachRun {
-                    testApp.launchViaIntent(wmHelper)
-                    this.setRotation(testSpec.endRotation)
-                    device.launchSplitScreen(wmHelper)
-                    device.waitForIdle()
-                }
-            }
-            teardown {
-                eachRun {
-                    testApp.exit(wmHelper)
-                }
-            }
-            transitions {
-                device.exitSplitScreen()
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(LAUNCHER_COMPONENT, FlickerComponentName.SPLASH_SCREEN,
-            FlickerComponentName.SNAPSHOT)
-
-    @Presubmit
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
-    @FlakyTest
-    @Test
-    fun dockedStackDividerBecomesInvisible() = testSpec.dockedStackDividerBecomesInvisible()
-
-    @FlakyTest
-    @Test
-    fun layerBecomesInvisible() {
-        testSpec.assertLayers {
-            this.isVisible(testApp.component)
-                    .then()
-                    .isInvisible(testApp.component)
-        }
-    }
-
-    @FlakyTest
-    @Test
-    fun focusDoesNotChange() {
-        testSpec.assertEventLog {
-            this.focusDoesNotChange()
-        }
-    }
-
-    @Presubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            // b/161435597 causes the test not to work on 90 degrees
-            return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt
deleted file mode 100644
index a4a1f61..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.legacysplitscreen
-
-import android.app.Instrumentation
-import android.content.Context
-import android.support.test.launcherhelper.LauncherStrategyFactory
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.FlickerBuilderProvider
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.openQuickStepAndClearRecentAppsFromOverview
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.helpers.BaseAppHelper.Companion.isShellTransitionsEnabled
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.getDevEnableNonResizableMultiWindow
-import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.setDevEnableNonResizableMultiWindow
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.After
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
-import org.junit.Before
-import org.junit.Test
-
-abstract class LegacySplitScreenTransition(protected val testSpec: FlickerTestParameter) {
-    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-    protected val context: Context = instrumentation.context
-    protected val splitScreenApp = SplitScreenHelper.getPrimary(instrumentation)
-    protected val secondaryApp = SplitScreenHelper.getSecondary(instrumentation)
-    protected val nonResizeableApp = SplitScreenHelper.getNonResizeable(instrumentation)
-    protected val LAUNCHER_COMPONENT = FlickerComponentName("",
-            LauncherStrategyFactory.getInstance(instrumentation)
-                    .launcherStrategy.supportedLauncherPackage)
-    private var prevDevEnableNonResizableMultiWindow = 0
-
-    @Before
-    open fun setup() {
-        // Only run legacy split tests when the system is using legacy split screen.
-        assumeTrue(SplitScreenHelper.isUsingLegacySplit())
-        // Legacy split is having some issue with Shell transition, and will be deprecated soon.
-        assumeFalse(isShellTransitionsEnabled())
-        prevDevEnableNonResizableMultiWindow = getDevEnableNonResizableMultiWindow(context)
-        if (prevDevEnableNonResizableMultiWindow != 0) {
-            // Turn off the development option
-            setDevEnableNonResizableMultiWindow(context, 0)
-        }
-    }
-
-    @After
-    open fun teardown() {
-        setDevEnableNonResizableMultiWindow(context, prevDevEnableNonResizableMultiWindow)
-    }
-
-    /**
-     * List of windows that are ignored when verifying that visible elements appear on 2
-     * consecutive entries in the trace.
-     *
-     * b/182720234
-     */
-    open val ignoredWindows: List<FlickerComponentName> = listOf(
-        FlickerComponentName.SPLASH_SCREEN,
-        FlickerComponentName.SNAPSHOT)
-
-    protected open val transition: FlickerBuilder.() -> Unit
-        get() = {
-            setup {
-                eachRun {
-                    device.wakeUpAndGoToHomeScreen()
-                    device.openQuickStepAndClearRecentAppsFromOverview(wmHelper)
-                    secondaryApp.launchViaIntent(wmHelper)
-                    splitScreenApp.launchViaIntent(wmHelper)
-                    this.setRotation(testSpec.startRotation)
-                }
-            }
-            teardown {
-                eachRun {
-                    secondaryApp.exit(wmHelper)
-                    splitScreenApp.exit(wmHelper)
-                    this.setRotation(Surface.ROTATION_0)
-                }
-            }
-        }
-
-    @FlickerBuilderProvider
-    fun buildFlicker(): FlickerBuilder {
-        return FlickerBuilder(instrumentation).apply {
-            transition(this)
-        }
-    }
-
-    internal open val cleanSetup: FlickerBuilder.() -> Unit
-        get() = {
-            setup {
-                eachRun {
-                    device.wakeUpAndGoToHomeScreen()
-                    device.openQuickStepAndClearRecentAppsFromOverview(wmHelper)
-                    this.setRotation(testSpec.startRotation)
-                }
-            }
-            teardown {
-                eachRun {
-                    nonResizeableApp.exit(wmHelper)
-                    splitScreenApp.exit(wmHelper)
-                    device.pressHome()
-                    this.setRotation(Surface.ROTATION_0)
-                }
-            }
-        }
-
-    @FlakyTest(bugId = 178447631)
-    @Test
-    open fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertWm {
-            this.visibleWindowsShownMoreThanOneConsecutiveEntry(ignoredWindows)
-        }
-    }
-
-    @FlakyTest(bugId = 178447631)
-    @Test
-    open fun visibleLayersShownMoreThanOneConsecutiveEntry() {
-        testSpec.assertLayers {
-            this.visibleLayersShownMoreThanOneConsecutiveEntry(ignoredWindows)
-        }
-    }
-
-    companion object {
-        internal val LIVE_WALLPAPER_COMPONENT = FlickerComponentName("",
-            "com.breel.wallpapers18.soundviz.wallpaper.variations.SoundVizWallpaperV2")
-        internal val LETTERBOX_COMPONENT = FlickerComponentName("", "Letterbox")
-        internal val TOAST_COMPONENT = FlickerComponentName("", "Toast")
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OWNERS b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OWNERS
deleted file mode 100644
index 8446b37..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# window manager > wm shell > Split Screen
-# Bug component: 928697
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreen.kt
deleted file mode 100644
index 087b21c..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreen.kt
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.traces.common.FlickerComponentName
-import com.android.wm.shell.flicker.appPairsDividerBecomesVisible
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:OpenAppToLegacySplitScreen`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class OpenAppToLegacySplitScreen(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                device.launchSplitScreen(wmHelper)
-                wmHelper.waitForAppTransitionIdle()
-            }
-        }
-
-    override val ignoredWindows: List<FlickerComponentName>
-        get() = listOf(LAUNCHER_COMPONENT, splitScreenApp.component,
-            FlickerComponentName.SPLASH_SCREEN,
-            FlickerComponentName.SNAPSHOT)
-
-    @FlakyTest
-    @Test
-    fun appWindowBecomesVisible() {
-        testSpec.assertWm {
-            this.isAppWindowInvisible(splitScreenApp.component)
-                    .then()
-                    .isAppWindowVisible(splitScreenApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    @Presubmit
-    @Test
-    fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
-    @Presubmit
-    @Test
-    fun appPairsDividerBecomesVisible() = testSpec.appPairsDividerBecomesVisible()
-
-    @FlakyTest
-    @Test
-    fun layerBecomesVisible() {
-        testSpec.assertLayers {
-            this.isInvisible(splitScreenApp.component)
-                    .then()
-                    .isVisible(splitScreenApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun focusChanges() {
-        testSpec.assertEventLog {
-            this.focusChanges(splitScreenApp.`package`,
-                    "recents_animation_input_consumer", "NexusLauncherActivity")
-        }
-    }
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0) // bugId = 179116910
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt
deleted file mode 100644
index e2da1a4..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.legacysplitscreen
-
-import android.util.Rational
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import androidx.test.uiautomator.By
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.entireScreenCovered
-import com.android.server.wm.flicker.helpers.ImeAppHelper
-import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.resizeSplitScreen
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.navBarLayerIsVisible
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.server.wm.traces.common.region.Region
-import com.android.server.wm.traces.parser.toFlickerComponent
-import com.android.wm.shell.flicker.DOCKED_STACK_DIVIDER_COMPONENT
-import com.android.wm.shell.flicker.helpers.SimpleAppHelper
-import com.android.wm.shell.flicker.testapp.Components
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test split screen resizing window transitions.
- * To run this test: `atest WMShellFlickerTests:ResizeLegacySplitScreen`
- *
- * Currently it runs only in 0 degrees because of b/156100803
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 159096424)
-@Group2
-class ResizeLegacySplitScreen(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenTransition(testSpec) {
-    private val testAppTop = SimpleAppHelper(instrumentation)
-    private val testAppBottom = ImeAppHelper(instrumentation)
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            setup {
-                eachRun {
-                    device.wakeUpAndGoToHomeScreen()
-                    this.setRotation(testSpec.startRotation)
-                    this.launcherStrategy.clearRecentAppsFromOverview()
-                    testAppBottom.launchViaIntent(wmHelper)
-                    device.pressHome()
-                    testAppTop.launchViaIntent(wmHelper)
-                    device.waitForIdle()
-                    device.launchSplitScreen(wmHelper)
-                    val snapshot =
-                        device.findObject(By.res(device.launcherPackageName, "snapshot"))
-                    snapshot.click()
-                    testAppBottom.openIME(device)
-                    device.pressBack()
-                    device.resizeSplitScreen(startRatio)
-                }
-            }
-            teardown {
-                eachRun {
-                    testAppTop.exit(wmHelper)
-                    testAppBottom.exit(wmHelper)
-                }
-            }
-            transitions {
-                device.resizeSplitScreen(stopRatio)
-            }
-        }
-
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @FlakyTest(bugId = 156223549)
-    @Test
-    fun topAppWindowIsAlwaysVisible() {
-        testSpec.assertWm {
-            this.isAppWindowVisible(Components.SimpleActivity.COMPONENT.toFlickerComponent())
-        }
-    }
-
-    @FlakyTest(bugId = 156223549)
-    @Test
-    fun bottomAppWindowIsAlwaysVisible() {
-        testSpec.assertWm {
-            this.isAppWindowVisible(Components.ImeActivity.COMPONENT.toFlickerComponent())
-        }
-    }
-
-    @Test
-    fun navBarLayerIsVisible() = testSpec.navBarLayerIsVisible()
-
-    @Test
-    fun statusBarLayerIsVisible() = testSpec.statusBarLayerIsVisible()
-
-    @Test
-    fun entireScreenCovered() = testSpec.entireScreenCovered()
-
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Test
-    fun topAppLayerIsAlwaysVisible() {
-        testSpec.assertLayers {
-            this.isVisible(Components.SimpleActivity.COMPONENT.toFlickerComponent())
-        }
-    }
-
-    @Test
-    fun bottomAppLayerIsAlwaysVisible() {
-        testSpec.assertLayers {
-            this.isVisible(Components.ImeActivity.COMPONENT.toFlickerComponent())
-        }
-    }
-
-    @Test
-    fun dividerLayerIsAlwaysVisible() {
-        testSpec.assertLayers {
-            this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT)
-        }
-    }
-
-    @FlakyTest
-    @Test
-    fun appsStartingBounds() {
-        testSpec.assertLayersStart {
-            val displayBounds = WindowUtils.displayBounds
-            val dividerBounds =
-                layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region.bounds
-
-            val topAppBounds = Region.from(0, 0, dividerBounds.right,
-                dividerBounds.top + WindowUtils.dockedStackDividerInset)
-            val bottomAppBounds = Region.from(0,
-                dividerBounds.bottom - WindowUtils.dockedStackDividerInset,
-                displayBounds.right,
-                displayBounds.bottom - WindowUtils.navigationBarFrameHeight)
-            visibleRegion(Components.SimpleActivity.COMPONENT.toFlickerComponent())
-                .coversExactly(topAppBounds)
-            visibleRegion(Components.ImeActivity.COMPONENT.toFlickerComponent())
-                .coversExactly(bottomAppBounds)
-        }
-    }
-
-    @FlakyTest
-    @Test
-    fun appsEndingBounds() {
-        testSpec.assertLayersStart {
-            val displayBounds = WindowUtils.displayBounds
-            val dividerBounds =
-                layer(DOCKED_STACK_DIVIDER_COMPONENT).visibleRegion.region.bounds
-
-            val topAppBounds = Region.from(0, 0, dividerBounds.right,
-                dividerBounds.top + WindowUtils.dockedStackDividerInset)
-            val bottomAppBounds = Region.from(0,
-                dividerBounds.bottom - WindowUtils.dockedStackDividerInset,
-                displayBounds.right,
-                displayBounds.bottom - WindowUtils.navigationBarFrameHeight)
-
-            visibleRegion(Components.SimpleActivity.COMPONENT.toFlickerComponent())
-                .coversExactly(topAppBounds)
-            visibleRegion(Components.ImeActivity.COMPONENT.toFlickerComponent())
-                .coversExactly(bottomAppBounds)
-        }
-    }
-
-    @Test
-    fun focusDoesNotChange() {
-        testSpec.assertEventLog {
-            focusDoesNotChange()
-        }
-    }
-
-    companion object {
-        private val startRatio = Rational(1, 3)
-        private val stopRatio = Rational(2, 3)
-
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
-                .map {
-                    val description = (startRatio.toString().replace("/", "-") + "_to_" +
-                        stopRatio.toString().replace("/", "-"))
-                    val newName = "${FlickerTestParameter.defaultName(it)}_$description"
-                    FlickerTestParameter(it.config, nameOverride = newName)
-                }
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppAndEnterSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppAndEnterSplitScreen.kt
deleted file mode 100644
index d703ea0..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppAndEnterSplitScreen.kt
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.wm.shell.flicker.dockedStackDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test dock activity to primary split screen and rotate
- * To run this test: `atest WMShellFlickerTests:RotateOneLaunchedAppAndEnterSplitScreen`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class RotateOneLaunchedAppAndEnterSplitScreen(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenRotateTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                device.launchSplitScreen(wmHelper)
-                this.setRotation(testSpec.startRotation)
-            }
-        }
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerIsVisibleAtEnd() = testSpec.dockedStackDividerIsVisibleAtEnd()
-
-    @Presubmit
-    @Test
-    fun dockedStackPrimaryBoundsIsVisibleAtEnd() =
-        testSpec.dockedStackPrimaryBoundsIsVisibleAtEnd(testSpec.startRotation,
-            splitScreenApp.component)
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @FlakyTest
-    @Test
-    fun appWindowBecomesVisible() {
-        testSpec.assertWm {
-            this.isAppWindowInvisible(splitScreenApp.component)
-                    .then()
-                    .isAppWindowVisible(splitScreenApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                    supportedRotations = listOf(Surface.ROTATION_0)) // b/178685668
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppInSplitScreenMode.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppInSplitScreenMode.kt
deleted file mode 100644
index 6b18839..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateOneLaunchedAppInSplitScreenMode.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.wm.shell.flicker.dockedStackDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Rotate
- * To run this test: `atest WMShellFlickerTests:RotateOneLaunchedAppInSplitScreenMode`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class RotateOneLaunchedAppInSplitScreenMode(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenRotateTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                this.setRotation(testSpec.startRotation)
-                device.launchSplitScreen(wmHelper)
-            }
-        }
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerIsVisibleAtEnd() = testSpec.dockedStackDividerIsVisibleAtEnd()
-
-    @Presubmit
-    @Test
-    fun dockedStackPrimaryBoundsIsVisibleAtEnd() = testSpec.dockedStackPrimaryBoundsIsVisibleAtEnd(
-        testSpec.startRotation, splitScreenApp.component)
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @FlakyTest
-    @Test
-    fun appWindowBecomesVisible() {
-        testSpec.assertWm {
-            this.isAppWindowInvisible(splitScreenApp.component)
-                    .then()
-                    .isAppWindowVisible(splitScreenApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0)) // b/178685668
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppAndEnterSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppAndEnterSplitScreen.kt
deleted file mode 100644
index acd658b..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppAndEnterSplitScreen.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.reopenAppFromOverview
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.wm.shell.flicker.dockedStackDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.dockedStackSecondaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:RotateTwoLaunchedAppAndEnterSplitScreen`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class RotateTwoLaunchedAppAndEnterSplitScreen(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenRotateTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            transitions {
-                this.setRotation(testSpec.startRotation)
-                device.launchSplitScreen(wmHelper)
-                device.reopenAppFromOverview(wmHelper)
-            }
-        }
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerIsVisibleAtEnd() = testSpec.dockedStackDividerIsVisibleAtEnd()
-
-    @Presubmit
-    @Test
-    fun dockedStackPrimaryBoundsIsVisibleAtEnd() =
-        testSpec.dockedStackPrimaryBoundsIsVisibleAtEnd(testSpec.startRotation,
-            splitScreenApp.component)
-
-    @Presubmit
-    @Test
-    fun dockedStackSecondaryBoundsIsVisibleAtEnd() =
-        testSpec.dockedStackSecondaryBoundsIsVisibleAtEnd(testSpec.startRotation,
-            secondaryApp.component)
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @Presubmit
-    @Test
-    fun appWindowBecomesVisible() {
-        testSpec.assertWm {
-            // when the app is launched, first the activity becomes visible, then the
-            // SnapshotStartingWindow appears and then the app window becomes visible.
-            // Because we log WM once per frame, sometimes the activity and the window
-            // become visible in the same entry, sometimes not, thus it is not possible to
-            // assert the visibility of the activity here
-            this.isAppWindowInvisible(secondaryApp.component)
-                    .then()
-                    // during re-parenting, the window may disappear and reappear from the
-                    // trace, this occurs because we log only 1x per frame
-                    .notContains(secondaryApp.component, isOptional = true)
-                    .then()
-                    // if the window reappears after re-parenting it will most likely not
-                    // be visible in the first log entry (because we log only 1x per frame)
-                    .isAppWindowInvisible(secondaryApp.component, isOptional = true)
-                    .then()
-                    .isAppWindowVisible(secondaryApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0)) // b/178685668
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppInSplitScreenMode.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppInSplitScreenMode.kt
deleted file mode 100644
index b40be8b..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/RotateTwoLaunchedAppInSplitScreenMode.kt
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.legacysplitscreen
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group2
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.reopenAppFromOverview
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
-import com.android.server.wm.flicker.navBarWindowIsVisible
-import com.android.server.wm.flicker.statusBarLayerRotatesScales
-import com.android.server.wm.flicker.statusBarWindowIsVisible
-import com.android.wm.shell.flicker.dockedStackDividerIsVisibleAtEnd
-import com.android.wm.shell.flicker.dockedStackPrimaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.dockedStackSecondaryBoundsIsVisibleAtEnd
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test open app to split screen.
- * To run this test: `atest WMShellFlickerTests:RotateTwoLaunchedAppInSplitScreenMode`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group2
-class RotateTwoLaunchedAppInSplitScreenMode(
-    testSpec: FlickerTestParameter
-) : LegacySplitScreenRotateTransition(testSpec) {
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            super.transition(this)
-            setup {
-                eachRun {
-                    device.launchSplitScreen(wmHelper)
-                    device.reopenAppFromOverview(wmHelper)
-                    this.setRotation(testSpec.startRotation)
-                }
-            }
-            transitions {
-                this.setRotation(testSpec.startRotation)
-            }
-        }
-
-    @Presubmit
-    @Test
-    fun dockedStackDividerIsVisibleAtEnd() = testSpec.dockedStackDividerIsVisibleAtEnd()
-
-    @Presubmit
-    @Test
-    fun dockedStackPrimaryBoundsIsVisibleAtEnd() =
-        testSpec.dockedStackPrimaryBoundsIsVisibleAtEnd(testSpec.startRotation,
-            splitScreenApp.component)
-
-    @Presubmit
-    @Test
-    fun dockedStackSecondaryBoundsIsVisibleAtEnd() =
-        testSpec.dockedStackSecondaryBoundsIsVisibleAtEnd(testSpec.startRotation,
-            secondaryApp.component)
-
-    @Presubmit
-    @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
-
-    @FlakyTest(bugId = 206753786)
-    @Test
-    fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
-
-    @FlakyTest
-    @Test
-    fun appWindowBecomesVisible() {
-        testSpec.assertWm {
-            this.isAppWindowInvisible(secondaryApp.component)
-                    .then()
-                    .isAppWindowVisible(secondaryApp.component)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun navBarWindowIsVisible() = testSpec.navBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    fun statusBarWindowIsVisible() = testSpec.statusBarWindowIsVisible()
-
-    @Presubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-            super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-            super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    companion object {
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
-                supportedRotations = listOf(Surface.ROTATION_0)) // b/178685668
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
new file mode 100644
index 0000000..e7d641e9
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip
+
+import androidx.test.filters.RequiresDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.annotation.Group3
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import org.junit.Assume
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test entering pip from an app via [onUserLeaveHint] and by navigating to home.
+ *
+ * To run this test: `atest WMShellFlickerTests:EnterPipOnUserLeaveHintTest`
+ *
+ * Actions:
+ *     Launch an app in full screen
+ *     Select "Via code behind" radio button
+ *     Press Home button to put [pipApp] in pip mode
+ *
+ * Notes:
+ *     1. All assertions are inherited from [EnterPipTest]
+ *     2. Part of the test setup occurs automatically via
+ *        [com.android.server.wm.flicker.TransitionRunnerWithRules],
+ *        including configuring navigation mode, initial orientation and ensuring no
+ *        apps are running before setup
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Group3
+class EnterPipOnUserLeaveHintTest(testSpec: FlickerTestParameter) : EnterPipTest(testSpec) {
+    protected val taplInstrumentation = LauncherInstrumentation()
+    /**
+     * Defines the transition used to run the test
+     */
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            setupAndTeardown(this)
+            setup {
+                eachRun {
+                    pipApp.launchViaIntent(wmHelper)
+                    pipApp.enableEnterPipOnUserLeaveHint()
+                }
+            }
+            teardown {
+                eachRun {
+                    pipApp.exit(wmHelper)
+                }
+            }
+            transitions {
+                taplInstrumentation.goHome()
+            }
+        }
+
+    override fun pipAppLayerAlwaysVisible() {
+        if (!testSpec.isGesturalNavigation) super.pipAppLayerAlwaysVisible() else {
+            // pip layer in gesture nav will disappear during transition
+            testSpec.assertLayers {
+                this.isVisible(pipApp.component)
+                    .then().isInvisible(pipApp.component)
+                    .then().isVisible(pipApp.component)
+            }
+        }
+    }
+
+    override fun pipLayerReduces() {
+        // in gestural nav the pip enters through alpha animation
+        Assume.assumeFalse(testSpec.isGesturalNavigation)
+        super.pipLayerReduces()
+    }
+
+    override fun focusChanges() {
+        // in gestural nav the focus goes to different activity on swipe up
+        Assume.assumeFalse(testSpec.isGesturalNavigation)
+        super.focusChanges()
+    }
+
+    override fun pipLayerRemainInsideVisibleBounds() {
+        if (!testSpec.isGesturalNavigation) super.pipLayerRemainInsideVisibleBounds() else {
+            // pip layer in gesture nav will disappear during transition
+            testSpec.assertLayersStart {
+                this.visibleRegion(pipApp.component).coversAtMost(displayBounds)
+            }
+            testSpec.assertLayersEnd {
+                this.visibleRegion(pipApp.component).coversAtMost(displayBounds)
+            }
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index 0640ac5..b4267ff 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -43,7 +43,7 @@
  *
  * Notes:
  *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
- *        are inherited [PipTransition]
+ *        are inherited from [PipTransition]
  *     2. Part of the test setup occurs automatically via
  *        [com.android.server.wm.flicker.TransitionRunnerWithRules],
  *        including configuring navigation mode, initial orientation and ensuring no
@@ -54,7 +54,7 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group3
-class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) {
+open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) {
 
     /**
      * Defines the transition used to run the test
@@ -98,7 +98,7 @@
      */
     @Presubmit
     @Test
-    fun pipAppLayerAlwaysVisible() {
+    open fun pipAppLayerAlwaysVisible() {
         testSpec.assertLayers {
             this.isVisible(pipApp.component)
         }
@@ -122,7 +122,7 @@
      */
     @Presubmit
     @Test
-    fun pipLayerRemainInsideVisibleBounds() {
+    open fun pipLayerRemainInsideVisibleBounds() {
         testSpec.assertLayersVisibleRegion(pipApp.component) {
             coversAtMost(displayBounds)
         }
@@ -133,7 +133,7 @@
      */
     @Presubmit
     @Test
-    fun pipLayerReduces() {
+    open fun pipLayerReduces() {
         val layerName = pipApp.component.toLayerName()
         testSpec.assertLayers {
             val pipLayerList = this.layers { it.name.contains(layerName) && it.isVisible }
@@ -175,7 +175,7 @@
      */
     @Presubmit
     @Test
-    fun focusChanges() {
+    open fun focusChanges() {
         testSpec.assertEventLog {
             this.focusChanges(pipApp.`package`, "NexusLauncherActivity")
         }
@@ -192,8 +192,10 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
-                    repetitions = 3)
+                .getConfigNonRotationTests(
+                    supportedRotations = listOf(Surface.ROTATION_0),
+                    repetitions = 3
+                )
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
index 37e93443..c6a705d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
@@ -80,7 +80,17 @@
     /** {@inheritDoc}  */
     @FlakyTest(bugId = 206753786)
     @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
+    override fun statusBarLayerRotatesScales() {
+        Assume.assumeFalse(isShellTransitionsEnabled)
+        super.statusBarLayerRotatesScales()
+    }
+
+    @Presubmit
+    @Test
+    fun statusBarLayerRotatesScales_ShellTransit() {
+        Assume.assumeTrue(isShellTransitionsEnabled)
+        super.statusBarLayerRotatesScales()
+    }
 
     /** {@inheritDoc}  */
     @FlakyTest(bugId = 197726610)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
index 1a21d32..fe51228 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
@@ -16,7 +16,7 @@
 
 package com.android.wm.shell.flicker.pip
 
-import androidx.test.filters.FlakyTest
+import android.platform.test.annotations.Presubmit
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -35,7 +35,6 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Group4
-@FlakyTest(bugId = 217777115)
 class PipKeyboardTestShellTransit(testSpec: FlickerTestParameter) : PipKeyboardTest(testSpec) {
 
     @Before
@@ -43,7 +42,7 @@
         Assume.assumeTrue(isShellTransitionsEnabled)
     }
 
-    @FlakyTest(bugId = 214452854)
+    @Presubmit
     @Test
     override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt
deleted file mode 100644
index 21175a0..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.flicker.pip
-
-import android.platform.test.annotations.Presubmit
-import android.view.Surface
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.RequiresDevice
-import com.android.server.wm.flicker.FlickerParametersRunnerFactory
-import com.android.server.wm.flicker.FlickerTestParameter
-import com.android.server.wm.flicker.FlickerTestParameterFactory
-import com.android.server.wm.flicker.annotation.Group4
-import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.launchSplitScreen
-import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
-import com.android.wm.shell.flicker.helpers.BaseAppHelper.Companion.isShellTransitionsEnabled
-import com.android.wm.shell.flicker.helpers.FixedAppHelper
-import com.android.wm.shell.flicker.helpers.ImeAppHelper
-import com.android.wm.shell.flicker.helpers.SplitScreenHelper
-import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
-import org.junit.Before
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-/**
- * Test Pip with split-screen.
- * To run this test: `atest WMShellFlickerTests:PipLegacySplitScreenTest`
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Group4
-class PipLegacySplitScreenTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) {
-    private val imeApp = ImeAppHelper(instrumentation)
-    private val testApp = FixedAppHelper(instrumentation)
-
-    @Before
-    open fun setup() {
-        // Only run legacy split tests when the system is using legacy split screen.
-        assumeTrue(SplitScreenHelper.isUsingLegacySplit())
-        // Legacy split is having some issue with Shell transition, and will be deprecated soon.
-        assumeFalse(isShellTransitionsEnabled())
-    }
-
-    override val transition: FlickerBuilder.() -> Unit
-        get() = {
-            setup {
-                test {
-                    removeAllTasksButHome()
-                    device.wakeUpAndGoToHomeScreen()
-                    pipApp.launchViaIntent(stringExtras = mapOf(EXTRA_ENTER_PIP to "true"),
-                        wmHelper = wmHelper)
-                }
-            }
-            transitions {
-                testApp.launchViaIntent(wmHelper)
-                device.launchSplitScreen(wmHelper)
-                imeApp.launchViaIntent(wmHelper)
-            }
-            teardown {
-                eachRun {
-                    imeApp.exit(wmHelper)
-                    testApp.exit(wmHelper)
-                }
-                test {
-                    removeAllTasksButHome()
-                }
-            }
-        }
-
-    /** {@inheritDoc}  */
-    @FlakyTest(bugId = 206753786)
-    @Test
-    override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
-
-    @FlakyTest(bugId = 161435597)
-    @Test
-    fun pipWindowInsideDisplayBounds() {
-        testSpec.assertWmVisibleRegion(pipApp.component) {
-            coversAtMost(displayBounds)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun bothAppWindowsVisible() {
-        testSpec.assertWmEnd {
-            isAppWindowVisible(testApp.component)
-            isAppWindowVisible(imeApp.component)
-            doNotOverlap(testApp.component, imeApp.component)
-        }
-    }
-
-    @FlakyTest(bugId = 161435597)
-    @Test
-    fun pipLayerInsideDisplayBounds() {
-        testSpec.assertLayersVisibleRegion(pipApp.component) {
-            coversAtMost(displayBounds)
-        }
-    }
-
-    @Presubmit
-    @Test
-    fun bothAppLayersVisible() {
-        testSpec.assertLayersEnd {
-            visibleRegion(testApp.component).coversAtMost(displayBounds)
-            visibleRegion(imeApp.component).coversAtMost(displayBounds)
-        }
-    }
-
-    @FlakyTest(bugId = 161435597)
-    @Test
-    override fun entireScreenCovered() = super.entireScreenCovered()
-
-    companion object {
-        const val TEST_REPETITIONS = 2
-
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): Collection<FlickerTestParameter> {
-            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                supportedRotations = listOf(Surface.ROTATION_0),
-                repetitions = TEST_REPETITIONS
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index c1ee1a7..4618fb3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -27,12 +27,10 @@
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.entireScreenCovered
 import com.android.server.wm.flicker.helpers.WindowUtils
-import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.navBarLayerRotatesAndScales
 import com.android.server.wm.flicker.statusBarLayerRotatesScales
 import com.android.wm.shell.flicker.helpers.FixedAppHelper
-import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -141,14 +139,6 @@
     @Presubmit
     @Test
     fun pipLayerRotates_StartingBounds() {
-        Assume.assumeFalse(isShellTransitionsEnabled)
-        pipLayerRotates_StartingBounds_internal()
-    }
-
-    @FlakyTest(bugId = 228024285)
-    @Test
-    fun pipLayerRotates_StartingBounds_ShellTransit() {
-        Assume.assumeTrue(isShellTransitionsEnabled)
         pipLayerRotates_StartingBounds_internal()
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
new file mode 100644
index 0000000..702710c
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen
+
+import android.platform.test.annotations.Presubmit
+import android.view.WindowManagerPolicyConstants
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.FlickerTestParameterFactory
+import com.android.server.wm.flicker.annotation.Group1
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.wm.shell.flicker.appWindowBecomesVisible
+import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import com.android.wm.shell.flicker.layerBecomesVisible
+import com.android.wm.shell.flicker.layerIsVisibleAtEnd
+import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisible
+import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
+import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test enter split screen by dragging app icon from all apps.
+ * This test is only for large screen devices.
+ *
+ * To run this test: `atest WMShellFlickerTests:EnterSplitScreenByDragFromAllApps`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Group1
+class EnterSplitScreenByDragFromAllApps(
+    testSpec: FlickerTestParameter
+) : SplitScreenBase(testSpec) {
+
+    @Before
+    open fun before() {
+        Assume.assumeTrue(taplInstrumentation.isTablet)
+    }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            super.transition(this)
+            setup {
+                eachRun {
+                    taplInstrumentation.goHome()
+                    primaryApp.launchViaIntent(wmHelper)
+                }
+            }
+            transitions {
+                taplInstrumentation.launchedAppState.taskbar
+                    .openAllApps()
+                    .getAppIcon(secondaryApp.appName)
+                    .dragToSplitscreen(secondaryApp.component.packageName,
+                        primaryApp.component.packageName)
+            }
+        }
+
+    @Presubmit
+    @Test
+    fun dividerBecomesVisible() = testSpec.splitScreenDividerBecomesVisible()
+
+    @Presubmit
+    @Test
+    fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component)
+
+    @Presubmit
+    @Test
+    fun secondaryAppLayerBecomesVisible() = testSpec.layerBecomesVisible(secondaryApp.component)
+
+    @Presubmit
+    @Test
+    fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd(
+        testSpec.endRotation, primaryApp.component, false /* splitLeftTop */)
+
+    @Presubmit
+    @Test
+    fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible(
+        testSpec.endRotation, secondaryApp.component, true /* splitLeftTop */)
+
+    @Presubmit
+    @Test
+    fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component)
+
+    @Presubmit
+    @Test
+    fun secondaryAppWindowBecomesVisible() =
+        testSpec.appWindowBecomesVisible(secondaryApp.component)
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTestParameter> {
+            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
+                repetitions = SplitScreenHelper.TEST_REPETITIONS,
+                // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
+                supportedNavigationModes =
+                    listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
new file mode 100644
index 0000000..7323d99
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen
+
+import android.platform.test.annotations.Presubmit
+import android.view.WindowManagerPolicyConstants
+import androidx.test.filters.RequiresDevice
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.Until
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.FlickerTestParameterFactory
+import com.android.server.wm.flicker.annotation.Group1
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+import com.android.wm.shell.flicker.layerBecomesVisible
+import com.android.wm.shell.flicker.layerIsVisibleAtEnd
+import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisible
+import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd
+import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test enter split screen by dragging app icon from notification.
+ * This test is only for large screen devices.
+ *
+ * To run this test: `atest WMShellFlickerTests:EnterSplitScreenByDragFromNotification`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Group1
+class EnterSplitScreenByDragFromNotification(
+    testSpec: FlickerTestParameter
+) : SplitScreenBase(testSpec) {
+
+    private val sendNotificationApp = SplitScreenHelper.getSendNotification(instrumentation)
+
+    @Before
+    fun before() {
+        Assume.assumeTrue(taplInstrumentation.isTablet)
+    }
+
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            super.transition(this)
+            setup {
+                eachRun {
+                    // Send a notification
+                    sendNotificationApp.launchViaIntent(wmHelper)
+                    val sendNotification = device.wait(
+                        Until.findObject(By.text("Send Notification")),
+                        SplitScreenHelper.TIMEOUT_MS
+                    )
+                    sendNotification?.click() ?: error("Send notification button not found")
+
+                    taplInstrumentation.goHome()
+                    primaryApp.launchViaIntent(wmHelper)
+                }
+            }
+            transitions {
+                SplitScreenHelper.dragFromNotificationToSplit(instrumentation, device, wmHelper)
+            }
+            teardown {
+                eachRun {
+                    sendNotificationApp.exit(wmHelper)
+                }
+            }
+        }
+
+    @Presubmit
+    @Test
+    fun dividerBecomesVisible() = testSpec.splitScreenDividerBecomesVisible()
+
+    @Presubmit
+    @Test
+    fun primaryAppLayerIsVisibleAtEnd() = testSpec.layerIsVisibleAtEnd(primaryApp.component)
+
+    @Presubmit
+    @Test
+    fun secondaryAppLayerBecomesVisible() =
+        testSpec.layerBecomesVisible(sendNotificationApp.component)
+
+    @Presubmit
+    @Test
+    fun primaryAppBoundsIsVisibleAtEnd() = testSpec.splitAppLayerBoundsIsVisibleAtEnd(
+        testSpec.endRotation, primaryApp.component, false /* splitLeftTop */
+    )
+
+    @Presubmit
+    @Test
+    fun secondaryAppBoundsBecomesVisible() = testSpec.splitAppLayerBoundsBecomesVisible(
+        testSpec.endRotation, sendNotificationApp.component, true /* splitLeftTop */
+    )
+
+    @Presubmit
+    @Test
+    fun primaryAppWindowIsVisibleAtEnd() = testSpec.appWindowIsVisibleAtEnd(primaryApp.component)
+
+    @Presubmit
+    @Test
+    fun secondaryAppWindowIsVisibleAtEnd() =
+        testSpec.appWindowIsVisibleAtEnd(sendNotificationApp.component)
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTestParameter> {
+            return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
+                repetitions = SplitScreenHelper.TEST_REPETITIONS,
+                // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
+                supportedNavigationModes =
+                    listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)
+            )
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
new file mode 100644
index 0000000..52c2daf
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.splitscreen
+
+import android.app.Instrumentation
+import android.content.Context
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.FlickerBuilderProvider
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.wm.shell.flicker.helpers.SplitScreenHelper
+
+abstract class SplitScreenBase(protected val testSpec: FlickerTestParameter) {
+    protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    protected val taplInstrumentation = LauncherInstrumentation()
+    protected val context: Context = instrumentation.context
+    protected val primaryApp = SplitScreenHelper.getPrimary(instrumentation)
+    protected val secondaryApp = SplitScreenHelper.getSecondary(instrumentation)
+
+    @FlickerBuilderProvider
+    fun buildFlicker(): FlickerBuilder {
+        return FlickerBuilder(instrumentation).apply {
+            transition(this)
+        }
+    }
+
+    protected open val transition: FlickerBuilder.() -> Unit
+        get() = {
+            setup {
+                test {
+                    taplInstrumentation.setEnableRotation(true)
+                    setRotation(testSpec.startRotation)
+                    taplInstrumentation.setExpectedRotation(testSpec.startRotation)
+                }
+            }
+            teardown {
+                eachRun {
+                    primaryApp.exit(wmHelper)
+                    secondaryApp.exit(wmHelper)
+                }
+            }
+        }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
index bd98585..bc0b0b6 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/AndroidManifest.xml
@@ -92,6 +92,17 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".SendNotificationActivity"
+                  android:taskAffinity="com.android.wm.shell.flicker.testapp.SendNotificationActivity"
+                  android:theme="@style/CutoutShortEdges"
+                  android:label="SendNotificationApp"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
         <activity android:name=".NonResizeableActivity"
                   android:resizeableActivity="false"
                   android:taskAffinity="com.android.wm.shell.flicker.testapp.NonResizeableActivity"
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_notification.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_notification.xml
new file mode 100644
index 0000000..8d59b56
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_notification.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="@android:color/black">
+
+        <Button
+            android:id="@+id/button_send_notification"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerHorizontal="true"
+            android:layout_centerVertical="true"
+            android:text="Send Notification" />
+</RelativeLayout>
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
index 909b77c..e9e7bb6 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/res/layout/activity_pip.xml
@@ -44,6 +44,32 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical"
+        android:checkedButton="@id/enter_pip_on_leave_disabled">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Enter PiP on home press"/>
+
+        <RadioButton
+            android:id="@+id/enter_pip_on_leave_disabled"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Disabled"
+            android:onClick="onAutoPipSelected"/>
+
+        <RadioButton
+            android:id="@+id/enter_pip_on_leave_manual"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Via code behind"
+            android:onClick="onAutoPipSelected"/>
+    </RadioGroup>
+
+    <RadioGroup
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
         android:checkedButton="@id/ratio_default">
 
         <TextView
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java
index 0ed59bd..a2b580d 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/Components.java
@@ -88,6 +88,12 @@
                 PACKAGE_NAME + ".SplitScreenSecondaryActivity");
     }
 
+    public static class SendNotificationActivity {
+        public static final String LABEL = "SendNotificationApp";
+        public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME,
+                PACKAGE_NAME + ".SendNotificationActivity");
+    }
+
     public static class LaunchBubbleActivity {
         public static final String LABEL = "LaunchBubbleApp";
         public static final ComponentName COMPONENT = new ComponentName(PACKAGE_NAME,
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
index a6ba782..a39aa4d 100644
--- a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/PipActivity.java
@@ -48,6 +48,7 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.CheckBox;
+import android.widget.RadioButton;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -201,6 +202,17 @@
         super.onDestroy();
     }
 
+    @Override
+    protected void onUserLeaveHint() {
+        // Only used when auto PiP is disabled. This is to simulate the behavior that an app
+        // supports regular PiP but not auto PiP.
+        final boolean manuallyEnterPip =
+                ((RadioButton) findViewById(R.id.enter_pip_on_leave_manual)).isChecked();
+        if (manuallyEnterPip) {
+            enterPictureInPictureMode();
+        }
+    }
+
     private RemoteAction buildRemoteAction(Icon icon, String label, String action) {
         final Intent intent = new Intent(action);
         final PendingIntent pendingIntent =
@@ -216,6 +228,17 @@
         enterPictureInPictureMode(mPipParamsBuilder.build());
     }
 
+    public void onAutoPipSelected(View v) {
+        switch (v.getId()) {
+            case R.id.enter_pip_on_leave_manual:
+                // disable auto enter PiP
+            case R.id.enter_pip_on_leave_disabled:
+                mPipParamsBuilder.setAutoEnterEnabled(false);
+                setPictureInPictureParams(mPipParamsBuilder.build());
+                break;
+        }
+    }
+
     public void onRatioSelected(View v) {
         switch (v.getId()) {
             case R.id.ratio_default:
diff --git a/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SendNotificationActivity.java b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SendNotificationActivity.java
new file mode 100644
index 0000000..8020ef2
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/test-apps/flickerapp/src/com/android/wm/shell/flicker/testapp/SendNotificationActivity.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.testapp;
+
+import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+
+public class SendNotificationActivity extends Activity {
+    private NotificationManager mNotificationManager;
+    private String mChannelId = "Channel id";
+    private String mChannelName = "Channel name";
+    private NotificationChannel mChannel;
+    private int mNotifyId = 0;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_notification);
+        findViewById(R.id.button_send_notification).setOnClickListener(this::sendNotification);
+
+        mChannel = new NotificationChannel(mChannelId, mChannelName,
+                NotificationManager.IMPORTANCE_DEFAULT);
+        mNotificationManager = getSystemService(NotificationManager.class);
+        mNotificationManager.createNotificationChannel(mChannel);
+    }
+
+    private void sendNotification(View v) {
+        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
+                new Intent(this, SendNotificationActivity.class),
+                PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+        Notification notification = new Notification.Builder(this, mChannelId)
+                .setContentTitle("Notification App")
+                .setContentText("Notification content")
+                .setWhen(System.currentTimeMillis())
+                .setSmallIcon(R.drawable.ic_message)
+                .setContentIntent(pendingIntent)
+                .build();
+
+        mNotificationManager.notify(mNotifyId, notification);
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index a6caefe..0b53c40 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -133,7 +133,7 @@
                     .when(mTaskOrganizerController).registerTaskOrganizer(any());
         } catch (RemoteException e) {}
         mOrganizer = spy(new ShellTaskOrganizer(mTaskOrganizerController, mTestExecutor, mContext,
-                mCompatUI, Optional.empty()));
+                mCompatUI, Optional.empty(), Optional.empty()));
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java
deleted file mode 100644
index e73d9aa..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairTests.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.apppairs;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.hardware.display.DisplayManager;
-
-import androidx.test.annotation.UiThreadTest;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.TestRunningTaskInfoBuilder;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.SyncTransactionQueue;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for {@link AppPair}
- * Build/Install/Run:
- *  atest WMShellUnitTests:AppPairTests
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class AppPairTests extends ShellTestCase {
-
-    private AppPairsController mController;
-    @Mock private SyncTransactionQueue mSyncQueue;
-    @Mock private ShellTaskOrganizer mTaskOrganizer;
-    @Mock private DisplayController mDisplayController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        when(mDisplayController.getDisplayContext(anyInt())).thenReturn(mContext);
-        when(mDisplayController.getDisplay(anyInt())).thenReturn(
-                mContext.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY));
-        mController = new TestAppPairsController(
-                mTaskOrganizer,
-                mSyncQueue,
-                mDisplayController);
-        spyOn(mController);
-    }
-
-    @After
-    public void tearDown() {}
-
-    @Test
-    @UiThreadTest
-    public void testContains() {
-        final ActivityManager.RunningTaskInfo task1 = new TestRunningTaskInfoBuilder().build();
-        final ActivityManager.RunningTaskInfo task2 = new TestRunningTaskInfoBuilder().build();
-
-        final AppPair pair = mController.pairInner(task1, task2);
-        assertThat(pair.contains(task1.taskId)).isTrue();
-        assertThat(pair.contains(task2.taskId)).isTrue();
-
-        pair.unpair();
-        assertThat(pair.contains(task1.taskId)).isFalse();
-        assertThat(pair.contains(task2.taskId)).isFalse();
-    }
-
-    @Test
-    @UiThreadTest
-    public void testVanishUnpairs() {
-        final ActivityManager.RunningTaskInfo task1 = new TestRunningTaskInfoBuilder().build();
-        final ActivityManager.RunningTaskInfo task2 = new TestRunningTaskInfoBuilder().build();
-
-        final AppPair pair = mController.pairInner(task1, task2);
-        assertThat(pair.contains(task1.taskId)).isTrue();
-        assertThat(pair.contains(task2.taskId)).isTrue();
-
-        pair.onTaskVanished(task1);
-        assertThat(pair.contains(task1.taskId)).isFalse();
-        assertThat(pair.contains(task2.taskId)).isFalse();
-    }
-
-    @Test
-    @UiThreadTest
-    public void testOnTaskInfoChanged_notSupportsMultiWindow() {
-        final ActivityManager.RunningTaskInfo task1 = new TestRunningTaskInfoBuilder().build();
-        final ActivityManager.RunningTaskInfo task2 = new TestRunningTaskInfoBuilder().build();
-
-        final AppPair pair = mController.pairInner(task1, task2);
-        assertThat(pair.contains(task1.taskId)).isTrue();
-        assertThat(pair.contains(task2.taskId)).isTrue();
-
-        task1.supportsMultiWindow = false;
-        pair.onTaskInfoChanged(task1);
-        verify(mController).unpair(pair.getRootTaskId());
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java
deleted file mode 100644
index 505c153..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsControllerTests.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.apppairs;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager;
-import android.hardware.display.DisplayManager;
-
-import androidx.test.annotation.UiThreadTest;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.TestRunningTaskInfoBuilder;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.SyncTransactionQueue;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/** Tests for {@link AppPairsController} */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class AppPairsControllerTests extends ShellTestCase {
-    private TestAppPairsController mController;
-    private TestAppPairsPool mPool;
-    @Mock private SyncTransactionQueue mSyncQueue;
-    @Mock private ShellTaskOrganizer mTaskOrganizer;
-    @Mock private DisplayController mDisplayController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        when(mDisplayController.getDisplayContext(anyInt())).thenReturn(mContext);
-        when(mDisplayController.getDisplay(anyInt())).thenReturn(
-                mContext.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY));
-        mController = new TestAppPairsController(
-                mTaskOrganizer,
-                mSyncQueue,
-                mDisplayController);
-        mPool = mController.getPool();
-    }
-
-    @After
-    public void tearDown() {}
-
-    @Test
-    @UiThreadTest
-    public void testPairUnpair() {
-        final ActivityManager.RunningTaskInfo task1 = new TestRunningTaskInfoBuilder().build();
-        final ActivityManager.RunningTaskInfo task2 = new TestRunningTaskInfoBuilder().build();
-
-        final AppPair pair = mController.pairInner(task1, task2);
-        assertThat(pair.contains(task1.taskId)).isTrue();
-        assertThat(pair.contains(task2.taskId)).isTrue();
-        assertThat(mPool.poolSize()).isGreaterThan(0);
-
-        mController.unpair(task2.taskId);
-        assertThat(pair.contains(task1.taskId)).isFalse();
-        assertThat(pair.contains(task2.taskId)).isFalse();
-        assertThat(mPool.poolSize()).isGreaterThan(1);
-    }
-
-    @Test
-    @UiThreadTest
-    public void testUnpair_DontReleaseToPool() {
-        final ActivityManager.RunningTaskInfo task1 = new TestRunningTaskInfoBuilder().build();
-        final ActivityManager.RunningTaskInfo task2 = new TestRunningTaskInfoBuilder().build();
-
-        final AppPair pair = mController.pairInner(task1, task2);
-        assertThat(pair.contains(task1.taskId)).isTrue();
-        assertThat(pair.contains(task2.taskId)).isTrue();
-
-        mController.unpair(task2.taskId, false /* releaseToPool */);
-        assertThat(pair.contains(task1.taskId)).isFalse();
-        assertThat(pair.contains(task2.taskId)).isFalse();
-        assertThat(mPool.poolSize()).isEqualTo(1);
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java
deleted file mode 100644
index a3f134e..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/AppPairsPoolTests.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.apppairs;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.when;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.ShellTestCase;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.SyncTransactionQueue;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/** Tests for {@link AppPairsPool} */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class AppPairsPoolTests extends ShellTestCase {
-    private TestAppPairsController mController;
-    private TestAppPairsPool mPool;
-    @Mock private SyncTransactionQueue mSyncQueue;
-    @Mock private ShellTaskOrganizer mTaskOrganizer;
-    @Mock private DisplayController mDisplayController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        when(mDisplayController.getDisplayContext(anyInt())).thenReturn(mContext);
-        mController = new TestAppPairsController(
-                mTaskOrganizer,
-                mSyncQueue,
-                mDisplayController);
-        mPool = mController.getPool();
-    }
-
-    @After
-    public void tearDown() {}
-
-    @Test
-    public void testInitialState() {
-        // Pool should always start off with at least 1 entry.
-        assertThat(mPool.poolSize()).isGreaterThan(0);
-    }
-
-    @Test
-    public void testAcquireRelease() {
-        assertThat(mPool.poolSize()).isGreaterThan(0);
-        final AppPair appPair = mPool.acquire();
-        assertThat(mPool.poolSize()).isGreaterThan(0);
-        mPool.release(appPair);
-        assertThat(mPool.poolSize()).isGreaterThan(1);
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsController.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsController.java
deleted file mode 100644
index 294bc12..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsController.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.apppairs;
-
-import static org.mockito.Mockito.mock;
-
-import com.android.wm.shell.ShellTaskOrganizer;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.DisplayInsetsController;
-import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.SyncTransactionQueue;
-
-public class TestAppPairsController extends AppPairsController {
-    private TestAppPairsPool mPool;
-
-    public TestAppPairsController(ShellTaskOrganizer organizer, SyncTransactionQueue syncQueue,
-            DisplayController displayController) {
-        super(organizer, syncQueue, displayController, mock(ShellExecutor.class),
-                mock(DisplayImeController.class), mock(DisplayInsetsController.class));
-        mPool = new TestAppPairsPool(this);
-        setPairsPool(mPool);
-    }
-
-    TestAppPairsPool getPool() {
-        return mPool;
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsPool.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsPool.java
deleted file mode 100644
index 1ee7fff..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/apppairs/TestAppPairsPool.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.apppairs;
-
-import android.app.ActivityManager;
-
-import com.android.wm.shell.TestRunningTaskInfoBuilder;
-
-public class TestAppPairsPool extends AppPairsPool{
-    TestAppPairsPool(AppPairsController controller) {
-        super(controller);
-    }
-
-    @Override
-    void incrementPool() {
-        final AppPair entry = new AppPair(mController);
-        final ActivityManager.RunningTaskInfo info =
-                new TestRunningTaskInfoBuilder().build();
-        entry.onTaskAppeared(info, null /* leash */);
-        release(entry);
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandlerTest.java
new file mode 100644
index 0000000..44ff354
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandlerTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.bubbles;
+
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_UP;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.floatThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.os.SystemClock;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.bubbles.BubblesNavBarMotionEventHandler.MotionEventListener;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Test {@link MotionEvent} handling in {@link BubblesNavBarMotionEventHandler}.
+ * Verifies that swipe events
+ */
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidTestingRunner.class)
+public class BubblesNavBarMotionEventHandlerTest extends ShellTestCase {
+
+    private BubblesNavBarMotionEventHandler mMotionEventHandler;
+    @Mock
+    private WindowManager mWindowManager;
+    @Mock
+    private Runnable mInterceptTouchRunnable;
+    @Mock
+    private MotionEventListener mMotionEventListener;
+    private long mMotionEventTime;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        TestableBubblePositioner positioner = new TestableBubblePositioner(getContext(),
+                mWindowManager);
+        mMotionEventHandler = new BubblesNavBarMotionEventHandler(getContext(), positioner,
+                mInterceptTouchRunnable, mMotionEventListener);
+        mMotionEventTime = SystemClock.uptimeMillis();
+    }
+
+    @Test
+    public void testMotionEvent_swipeUpInGestureZone_handled() {
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_DOWN, 0, 990));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_MOVE, 0, 690));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_MOVE, 0, 490));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_MOVE, 0, 390));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_UP, 0, 390));
+
+        verify(mMotionEventListener).onDown(0, 990);
+        verify(mMotionEventListener).onMove(0, -300);
+        verify(mMotionEventListener).onMove(0, -500);
+        verify(mMotionEventListener).onMove(0, -600);
+        // Check that velocity up is about 5000
+        verify(mMotionEventListener).onUp(eq(0f), floatThat(f -> Math.round(f) == -5000));
+        verifyZeroInteractions(mMotionEventListener);
+        verify(mInterceptTouchRunnable).run();
+    }
+
+    @Test
+    public void testMotionEvent_swipeUpOutsideGestureZone_ignored() {
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_DOWN, 0, 500));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_MOVE, 0, 100));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_UP, 0, 100));
+
+        verifyZeroInteractions(mMotionEventListener);
+        verifyZeroInteractions(mInterceptTouchRunnable);
+    }
+
+    @Test
+    public void testMotionEvent_horizontalMoveMoreThanTouchSlop_handled() {
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_DOWN, 0, 990));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_MOVE, 100, 990));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_UP, 100, 990));
+
+        verify(mMotionEventListener).onDown(0, 990);
+        verify(mMotionEventListener).onMove(100, 0);
+        verify(mMotionEventListener).onUp(0, 0);
+        verifyZeroInteractions(mMotionEventListener);
+        verify(mInterceptTouchRunnable).run();
+    }
+
+    @Test
+    public void testMotionEvent_moveLessThanTouchSlop_ignored() {
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_DOWN, 0, 990));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_MOVE, 0, 989));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_UP, 0, 989));
+
+        verify(mMotionEventListener).onDown(0, 990);
+        verifyNoMoreInteractions(mMotionEventListener);
+        verifyZeroInteractions(mInterceptTouchRunnable);
+    }
+
+    @Test
+    public void testMotionEvent_actionCancel_listenerNotified() {
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_DOWN, 0, 990));
+        mMotionEventHandler.onMotionEvent(newEvent(ACTION_CANCEL, 0, 990));
+        verify(mMotionEventListener).onDown(0, 990);
+        verify(mMotionEventListener).onCancel();
+        verifyNoMoreInteractions(mMotionEventListener);
+        verifyZeroInteractions(mInterceptTouchRunnable);
+    }
+
+    private MotionEvent newEvent(int actionDown, float x, float y) {
+        MotionEvent event = MotionEvent.obtain(0L, mMotionEventTime, actionDown, x, y, 0);
+        mMotionEventTime += 10;
+        return event;
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerTest.java
new file mode 100644
index 0000000..991913a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.animation;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.ViewConfiguration;
+import android.view.WindowManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.bubbles.BubbleExpandedView;
+import com.android.wm.shell.bubbles.TestableBubblePositioner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class ExpandedViewAnimationControllerTest extends ShellTestCase {
+
+    private ExpandedViewAnimationController mController;
+
+    @Mock
+    private WindowManager mWindowManager;
+
+    @Mock
+    private BubbleExpandedView mMockExpandedView;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        TestableBubblePositioner positioner = new TestableBubblePositioner(getContext(),
+                mWindowManager);
+        mController = new ExpandedViewAnimationControllerImpl(getContext(), positioner);
+
+        mController.setExpandedView(mMockExpandedView);
+        when(mMockExpandedView.getContentHeight()).thenReturn(1000);
+    }
+
+    @Test
+    public void testUpdateDrag_expandedViewMovesUpAndClipped() {
+        // Drag by 50 pixels which corresponds to 10 pixels with overscroll
+        int dragDistance = 50;
+        int dampenedDistance = 10;
+
+        mController.updateDrag(dragDistance);
+
+        verify(mMockExpandedView).setTopClip(dampenedDistance);
+        verify(mMockExpandedView).setContentTranslationY(-dampenedDistance);
+        verify(mMockExpandedView).setManageButtonTranslationY(-dampenedDistance);
+    }
+
+    @Test
+    public void testUpdateDrag_zOrderUpdates() {
+        mController.updateDrag(10);
+        mController.updateDrag(20);
+
+        verify(mMockExpandedView, times(1)).setSurfaceZOrderedOnTop(true);
+        verify(mMockExpandedView, times(1)).setAnimating(true);
+    }
+
+    @Test
+    public void testUpdateDrag_moveBackToZero_zOrderRestored() {
+        mController.updateDrag(50);
+        reset(mMockExpandedView);
+        mController.updateDrag(0);
+        mController.updateDrag(0);
+
+        verify(mMockExpandedView, times(1)).setSurfaceZOrderedOnTop(false);
+        verify(mMockExpandedView, times(1)).setAnimating(false);
+    }
+
+    @Test
+    public void testUpdateDrag_hapticFeedbackOnlyOnce() {
+        // Drag by 10 which is below the collapse threshold - no feedback
+        mController.updateDrag(10);
+        verify(mMockExpandedView, times(0)).performHapticFeedback(anyInt());
+        // 150 takes it over the threshold - perform feedback
+        mController.updateDrag(150);
+        verify(mMockExpandedView, times(1)).performHapticFeedback(anyInt());
+        // Continue dragging, no more feedback
+        mController.updateDrag(200);
+        verify(mMockExpandedView, times(1)).performHapticFeedback(anyInt());
+        // Drag below threshold and over again - no more feedback
+        mController.updateDrag(10);
+        mController.updateDrag(150);
+        verify(mMockExpandedView, times(1)).performHapticFeedback(anyInt());
+    }
+
+    @Test
+    public void testShouldCollapse_doNotCollapseIfNotDragged() {
+        assertThat(mController.shouldCollapse()).isFalse();
+    }
+
+    @Test
+    public void testShouldCollapse_doNotCollapseIfVelocityDown() {
+        assumeTrue("Min fling velocity should be > 1 for this test", getMinFlingVelocity() > 1);
+        mController.setSwipeVelocity(getVelocityAboveMinFling());
+        assertThat(mController.shouldCollapse()).isFalse();
+    }
+
+    @Test
+    public void tesShouldCollapse_doNotCollapseIfVelocityUpIsSmall() {
+        assumeTrue("Min fling velocity should be > 1 for this test", getMinFlingVelocity() > 1);
+        mController.setSwipeVelocity(-getVelocityBelowMinFling());
+        assertThat(mController.shouldCollapse()).isFalse();
+    }
+
+    @Test
+    public void testShouldCollapse_collapseIfVelocityUpIsLarge() {
+        assumeTrue("Min fling velocity should be > 1 for this test", getMinFlingVelocity() > 1);
+        mController.setSwipeVelocity(-getVelocityAboveMinFling());
+        assertThat(mController.shouldCollapse()).isTrue();
+    }
+
+    @Test
+    public void testShouldCollapse_collapseIfPastThreshold() {
+        mController.updateDrag(500);
+        assertThat(mController.shouldCollapse()).isTrue();
+    }
+
+    @Test
+    public void testReset() {
+        mController.updateDrag(100);
+        reset(mMockExpandedView);
+        mController.reset();
+        verify(mMockExpandedView, atLeastOnce()).setAnimating(false);
+        verify(mMockExpandedView).setContentAlpha(1);
+        verify(mMockExpandedView).setBackgroundAlpha(1);
+        verify(mMockExpandedView).setManageButtonAlpha(1);
+        verify(mMockExpandedView).setManageButtonAlpha(1);
+        verify(mMockExpandedView).setTopClip(0);
+        verify(mMockExpandedView).setContentTranslationY(-0f);
+        verify(mMockExpandedView).setManageButtonTranslationY(-0f);
+        verify(mMockExpandedView).setBottomClip(0);
+        verify(mMockExpandedView).movePointerBy(0, 0);
+        assertThat(mController.shouldCollapse()).isFalse();
+    }
+
+    private int getVelocityBelowMinFling() {
+        return getMinFlingVelocity() - 1;
+    }
+
+    private int getVelocityAboveMinFling() {
+        return getMinFlingVelocity() + 1;
+    }
+
+    private int getMinFlingVelocity() {
+        return ViewConfiguration.get(getContext()).getScaledMinimumFlingVelocity();
+    }
+}
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 bb6026c..7e6595f 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
@@ -182,8 +182,10 @@
         info.configuration.windowConfiguration.setActivityType(actType);
         info.configuration.windowConfiguration.setWindowingMode(winMode);
         info.isResizeable = true;
-        info.baseActivity = new ComponentName(getInstrumentation().getContext().getPackageName(),
+        info.baseActivity = new ComponentName(getInstrumentation().getContext(),
                 ".ActivityWithMode" + winMode);
+        info.baseIntent = new Intent();
+        info.baseIntent.setComponent(info.baseActivity);
         ActivityInfo activityInfo = new ActivityInfo();
         activityInfo.packageName = info.baseActivity.getPackageName();
         activityInfo.name = info.baseActivity.getClassName();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java
deleted file mode 100644
index 4523e2c..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/fullscreen/FullscreenTaskListenerTest.java
+++ /dev/null
@@ -1,166 +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.wm.shell.fullscreen;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-
-import static org.junit.Assume.assumeFalse;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.ActivityManager.RunningTaskInfo;
-import android.app.WindowConfiguration;
-import android.content.res.Configuration;
-import android.graphics.Point;
-import android.os.SystemProperties;
-import android.view.SurfaceControl;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.recents.RecentTasksController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Optional;
-
-@SmallTest
-public class FullscreenTaskListenerTest {
-    private static final boolean ENABLE_SHELL_TRANSITIONS =
-            SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
-
-    @Mock
-    private SyncTransactionQueue mSyncQueue;
-    @Mock
-    private FullscreenUnfoldController mUnfoldController;
-    @Mock
-    private RecentTasksController mRecentTasksController;
-    @Mock
-    private SurfaceControl mSurfaceControl;
-
-    private Optional<FullscreenUnfoldController> mFullscreenUnfoldController;
-
-    private FullscreenTaskListener mListener;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mFullscreenUnfoldController = Optional.of(mUnfoldController);
-        mListener = new FullscreenTaskListener(mSyncQueue, mFullscreenUnfoldController,
-                Optional.empty());
-    }
-
-    @Test
-    public void testAnimatableTaskAppeared_notifiesUnfoldController() {
-        assumeFalse(ENABLE_SHELL_TRANSITIONS);
-        RunningTaskInfo info = createTaskInfo(/* visible */ true, /* taskId */ 0);
-
-        mListener.onTaskAppeared(info, mSurfaceControl);
-
-        verify(mUnfoldController).onTaskAppeared(eq(info), any());
-    }
-
-    @Test
-    public void testMultipleAnimatableTasksAppeared_notifiesUnfoldController() {
-        assumeFalse(ENABLE_SHELL_TRANSITIONS);
-        RunningTaskInfo animatable1 = createTaskInfo(/* visible */ true, /* taskId */ 0);
-        RunningTaskInfo animatable2 = createTaskInfo(/* visible */ true, /* taskId */ 1);
-
-        mListener.onTaskAppeared(animatable1, mSurfaceControl);
-        mListener.onTaskAppeared(animatable2, mSurfaceControl);
-
-        InOrder order = inOrder(mUnfoldController);
-        order.verify(mUnfoldController).onTaskAppeared(eq(animatable1), any());
-        order.verify(mUnfoldController).onTaskAppeared(eq(animatable2), any());
-    }
-
-    @Test
-    public void testNonAnimatableTaskAppeared_doesNotNotifyUnfoldController() {
-        assumeFalse(ENABLE_SHELL_TRANSITIONS);
-        RunningTaskInfo info = createTaskInfo(/* visible */ false, /* taskId */ 0);
-
-        mListener.onTaskAppeared(info, mSurfaceControl);
-
-        verifyNoMoreInteractions(mUnfoldController);
-    }
-
-    @Test
-    public void testNonAnimatableTaskChanged_doesNotNotifyUnfoldController() {
-        assumeFalse(ENABLE_SHELL_TRANSITIONS);
-        RunningTaskInfo info = createTaskInfo(/* visible */ false, /* taskId */ 0);
-        mListener.onTaskAppeared(info, mSurfaceControl);
-
-        mListener.onTaskInfoChanged(info);
-
-        verifyNoMoreInteractions(mUnfoldController);
-    }
-
-    @Test
-    public void testNonAnimatableTaskVanished_doesNotNotifyUnfoldController() {
-        assumeFalse(ENABLE_SHELL_TRANSITIONS);
-        RunningTaskInfo info = createTaskInfo(/* visible */ false, /* taskId */ 0);
-        mListener.onTaskAppeared(info, mSurfaceControl);
-
-        mListener.onTaskVanished(info);
-
-        verifyNoMoreInteractions(mUnfoldController);
-    }
-
-    @Test
-    public void testAnimatableTaskBecameInactive_notifiesUnfoldController() {
-        assumeFalse(ENABLE_SHELL_TRANSITIONS);
-        RunningTaskInfo animatableTask = createTaskInfo(/* visible */ true, /* taskId */ 0);
-        mListener.onTaskAppeared(animatableTask, mSurfaceControl);
-        RunningTaskInfo notAnimatableTask = createTaskInfo(/* visible */ false, /* taskId */ 0);
-
-        mListener.onTaskInfoChanged(notAnimatableTask);
-
-        verify(mUnfoldController).onTaskVanished(eq(notAnimatableTask));
-    }
-
-    @Test
-    public void testAnimatableTaskVanished_notifiesUnfoldController() {
-        assumeFalse(ENABLE_SHELL_TRANSITIONS);
-        RunningTaskInfo taskInfo = createTaskInfo(/* visible */ true, /* taskId */ 0);
-        mListener.onTaskAppeared(taskInfo, mSurfaceControl);
-
-        mListener.onTaskVanished(taskInfo);
-
-        verify(mUnfoldController).onTaskVanished(eq(taskInfo));
-    }
-
-    private RunningTaskInfo createTaskInfo(boolean visible, int taskId) {
-        final RunningTaskInfo info = spy(new RunningTaskInfo());
-        info.isVisible = visible;
-        info.positionInParent = new Point();
-        when(info.getWindowingMode()).thenReturn(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
-        final Configuration configuration = new Configuration();
-        configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_STANDARD);
-        when(info.getConfiguration()).thenReturn(configuration);
-        info.taskId = taskId;
-        return info;
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
index 440a6f8..1eadeed 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
@@ -88,7 +88,7 @@
         // NOTE: KidsModeTaskOrganizer should have a null CompatUIController.
         mOrganizer = spy(new KidsModeTaskOrganizer(mTaskOrganizerController, mTestExecutor,
                 mHandler, mContext, mSyncTransactionQueue, mDisplayController,
-                mDisplayInsetsController, Optional.empty(), mObserver));
+                mDisplayInsetsController, Optional.empty(), Optional.empty(), mObserver));
         mOrganizer.initialize(mStartingWindowController);
         doReturn(mTransaction).when(mOrganizer).getWindowContainerTransaction();
         doReturn(new InsetsState()).when(mDisplayController).getInsetsState(DEFAULT_DISPLAY);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
index ecf1c5d..6a6db8a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
@@ -345,8 +345,8 @@
         when(mMockSettingsUitl.getSettingsSwipeToNotificationEnabled(any(), anyInt())).thenReturn(
                 false);
         final WindowContainerTransaction handlerWCT = new WindowContainerTransaction();
-        mSpiedOneHandedController.onRotateDisplay(mDisplay.getDisplayId(), Surface.ROTATION_0,
-                Surface.ROTATION_90, handlerWCT);
+        mSpiedOneHandedController.onDisplayChange(mDisplay.getDisplayId(), Surface.ROTATION_0,
+                Surface.ROTATION_90, null /* newDisplayAreaInfo */, handlerWCT);
 
         verify(mMockDisplayAreaOrganizer, atLeastOnce()).onRotateDisplay(eq(mContext),
                 eq(Surface.ROTATION_90), any(WindowContainerTransaction.class));
@@ -358,8 +358,8 @@
         when(mMockSettingsUitl.getSettingsSwipeToNotificationEnabled(any(), anyInt())).thenReturn(
                 false);
         final WindowContainerTransaction handlerWCT = new WindowContainerTransaction();
-        mSpiedOneHandedController.onRotateDisplay(mDisplay.getDisplayId(), Surface.ROTATION_0,
-                Surface.ROTATION_90, handlerWCT);
+        mSpiedOneHandedController.onDisplayChange(mDisplay.getDisplayId(), Surface.ROTATION_0,
+                Surface.ROTATION_90, null /* newDisplayAreaInfo */, handlerWCT);
 
         verify(mMockDisplayAreaOrganizer, never()).onRotateDisplay(eq(mContext),
                 eq(Surface.ROTATION_90), any(WindowContainerTransaction.class));
@@ -371,8 +371,8 @@
         when(mMockSettingsUitl.getSettingsSwipeToNotificationEnabled(any(), anyInt())).thenReturn(
                 true);
         final WindowContainerTransaction handlerWCT = new WindowContainerTransaction();
-        mSpiedOneHandedController.onRotateDisplay(mDisplay.getDisplayId(), Surface.ROTATION_0,
-                Surface.ROTATION_90, handlerWCT);
+        mSpiedOneHandedController.onDisplayChange(mDisplay.getDisplayId(), Surface.ROTATION_0,
+                Surface.ROTATION_90, null /* newDisplayAreaInfo */, handlerWCT);
 
         verify(mMockDisplayAreaOrganizer, never()).onRotateDisplay(eq(mContext),
                 eq(Surface.ROTATION_90), any(WindowContainerTransaction.class));
@@ -384,8 +384,8 @@
         when(mMockSettingsUitl.getSettingsSwipeToNotificationEnabled(any(), anyInt())).thenReturn(
                 false);
         final WindowContainerTransaction handlerWCT = new WindowContainerTransaction();
-        mSpiedOneHandedController.onRotateDisplay(mDisplay.getDisplayId(), Surface.ROTATION_0,
-                Surface.ROTATION_90, handlerWCT);
+        mSpiedOneHandedController.onDisplayChange(mDisplay.getDisplayId(), Surface.ROTATION_0,
+                Surface.ROTATION_90, null /* newDisplayAreaInfo */, handlerWCT);
 
         verify(mMockDisplayAreaOrganizer, atLeastOnce()).onRotateDisplay(eq(mContext),
                 eq(Surface.ROTATION_90), any(WindowContainerTransaction.class));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index df18133..babc970 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -53,6 +53,7 @@
 import com.android.wm.shell.pip.PipSnapAlgorithm;
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipTransitionController;
+import com.android.wm.shell.pip.PipTransitionState;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -76,9 +77,11 @@
     @Mock private PhonePipMenuController mMockPhonePipMenuController;
     @Mock private PipAppOpsListener mMockPipAppOpsListener;
     @Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm;
+    @Mock private PipKeepClearAlgorithm mMockPipKeepClearAlgorithm;
     @Mock private PipSnapAlgorithm mMockPipSnapAlgorithm;
     @Mock private PipMediaController mMockPipMediaController;
     @Mock private PipTaskOrganizer mMockPipTaskOrganizer;
+    @Mock private PipTransitionState mMockPipTransitionState;
     @Mock private PipTransitionController mMockPipTransitionController;
     @Mock private PipTouchHandler mMockPipTouchHandler;
     @Mock private PipMotionHelper mMockPipMotionHelper;
@@ -101,9 +104,10 @@
         }).when(mMockExecutor).execute(any());
         mPipController = new PipController(mContext, mMockDisplayController,
                 mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
-                mMockPipBoundsState, mMockPipMediaController,
-                mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTouchHandler,
-                mMockPipTransitionController, mMockWindowManagerShellWrapper,
+                mMockPipKeepClearAlgorithm,
+                mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
+                mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTransitionState,
+                mMockPipTouchHandler, mMockPipTransitionController, mMockWindowManagerShellWrapper,
                 mMockTaskStackListener, mPipParamsChangedForwarder,
                 mMockOneHandedController, mMockExecutor);
         when(mMockPipBoundsAlgorithm.getSnapAlgorithm()).thenReturn(mMockPipSnapAlgorithm);
@@ -134,9 +138,10 @@
 
         assertNull(PipController.create(spyContext, mMockDisplayController,
                 mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
-                mMockPipBoundsState, mMockPipMediaController,
-                mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTouchHandler,
-                mMockPipTransitionController, mMockWindowManagerShellWrapper,
+                mMockPipKeepClearAlgorithm,
+                mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
+                mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTransitionState,
+                mMockPipTouchHandler, mMockPipTransitionController, mMockWindowManagerShellWrapper,
                 mMockTaskStackListener, mPipParamsChangedForwarder,
                 mMockOneHandedController, mMockExecutor));
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithmTest.java
new file mode 100644
index 0000000..e0f7e35
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipKeepClearAlgorithmTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip.phone;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import android.graphics.Rect;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.ShellTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Set;
+
+/**
+ * Unit tests against {@link PipKeepClearAlgorithm}.
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class PipKeepClearAlgorithmTest extends ShellTestCase {
+
+    private PipKeepClearAlgorithm mPipKeepClearAlgorithm;
+    private static final Rect DISPLAY_BOUNDS = new Rect(0, 0, 1000, 1000);
+
+    @Before
+    public void setUp() throws Exception {
+        mPipKeepClearAlgorithm = new PipKeepClearAlgorithm();
+    }
+
+    @Test
+    public void adjust_withCollidingRestrictedKeepClearAreas_movesBounds() {
+        final Rect inBounds = new Rect(0, 0, 100, 100);
+        final Rect keepClearRect = new Rect(50, 50, 150, 150);
+
+        final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(keepClearRect),
+                Set.of(), DISPLAY_BOUNDS);
+
+        assertFalse(outBounds.contains(keepClearRect));
+    }
+
+    @Test
+    public void adjust_withNonCollidingRestrictedKeepClearAreas_boundsDoNotChange() {
+        final Rect inBounds = new Rect(0, 0, 100, 100);
+        final Rect keepClearRect = new Rect(100, 100, 150, 150);
+
+        final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(keepClearRect),
+                Set.of(), DISPLAY_BOUNDS);
+
+        assertEquals(inBounds, outBounds);
+    }
+
+    @Test
+    public void adjust_withCollidingUnrestrictedKeepClearAreas_boundsDoNotChange() {
+        // TODO(b/183746978): update this test to accommodate for the updated algorithm
+        final Rect inBounds = new Rect(0, 0, 100, 100);
+        final Rect keepClearRect = new Rect(50, 50, 150, 150);
+
+        final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(),
+                Set.of(keepClearRect), DISPLAY_BOUNDS);
+
+        assertEquals(inBounds, outBounds);
+    }
+
+    @Test
+    public void adjust_withNonCollidingUnrestrictedKeepClearAreas_boundsDoNotChange() {
+        final Rect inBounds = new Rect(0, 0, 100, 100);
+        final Rect keepClearRect = new Rect(100, 100, 150, 150);
+
+        final Rect outBounds = mPipKeepClearAlgorithm.adjust(inBounds, Set.of(),
+                Set.of(keepClearRect), DISPLAY_BOUNDS);
+
+        assertEquals(inBounds, outBounds);
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 50f6bd7..2b4d1a6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -47,7 +47,7 @@
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.util.GroupedRecentTaskInfo;
-import com.android.wm.shell.util.StagedSplitBounds;
+import com.android.wm.shell.util.SplitBounds;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -80,7 +80,7 @@
         mRecentTasksController = spy(new RecentTasksController(mContext, mTaskStackListener,
                 mMainExecutor));
         mShellTaskOrganizer = new ShellTaskOrganizer(mMainExecutor, mContext,
-                null /* sizeCompatUI */, Optional.of(mRecentTasksController));
+                null /* sizeCompatUI */, Optional.empty(), Optional.of(mRecentTasksController));
     }
 
     @Test
@@ -89,7 +89,7 @@
         ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
         setRawList(t1, t2);
 
-        mRecentTasksController.addSplitPair(t1.taskId, t2.taskId, mock(StagedSplitBounds.class));
+        mRecentTasksController.addSplitPair(t1.taskId, t2.taskId, mock(SplitBounds.class));
         verify(mRecentTasksController).notifyRecentTasksChanged();
 
         reset(mRecentTasksController);
@@ -104,10 +104,10 @@
         setRawList(t1, t2);
 
         // Verify only one update if the split info is the same
-        StagedSplitBounds bounds1 = new StagedSplitBounds(new Rect(0, 0, 50, 50),
+        SplitBounds bounds1 = new SplitBounds(new Rect(0, 0, 50, 50),
                 new Rect(50, 50, 100, 100), t1.taskId, t2.taskId);
         mRecentTasksController.addSplitPair(t1.taskId, t2.taskId, bounds1);
-        StagedSplitBounds bounds2 = new StagedSplitBounds(new Rect(0, 0, 50, 50),
+        SplitBounds bounds2 = new SplitBounds(new Rect(0, 0, 50, 50),
                 new Rect(50, 50, 100, 100), t1.taskId, t2.taskId);
         mRecentTasksController.addSplitPair(t1.taskId, t2.taskId, bounds2);
         verify(mRecentTasksController, times(1)).notifyRecentTasksChanged();
@@ -139,8 +139,8 @@
         setRawList(t1, t2, t3, t4, t5, t6);
 
         // Mark a couple pairs [t2, t4], [t3, t5]
-        StagedSplitBounds pair1Bounds = new StagedSplitBounds(new Rect(), new Rect(), 2, 4);
-        StagedSplitBounds pair2Bounds = new StagedSplitBounds(new Rect(), new Rect(), 3, 5);
+        SplitBounds pair1Bounds = new SplitBounds(new Rect(), new Rect(), 2, 4);
+        SplitBounds pair2Bounds = new SplitBounds(new Rect(), new Rect(), 3, 5);
 
         mRecentTasksController.addSplitPair(t2.taskId, t4.taskId, pair1Bounds);
         mRecentTasksController.addSplitPair(t3.taskId, t5.taskId, pair2Bounds);
@@ -162,7 +162,7 @@
         setRawList(t1, t2, t3);
 
         // Add a pair
-        StagedSplitBounds pair1Bounds = new StagedSplitBounds(new Rect(), new Rect(), 2, 3);
+        SplitBounds pair1Bounds = new SplitBounds(new Rect(), new Rect(), 2, 3);
         mRecentTasksController.addSplitPair(t2.taskId, t3.taskId, pair1Bounds);
         reset(mRecentTasksController);
 
@@ -245,15 +245,15 @@
                     : -1;
 
             if (pair.mTaskInfo2 != null) {
-                assertNotNull(pair.mStagedSplitBounds);
-                int leftTopTaskId = pair.mStagedSplitBounds.leftTopTaskId;
-                int bottomRightTaskId = pair.mStagedSplitBounds.rightBottomTaskId;
+                assertNotNull(pair.mSplitBounds);
+                int leftTopTaskId = pair.mSplitBounds.leftTopTaskId;
+                int bottomRightTaskId = pair.mSplitBounds.rightBottomTaskId;
                 // Unclear if pairs are ordered by split position, most likely not.
                 assertTrue(leftTopTaskId == taskId1 || leftTopTaskId == pair.mTaskInfo2.taskId);
                 assertTrue(bottomRightTaskId == taskId1
                         || bottomRightTaskId == pair.mTaskInfo2.taskId);
             } else {
-                assertNull(pair.mStagedSplitBounds);
+                assertNull(pair.mSplitBounds);
             }
         }
         assertTrue("Expected: " + Arrays.toString(expectedTaskIds)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/StagedSplitBoundsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java
similarity index 84%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/StagedSplitBoundsTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java
index ad73c56..068a60a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/StagedSplitBoundsTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/SplitBoundsTest.java
@@ -9,7 +9,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.wm.shell.util.StagedSplitBounds;
+import com.android.wm.shell.util.SplitBounds;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -17,7 +17,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-public class StagedSplitBoundsTest {
+public class SplitBoundsTest {
     private static final int DEVICE_WIDTH = 100;
     private static final int DEVICE_LENGTH = 200;
     private static final int DIVIDER_SIZE = 20;
@@ -42,21 +42,21 @@
 
     @Test
     public void testVerticalStacked() {
-        StagedSplitBounds ssb = new StagedSplitBounds(mTopRect, mBottomRect,
+        SplitBounds ssb = new SplitBounds(mTopRect, mBottomRect,
                 TASK_ID_1, TASK_ID_2);
         assertTrue(ssb.appsStackedVertically);
     }
 
     @Test
     public void testHorizontalStacked() {
-        StagedSplitBounds ssb = new StagedSplitBounds(mLeftRect, mRightRect,
+        SplitBounds ssb = new SplitBounds(mLeftRect, mRightRect,
                 TASK_ID_1, TASK_ID_2);
         assertFalse(ssb.appsStackedVertically);
     }
 
     @Test
     public void testHorizontalDividerBounds() {
-        StagedSplitBounds ssb = new StagedSplitBounds(mTopRect, mBottomRect,
+        SplitBounds ssb = new SplitBounds(mTopRect, mBottomRect,
                 TASK_ID_1, TASK_ID_2);
         Rect dividerBounds = ssb.visualDividerBounds;
         assertEquals(0, dividerBounds.left);
@@ -67,7 +67,7 @@
 
     @Test
     public void testVerticalDividerBounds() {
-        StagedSplitBounds ssb = new StagedSplitBounds(mLeftRect, mRightRect,
+        SplitBounds ssb = new SplitBounds(mLeftRect, mRightRect,
                 TASK_ID_1, TASK_ID_2);
         Rect dividerBounds = ssb.visualDividerBounds;
         assertEquals(DEVICE_WIDTH / 2 - DIVIDER_SIZE / 2, dividerBounds.left);
@@ -78,7 +78,7 @@
 
     @Test
     public void testEqualVerticalTaskPercent() {
-        StagedSplitBounds ssb = new StagedSplitBounds(mTopRect, mBottomRect,
+        SplitBounds ssb = new SplitBounds(mTopRect, mBottomRect,
                 TASK_ID_1, TASK_ID_2);
         float topPercentSpaceTaken = (float) (DEVICE_LENGTH / 2 - DIVIDER_SIZE / 2) / DEVICE_LENGTH;
         assertEquals(topPercentSpaceTaken, ssb.topTaskPercent, 0.01);
@@ -86,7 +86,7 @@
 
     @Test
     public void testEqualHorizontalTaskPercent() {
-        StagedSplitBounds ssb = new StagedSplitBounds(mLeftRect, mRightRect,
+        SplitBounds ssb = new SplitBounds(mLeftRect, mRightRect,
                 TASK_ID_1, TASK_ID_2);
         float leftPercentSpaceTaken = (float) (DEVICE_WIDTH / 2 - DIVIDER_SIZE / 2) / DEVICE_WIDTH;
         assertEquals(leftPercentSpaceTaken, ssb.leftTaskPercent, 0.01);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java
index 0639ad5..68cb57c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java
@@ -61,7 +61,7 @@
         MockitoAnnotations.initMocks(this);
         mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
         mMainStage = new MainStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mCallbacks,
-                mSyncQueue, mSurfaceSession, mIconProvider, null);
+                mSyncQueue, mSurfaceSession, mIconProvider);
         mMainStage.onTaskAppeared(mRootTaskInfo, mRootLeash);
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
index a31aa58..3b42a48 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SideStageTests.java
@@ -66,7 +66,7 @@
         MockitoAnnotations.initMocks(this);
         mRootTask = new TestRunningTaskInfoBuilder().build();
         mSideStage = new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mCallbacks,
-                mSyncQueue, mSurfaceSession, mIconProvider, null);
+                mSyncQueue, mSurfaceSession, mIconProvider);
         mSideStage.onTaskAppeared(mRootTask, mRootLeash);
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
index eb9d3a1..a67853c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTestUtils.java
@@ -40,8 +40,6 @@
 
 import java.util.Optional;
 
-import javax.inject.Provider;
-
 public class SplitTestUtils {
 
     static SplitLayout createMockSplitLayout() {
@@ -74,12 +72,10 @@
                 DisplayInsetsController insetsController, SplitLayout splitLayout,
                 Transitions transitions, TransactionPool transactionPool,
                 SplitscreenEventLogger logger, ShellExecutor mainExecutor,
-                Optional<RecentTasksController> recentTasks,
-                Provider<Optional<StageTaskUnfoldController>> unfoldController) {
+                Optional<RecentTasksController> recentTasks) {
             super(context, displayId, syncQueue, taskOrganizer, mainStage,
                     sideStage, displayController, imeController, insetsController, splitLayout,
-                    transitions, transactionPool, logger, mainExecutor, recentTasks,
-                    unfoldController);
+                    transitions, transactionPool, logger, mainExecutor, recentTasks);
 
             // Prepare root task for testing.
             mRootTask = new TestRunningTaskInfoBuilder().build();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index ffaab65..304ca66 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -118,16 +118,16 @@
         mSplitLayout = SplitTestUtils.createMockSplitLayout();
         mMainStage = new MainStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
                 StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
-                mIconProvider, null);
+                mIconProvider);
         mMainStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
         mSideStage = new SideStage(mContext, mTaskOrganizer, DEFAULT_DISPLAY, mock(
                 StageTaskListener.StageListenerCallbacks.class), mSyncQueue, mSurfaceSession,
-                mIconProvider, null);
+                mIconProvider);
         mSideStage.onTaskAppeared(new TestRunningTaskInfoBuilder().build(), createMockSurface());
         mStageCoordinator = new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
                 mSyncQueue, mTaskOrganizer, mMainStage, mSideStage, mDisplayController,
                 mDisplayImeController, mDisplayInsetsController, mSplitLayout, mTransitions,
-                mTransactionPool, mLogger, mMainExecutor, Optional.empty(), Optional::empty);
+                mTransactionPool, mLogger, mMainExecutor, Optional.empty());
         mSplitScreenTransitions = mStageCoordinator.getSplitTransitions();
         doAnswer((Answer<IBinder>) invocation -> mock(IBinder.class))
                 .when(mTransitions).startTransition(anyInt(), any(), any());
@@ -340,7 +340,7 @@
         TransitionInfo info = new TransitionInfo(TRANSIT_TO_BACK, 0);
         info.addChange(mainChange);
         info.addChange(sideChange);
-        IBinder transition = mSplitScreenTransitions.startDismissTransition(null,
+        IBinder transition = mSplitScreenTransitions.startDismissTransition(
                 new WindowContainerTransaction(), mStageCoordinator,
                 EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW, STAGE_TYPE_SIDE);
         boolean accepted = mStageCoordinator.startAnimation(transition, info,
@@ -363,7 +363,7 @@
         TransitionInfo info = new TransitionInfo(TRANSIT_TO_BACK, 0);
         info.addChange(mainChange);
         info.addChange(sideChange);
-        IBinder transition = mSplitScreenTransitions.startDismissTransition(null,
+        IBinder transition = mSplitScreenTransitions.startDismissTransition(
                 new WindowContainerTransaction(), mStageCoordinator, EXIT_REASON_DRAG_DIVIDER,
                 STAGE_TYPE_SIDE);
         mMainStage.onTaskVanished(mMainChild);
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 42d998f..af2c495 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
@@ -34,6 +34,7 @@
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -58,6 +59,7 @@
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.common.split.SplitLayout;
+import com.android.wm.shell.splitscreen.SplitScreen.SplitScreenListener;
 import com.android.wm.shell.transition.Transitions;
 
 import org.junit.Before;
@@ -68,8 +70,6 @@
 
 import java.util.Optional;
 
-import javax.inject.Provider;
-
 /**
  * Tests for {@link StageCoordinator}
  */
@@ -85,10 +85,6 @@
     @Mock
     private SideStage mSideStage;
     @Mock
-    private StageTaskUnfoldController mMainUnfoldController;
-    @Mock
-    private StageTaskUnfoldController mSideUnfoldController;
-    @Mock
     private SplitLayout mSplitLayout;
     @Mock
     private DisplayController mDisplayController;
@@ -107,6 +103,7 @@
 
     private final Rect mBounds1 = new Rect(10, 20, 30, 40);
     private final Rect mBounds2 = new Rect(5, 10, 15, 20);
+    private final Rect mRootBounds = new Rect(0, 0, 45, 60);
 
     private SurfaceSession mSurfaceSession = new SurfaceSession();
     private SurfaceControl mRootLeash;
@@ -119,11 +116,12 @@
         mStageCoordinator = spy(new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
                 mTaskOrganizer, mMainStage, mSideStage, mDisplayController, mDisplayImeController,
                 mDisplayInsetsController, mSplitLayout, mTransitions, mTransactionPool, mLogger,
-                mMainExecutor, Optional.empty(), new UnfoldControllerProvider()));
+                mMainExecutor, Optional.empty()));
         doNothing().when(mStageCoordinator).updateActivityOptions(any(), anyInt());
 
         when(mSplitLayout.getBounds1()).thenReturn(mBounds1);
         when(mSplitLayout.getBounds2()).thenReturn(mBounds2);
+        when(mSplitLayout.getRootBounds()).thenReturn(mRootBounds);
         when(mSplitLayout.isLandscape()).thenReturn(false);
 
         mRootTask = new TestRunningTaskInfoBuilder().build();
@@ -168,13 +166,6 @@
     }
 
     @Test
-    public void testRootTaskAppeared_initializesUnfoldControllers() {
-        verify(mMainUnfoldController).init();
-        verify(mSideUnfoldController).init();
-        verify(mStageCoordinator).onRootTaskAppeared();
-    }
-
-    @Test
     public void testRootTaskInfoChanged_updatesSplitLayout() {
         mStageCoordinator.onTaskInfoChanged(mRootTask);
 
@@ -184,26 +175,25 @@
     @Test
     public void testLayoutChanged_topLeftSplitPosition_updatesUnfoldStageBounds() {
         mStageCoordinator.setSideStagePosition(SPLIT_POSITION_TOP_OR_LEFT, null);
-        clearInvocations(mMainUnfoldController, mSideUnfoldController);
+        final SplitScreenListener listener = mock(SplitScreenListener.class);
+        mStageCoordinator.registerSplitScreenListener(listener);
+        clearInvocations(listener);
 
         mStageCoordinator.onLayoutSizeChanged(mSplitLayout);
 
-        verify(mMainUnfoldController).onLayoutChanged(mBounds2, SPLIT_POSITION_BOTTOM_OR_RIGHT,
-                false);
-        verify(mSideUnfoldController).onLayoutChanged(mBounds1, SPLIT_POSITION_TOP_OR_LEFT, false);
+        verify(listener).onSplitBoundsChanged(mRootBounds, mBounds2, mBounds1);
     }
 
     @Test
     public void testLayoutChanged_bottomRightSplitPosition_updatesUnfoldStageBounds() {
         mStageCoordinator.setSideStagePosition(SPLIT_POSITION_BOTTOM_OR_RIGHT, null);
-        clearInvocations(mMainUnfoldController, mSideUnfoldController);
+        final SplitScreenListener listener = mock(SplitScreenListener.class);
+        mStageCoordinator.registerSplitScreenListener(listener);
+        clearInvocations(listener);
 
         mStageCoordinator.onLayoutSizeChanged(mSplitLayout);
 
-        verify(mMainUnfoldController).onLayoutChanged(mBounds1, SPLIT_POSITION_TOP_OR_LEFT,
-                false);
-        verify(mSideUnfoldController).onLayoutChanged(mBounds2, SPLIT_POSITION_BOTTOM_OR_RIGHT,
-                false);
+        verify(listener).onSplitBoundsChanged(mRootBounds, mBounds1, mBounds2);
     }
 
     @Test
@@ -314,20 +304,4 @@
 
         verify(mSplitLayout).applySurfaceChanges(any(), any(), any(), any(), any(), eq(false));
     }
-
-    private class UnfoldControllerProvider implements
-            Provider<Optional<StageTaskUnfoldController>> {
-
-        private boolean isMain = true;
-
-        @Override
-        public Optional<StageTaskUnfoldController> get() {
-            if (isMain) {
-                isMain = false;
-                return Optional.of(mMainUnfoldController);
-            } else {
-                return Optional.of(mSideUnfoldController);
-            }
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
index 157c30b..5ee8bf3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageTaskListenerTests.java
@@ -25,7 +25,6 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeFalse;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -72,8 +71,6 @@
     private SyncTransactionQueue mSyncQueue;
     @Mock
     private IconProvider mIconProvider;
-    @Mock
-    private StageTaskUnfoldController mStageTaskUnfoldController;
     @Captor
     private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor;
     private SurfaceSession mSurfaceSession = new SurfaceSession();
@@ -92,8 +89,7 @@
                 mCallbacks,
                 mSyncQueue,
                 mSurfaceSession,
-                mIconProvider,
-                mStageTaskUnfoldController);
+                mIconProvider);
         mRootTask = new TestRunningTaskInfoBuilder().build();
         mRootTask.parentTaskId = INVALID_TASK_ID;
         mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession).setName("test").build();
@@ -130,30 +126,6 @@
         verify(mCallbacks).onStatusChanged(eq(mRootTask.isVisible), eq(true));
     }
 
-    @Test
-    public void testTaskAppeared_notifiesUnfoldListener() {
-        assumeFalse(ENABLE_SHELL_TRANSITIONS);
-        final ActivityManager.RunningTaskInfo task =
-                new TestRunningTaskInfoBuilder().setParentTaskId(mRootTask.taskId).build();
-
-        mStageTaskListener.onTaskAppeared(task, mSurfaceControl);
-
-        verify(mStageTaskUnfoldController).onTaskAppeared(eq(task), eq(mSurfaceControl));
-    }
-
-    @Test
-    public void testTaskVanished_notifiesUnfoldListener() {
-        assumeFalse(ENABLE_SHELL_TRANSITIONS);
-        final ActivityManager.RunningTaskInfo task =
-                new TestRunningTaskInfoBuilder().setParentTaskId(mRootTask.taskId).build();
-        mStageTaskListener.onTaskAppeared(task, mSurfaceControl);
-        clearInvocations(mStageTaskUnfoldController);
-
-        mStageTaskListener.onTaskVanished(task);
-
-        verify(mStageTaskUnfoldController).onTaskVanished(eq(task));
-    }
-
     @Test(expected = IllegalArgumentException.class)
     public void testUnknownTaskVanished() {
         final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index 630d0d2..14d8ce4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -249,7 +249,8 @@
                 any() /* window */, any() /* attrs */,
                 anyInt() /* viewVisibility */, anyInt() /* displayId */,
                 any() /* requestedVisibility */, any() /* outInputChannel */,
-                any() /* outInsetsState */, any() /* outActiveControls */);
+                any() /* outInsetsState */, any() /* outActiveControls */,
+                any() /* outAttachedFrame */);
         TaskSnapshotWindow mockSnapshotWindow = TaskSnapshotWindow.create(windowInfo,
                 mBinder,
                 snapshot, mTestExecutor, () -> {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java
new file mode 100644
index 0000000..46de607
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldAnimationControllerTest.java
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.unfold;
+
+import static com.android.wm.shell.unfold.UnfoldAnimationControllerTest.TestUnfoldTaskAnimator.UNSET;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.TaskInfo;
+import android.testing.AndroidTestingRunner;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
+
+import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestRunningTaskInfoBuilder;
+import com.android.wm.shell.TestShellExecutor;
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.unfold.animation.UnfoldTaskAnimator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.Predicate;
+
+/**
+ * Tests for {@link UnfoldAnimationController}.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:UnfoldAnimationControllerTest
+ */
+@RunWith(AndroidTestingRunner.class)
+public class UnfoldAnimationControllerTest extends ShellTestCase {
+
+    @Mock
+    private TransactionPool mTransactionPool;
+    @Mock
+    private UnfoldTransitionHandler mUnfoldTransitionHandler;
+    @Mock
+    private SurfaceControl mLeash;
+
+    private UnfoldAnimationController mUnfoldAnimationController;
+
+    private final TestShellUnfoldProgressProvider mProgressProvider =
+            new TestShellUnfoldProgressProvider();
+    private final TestShellExecutor mShellExecutor = new TestShellExecutor();
+
+    private final TestUnfoldTaskAnimator mTaskAnimator1 = new TestUnfoldTaskAnimator();
+    private final TestUnfoldTaskAnimator mTaskAnimator2 = new TestUnfoldTaskAnimator();
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mTransactionPool.acquire()).thenReturn(mock(SurfaceControl.Transaction.class));
+
+        final List<UnfoldTaskAnimator> animators = new ArrayList<>();
+        animators.add(mTaskAnimator1);
+        animators.add(mTaskAnimator2);
+        mUnfoldAnimationController = new UnfoldAnimationController(
+                mTransactionPool,
+                mProgressProvider,
+                animators,
+                () -> Optional.of(mUnfoldTransitionHandler),
+                mShellExecutor
+        );
+    }
+
+    @Test
+    public void testAppearedMatchingTask_appliesUnfoldProgress() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+        RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(2).build();
+
+        mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+
+        mUnfoldAnimationController.onStateChangeProgress(0.5f);
+        assertThat(mTaskAnimator1.mLastAppliedProgress).isEqualTo(0.5f);
+    }
+
+    @Test
+    public void testAppearedMatchingTaskTwoDifferentAnimators_appliesUnfoldProgressToBoth() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 1);
+        mTaskAnimator2.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+        RunningTaskInfo taskInfo1 = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(1).build();
+        RunningTaskInfo taskInfo2 = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(2).build();
+
+        mUnfoldAnimationController.onTaskAppeared(taskInfo1, mLeash);
+        mUnfoldAnimationController.onTaskAppeared(taskInfo2, mLeash);
+
+        mUnfoldAnimationController.onStateChangeProgress(0.5f);
+        assertThat(mTaskAnimator1.mLastAppliedProgress).isEqualTo(0.5f);
+        assertThat(mTaskAnimator2.mLastAppliedProgress).isEqualTo(0.5f);
+    }
+
+    @Test
+    public void testAppearedNonMatchingTask_doesNotApplyUnfoldProgress() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+        RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(0).build();
+
+        mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+
+        mUnfoldAnimationController.onStateChangeProgress(0.5f);
+        assertThat(mTaskAnimator1.mLastAppliedProgress).isEqualTo(UNSET);
+    }
+
+    @Test
+    public void testAppearedAndChangedToNonMatchingTask_doesNotApplyUnfoldProgress() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+        RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(2).build();
+
+        mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(0);
+        mUnfoldAnimationController.onTaskInfoChanged(taskInfo);
+
+        mUnfoldAnimationController.onStateChangeProgress(0.5f);
+        assertThat(mTaskAnimator1.mLastAppliedProgress).isEqualTo(UNSET);
+    }
+
+    @Test
+    public void testAppearedAndChangedToNonMatchingTaskAndBack_appliesUnfoldProgress() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+        RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(2).build();
+
+        mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(0);
+        mUnfoldAnimationController.onTaskInfoChanged(taskInfo);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(2);
+        mUnfoldAnimationController.onTaskInfoChanged(taskInfo);
+
+        mUnfoldAnimationController.onStateChangeProgress(0.5f);
+        assertThat(mTaskAnimator1.mLastAppliedProgress).isEqualTo(0.5f);
+    }
+
+    @Test
+    public void testAppearedNonMatchingTaskAndChangedToMatching_appliesUnfoldProgress() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+        RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(0).build();
+
+        mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(2);
+        mUnfoldAnimationController.onTaskInfoChanged(taskInfo);
+
+        mUnfoldAnimationController.onStateChangeProgress(0.5f);
+        assertThat(mTaskAnimator1.mLastAppliedProgress).isEqualTo(0.5f);
+    }
+
+    @Test
+    public void testAppearedMatchingTaskAndChanged_appliesUnfoldProgress() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+        RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(2).build();
+
+        mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+        mUnfoldAnimationController.onTaskInfoChanged(taskInfo);
+
+        mUnfoldAnimationController.onStateChangeProgress(0.5f);
+        assertThat(mTaskAnimator1.mLastAppliedProgress).isEqualTo(0.5f);
+    }
+
+    @Test
+    public void testShellTransitionRunning_doesNotApplyUnfoldProgress() {
+        when(mUnfoldTransitionHandler.willHandleTransition()).thenReturn(true);
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+        RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(2).build();
+
+        mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+
+        mUnfoldAnimationController.onStateChangeProgress(0.5f);
+        assertThat(mTaskAnimator1.mLastAppliedProgress).isEqualTo(UNSET);
+    }
+
+    @Test
+    public void testApplicableTaskDisappeared_resetsSurface() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 0);
+        RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(0).build();
+        mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+        assertThat(mTaskAnimator1.mResetTasks).doesNotContain(taskInfo.taskId);
+
+        mUnfoldAnimationController.onTaskVanished(taskInfo);
+
+        assertThat(mTaskAnimator1.mResetTasks).contains(taskInfo.taskId);
+    }
+
+    @Test
+    public void testApplicablePinnedTaskDisappeared_doesNotResetSurface() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+        RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(2).build();
+        mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+        assertThat(mTaskAnimator1.mResetTasks).doesNotContain(taskInfo.taskId);
+
+        mUnfoldAnimationController.onTaskVanished(taskInfo);
+
+        assertThat(mTaskAnimator1.mResetTasks).doesNotContain(taskInfo.taskId);
+    }
+
+    @Test
+    public void testNonApplicableTaskAppearedDisappeared_doesNotResetSurface() {
+        mTaskAnimator1.setTaskMatcher((info) -> info.getWindowingMode() == 2);
+        RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
+                .setWindowingMode(0).build();
+
+        mUnfoldAnimationController.onTaskAppeared(taskInfo, mLeash);
+        mUnfoldAnimationController.onTaskVanished(taskInfo);
+
+        assertThat(mTaskAnimator1.mResetTasks).doesNotContain(taskInfo.taskId);
+    }
+
+    @Test
+    public void testInit_initsAndStartsAnimators() {
+        mUnfoldAnimationController.init();
+
+        assertThat(mTaskAnimator1.mInitialized).isTrue();
+        assertThat(mTaskAnimator1.mStarted).isTrue();
+    }
+
+    private static class TestShellUnfoldProgressProvider implements ShellUnfoldProgressProvider,
+            ShellUnfoldProgressProvider.UnfoldListener {
+
+        private final List<UnfoldListener> mListeners = new ArrayList<>();
+
+        @Override
+        public void addListener(Executor executor, UnfoldListener listener) {
+            mListeners.add(listener);
+        }
+
+        @Override
+        public void onStateChangeStarted() {
+            mListeners.forEach(UnfoldListener::onStateChangeStarted);
+        }
+
+        @Override
+        public void onStateChangeProgress(float progress) {
+            mListeners.forEach(unfoldListener -> unfoldListener.onStateChangeProgress(progress));
+        }
+
+        @Override
+        public void onStateChangeFinished() {
+            mListeners.forEach(UnfoldListener::onStateChangeFinished);
+        }
+    }
+
+    public static class TestUnfoldTaskAnimator implements UnfoldTaskAnimator {
+
+        public static final float UNSET = -1f;
+        private Predicate<TaskInfo> mTaskMatcher = (info) -> false;
+
+        Map<Integer, TaskInfo> mTasksMap = new HashMap<>();
+        Set<Integer> mResetTasks = new HashSet<>();
+
+        boolean mInitialized = false;
+        boolean mStarted = false;
+        float mLastAppliedProgress = UNSET;
+
+        @Override
+        public void init() {
+            mInitialized = true;
+        }
+
+        @Override
+        public void start() {
+            mStarted = true;
+        }
+
+        @Override
+        public void stop() {
+            mStarted = false;
+        }
+
+        @Override
+        public boolean isApplicableTask(TaskInfo taskInfo) {
+            return mTaskMatcher.test(taskInfo);
+        }
+
+        @Override
+        public void applyAnimationProgress(float progress, Transaction transaction) {
+            mLastAppliedProgress = progress;
+        }
+
+        public void setTaskMatcher(Predicate<TaskInfo> taskMatcher) {
+            mTaskMatcher = taskMatcher;
+        }
+
+        @Override
+        public void onTaskAppeared(TaskInfo taskInfo, SurfaceControl leash) {
+            mTasksMap.put(taskInfo.taskId, taskInfo);
+        }
+
+        @Override
+        public void onTaskVanished(TaskInfo taskInfo) {
+            mTasksMap.remove(taskInfo.taskId);
+        }
+
+        @Override
+        public void onTaskChanged(TaskInfo taskInfo) {
+            mTasksMap.put(taskInfo.taskId, taskInfo);
+        }
+
+        @Override
+        public void resetSurface(TaskInfo taskInfo, Transaction transaction) {
+            mResetTasks.add(taskInfo.taskId);
+        }
+
+        @Override
+        public void resetAllSurfaces(Transaction transaction) {
+            mTasksMap.values().forEach((t) -> mResetTasks.add(t.taskId));
+        }
+
+        @Override
+        public boolean hasActiveTasks() {
+            return mTasksMap.size() > 0;
+        }
+
+        public List<TaskInfo> getCurrentTasks() {
+            return new ArrayList<>(mTasksMap.values());
+        }
+    }
+}
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index 1e5be6c..4b0ddd2 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -201,8 +201,9 @@
     // If we are in triple buffering, we have enough buffers in queue to sustain a single frame
     // drop without jank, so adjust the frame interval to the deadline.
     if (isTripleBuffered) {
-        deadline += frameInterval;
-        frame.set(FrameInfoIndex::FrameDeadline) += frameInterval;
+        int64_t originalDeadlineDuration = deadline - frame[FrameInfoIndex::IntendedVsync];
+        deadline = mNextFrameStartUnstuffed + originalDeadlineDuration;
+        frame.set(FrameInfoIndex::FrameDeadline) = deadline;
     }
 
     // If we hit the deadline, cool!
diff --git a/libs/hwui/tests/unit/JankTrackerTests.cpp b/libs/hwui/tests/unit/JankTrackerTests.cpp
index 5b397de..b67e419 100644
--- a/libs/hwui/tests/unit/JankTrackerTests.cpp
+++ b/libs/hwui/tests/unit/JankTrackerTests.cpp
@@ -195,3 +195,68 @@
     ASSERT_EQ(3, container.get()->totalFrameCount());
     ASSERT_EQ(2, container.get()->jankFrameCount());
 }
+
+TEST(JankTracker, doubleStuffedTwoIntervalBehind) {
+    std::mutex mutex;
+    ProfileDataContainer container(mutex);
+    JankTracker jankTracker(&container);
+    std::unique_ptr<FrameMetricsReporter> reporter = std::make_unique<FrameMetricsReporter>();
+
+    uint64_t frameNumber = 0;
+    uint32_t surfaceId = 0;
+
+    // First frame janks
+    FrameInfo* info = jankTracker.startFrame();
+    info->set(FrameInfoIndex::IntendedVsync) = 100_ms;
+    info->set(FrameInfoIndex::Vsync) = 101_ms;
+    info->set(FrameInfoIndex::SwapBuffersCompleted) = 107_ms;
+    info->set(FrameInfoIndex::GpuCompleted) = 117_ms;
+    info->set(FrameInfoIndex::FrameCompleted) = 117_ms;
+    info->set(FrameInfoIndex::FrameInterval) = 16_ms;
+    info->set(FrameInfoIndex::FrameDeadline) = 116_ms;
+    jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
+
+    ASSERT_EQ(1, container.get()->jankFrameCount());
+
+    // Second frame is long, but doesn't jank because double-stuffed.
+    // Second frame duration is between 1*interval ~ 2*interval
+    info = jankTracker.startFrame();
+    info->set(FrameInfoIndex::IntendedVsync) = 116_ms;
+    info->set(FrameInfoIndex::Vsync) = 116_ms;
+    info->set(FrameInfoIndex::SwapBuffersCompleted) = 129_ms;
+    info->set(FrameInfoIndex::GpuCompleted) = 133_ms;
+    info->set(FrameInfoIndex::FrameCompleted) = 133_ms;
+    info->set(FrameInfoIndex::FrameInterval) = 16_ms;
+    info->set(FrameInfoIndex::FrameDeadline) = 132_ms;
+    jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
+
+    ASSERT_EQ(1, container.get()->jankFrameCount());
+
+    // Third frame is even longer, cause a jank
+    // Third frame duration is between 2*interval ~ 3*interval
+    info = jankTracker.startFrame();
+    info->set(FrameInfoIndex::IntendedVsync) = 132_ms;
+    info->set(FrameInfoIndex::Vsync) = 132_ms;
+    info->set(FrameInfoIndex::SwapBuffersCompleted) = 160_ms;
+    info->set(FrameInfoIndex::GpuCompleted) = 165_ms;
+    info->set(FrameInfoIndex::FrameCompleted) = 165_ms;
+    info->set(FrameInfoIndex::FrameInterval) = 16_ms;
+    info->set(FrameInfoIndex::FrameDeadline) = 148_ms;
+    jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
+
+    ASSERT_EQ(2, container.get()->jankFrameCount());
+
+    // 4th frame is double-stuffed with a 2 * interval latency
+    // 4th frame duration is between 2*interval ~ 3*interval
+    info = jankTracker.startFrame();
+    info->set(FrameInfoIndex::IntendedVsync) = 148_ms;
+    info->set(FrameInfoIndex::Vsync) = 148_ms;
+    info->set(FrameInfoIndex::SwapBuffersCompleted) = 170_ms;
+    info->set(FrameInfoIndex::GpuCompleted) = 181_ms;
+    info->set(FrameInfoIndex::FrameCompleted) = 181_ms;
+    info->set(FrameInfoIndex::FrameInterval) = 16_ms;
+    info->set(FrameInfoIndex::FrameDeadline) = 164_ms;
+    jankTracker.finishFrame(*info, reporter, frameNumber, surfaceId);
+
+    ASSERT_EQ(2, container.get()->jankFrameCount());
+}
diff --git a/media/java/android/media/projection/IMediaProjection.aidl b/media/java/android/media/projection/IMediaProjection.aidl
index b136d5b..2bdd5c8 100644
--- a/media/java/android/media/projection/IMediaProjection.aidl
+++ b/media/java/android/media/projection/IMediaProjection.aidl
@@ -17,7 +17,7 @@
 package android.media.projection;
 
 import android.media.projection.IMediaProjectionCallback;
-import android.window.WindowContainerToken;
+import android.os.IBinder;
 
 /** {@hide} */
 interface IMediaProjection {
@@ -31,14 +31,14 @@
     void unregisterCallback(IMediaProjectionCallback callback);
 
     /**
-     * Returns the {@link android.window.WindowContainerToken} identifying the task to record, or
-     * {@code null} if there is none.
+     * Returns the {@link android.os.IBinder} identifying the task to record, or {@code null} if
+     * there is none.
      */
-    WindowContainerToken getTaskRecordingWindowContainerToken();
+    IBinder getLaunchCookie();
 
     /**
-     * Updates the {@link android.window.WindowContainerToken} identifying the task to record, or
-     * {@code null} if there is none.
+     * Updates the {@link android.os.IBinder} identifying the task to record, or {@code null} if
+     * there is none.
      */
-    void setTaskRecordingWindowContainerToken(in WindowContainerToken token);
+    void setLaunchCookie(in IBinder launchCookie);
 }
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index ba7bf3f..ae44fc5 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -25,13 +25,13 @@
 import android.hardware.display.VirtualDisplay;
 import android.hardware.display.VirtualDisplayConfig;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.ContentRecordingSession;
 import android.view.Surface;
-import android.window.WindowContainerToken;
 
 import java.util.Map;
 
@@ -172,18 +172,16 @@
             @NonNull VirtualDisplayConfig.Builder virtualDisplayConfig,
             @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
         try {
-            final WindowContainerToken taskWindowContainerToken =
-                    mImpl.getTaskRecordingWindowContainerToken();
+            final IBinder launchCookie = mImpl.getLaunchCookie();
             Context windowContext = null;
             ContentRecordingSession session;
-            if (taskWindowContainerToken == null) {
+            if (launchCookie == null) {
                 windowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(),
                         TYPE_APPLICATION, null /* options */);
                 session = ContentRecordingSession.createDisplaySession(
                         windowContext.getWindowContextToken());
             } else {
-                session = ContentRecordingSession.createTaskSession(
-                        taskWindowContainerToken.asBinder());
+                session = ContentRecordingSession.createTaskSession(launchCookie);
             }
             virtualDisplayConfig.setWindowManagerMirroring(true);
             final DisplayManager dm = mContext.getSystemService(DisplayManager.class);
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 9a80b02..87e61b5 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -50,6 +50,7 @@
         "SettingsLibTwoTargetPreference",
         "SettingsLibSettingsTransition",
         "SettingsLibButtonPreference",
+        "SettingsLibDeviceStateRotationLock",
         "setupdesign",
         "zxing-core-1.7",
     ],
diff --git a/packages/SettingsLib/DeviceStateRotationLock/Android.bp b/packages/SettingsLib/DeviceStateRotationLock/Android.bp
new file mode 100644
index 0000000..c642bd1
--- /dev/null
+++ b/packages/SettingsLib/DeviceStateRotationLock/Android.bp
@@ -0,0 +1,16 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_library {
+    name: "SettingsLibDeviceStateRotationLock",
+
+    srcs: ["src/**/*.java"],
+
+    min_sdk_version: "21",
+}
diff --git a/packages/SettingsLib/DeviceStateRotationLock/AndroidManifest.xml b/packages/SettingsLib/DeviceStateRotationLock/AndroidManifest.xml
new file mode 100644
index 0000000..bce6599
--- /dev/null
+++ b/packages/SettingsLib/DeviceStateRotationLock/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.settingslib.devicestate">
+
+</manifest>
diff --git a/packages/SettingsLib/src/com/android/settingslib/devicestate/AndroidSecureSettings.java b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/AndroidSecureSettings.java
similarity index 100%
rename from packages/SettingsLib/src/com/android/settingslib/devicestate/AndroidSecureSettings.java
rename to packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/AndroidSecureSettings.java
diff --git a/packages/SettingsLib/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManager.java b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
similarity index 100%
rename from packages/SettingsLib/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManager.java
rename to packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
diff --git a/packages/SettingsLib/src/com/android/settingslib/devicestate/SecureSettings.java b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/SecureSettings.java
similarity index 100%
rename from packages/SettingsLib/src/com/android/settingslib/devicestate/SecureSettings.java
rename to packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/SecureSettings.java
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 1992c9b..0aa3245 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laai tans vinnig"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Laai tans stadig"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Laai tans draadloos"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Laaidok"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Laai nie"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Gekoppel, laai nie"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Gelaai"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Stel terug"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Verwyder"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Stel tans gassessie terug …"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Stel gastesessie terug?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Dit sal ’n nuwe gastesessie begin en alle programme en data van die huidige sessie uitvee"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Verlaat gasmodus?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Dit sal programme en data in die huidige gastesessie uitvee"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Gaan uit"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Stoor gasaktiwiteit?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Jy kan aktiwiteit in die huidige sessie stoor of alle programme en data uitvee"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Vee uit"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Stoor"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Verlaat gasmodus"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Stel jou gastesessie terug"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Verlaat gasmodus"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Alle aktiwiteit sal uitgevee word wanneer jy uitgaan"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Jy kan jou aktiwiteit stoor of uitvee wanneer jy uitgaan"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Stel terug om aktiwiteit nou uit te vee, of stoor of vee aktiwiteit uit wanneer jy uitgaan"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Neem \'n foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Kies \'n prent"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Kies foto"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index b5982ae..7f1e6f8 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ኃይል በፍጥነት በመሙላት ላይ"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ኃይል በዝግታ በመሙላት ላይ"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"በገመድ-አልባ ኃይል በመሙላት ላይ"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"የኃይል መሙያ መትከያ"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ባትሪ እየሞላ አይደለም"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ተገናኝቷል፣ ኃይል በመሙላት ላይ አይደለም"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ባትሪ ሞልቷል"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ዳግም አስጀምር"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"አስወግድ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"እንግዳን ዳግም በማስጀመር ላይ…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"የእንግዳ ክፍለ-ጊዜ ዳግም ይጀመር?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ይህ አዲስ የእንግዳ ክፍለ-ጊዜ ይጀምራል እና ሁሉንም መተግበሪያዎች እና ውሂብ አሁን ካለው ክፍለ-ጊዜ ይሰርዛል"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ከእንግዳ ሁኔታ ይውጣ?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ይህ አሁን ካለው የእንግዳ ክፍለ-ጊዜ መተግበሪያዎችን እና ውሂብን ይሰርዛል"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ውጣ"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"የእንግዳ እንቅስቃሴ ይቀመጥ?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"እንቅስቃሴን አሁን ካለው ክፍለ-ጊዜ ማስቀመጥ ወይም ሁሉንም መተግበሪያዎች እና ውሂብ መሰረዝ ይችላሉ"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ሰርዝ"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"አስቀምጥ"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"ከእንግዳ ሁኔታ ውጣ"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"የእንግዳ ክፍለ-ጊዜን ዳግም አስጀምር"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"እንግዳ ያስወጡ"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"በሚወጡበት ጊዜ ሁሉም እንቅስቃሴዎች ይሰረዛሉ"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"በሚወጡበት ጊዜ እንቅስቃሴዎን ማስቀመጥ ወይም መሰረዝ ይችላሉ"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"የክፍለ-ጊዜ እንቅስቃሴን አሁን ለመሰረዝ ዳግም ያስጀምሩ፣ ወይም በሚወጡበት ጊዜ እንቅስቃሴን ማስቀመጥ ወይም መሰረዝ ይችላሉ"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ፎቶ አንሳ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ምስል ይምረጡ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ፎቶ ይምረጡ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index cef5d43..3bda387 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"جارٍ الشحن سريعًا"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"جارٍ الشحن ببطء"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"جارٍ الشحن لاسلكيًا"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"وحدة الإرساء للشحن"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"لا يتم الشحن"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"الجهاز متصل بالشاحن، ولا يتم الشحن."</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"مشحونة"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"إعادة الضبط"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"إزالة"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"جارٍ إعادة ضبط جلسة الضيف…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"هل تريد إعادة ضبط جلسة الضيف؟"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"سيؤدي إجراء إعادة الضبط إلى بدء جلسة ضيف جديدة وحذف جميع التطبيقات والبيانات من الجلسة الحالية."</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"هل تريد الخروج من وضع الضيف؟"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"سيؤدي الخروج من وضع الضيف إلى حذف التطبيقات والبيانات من جلسة الضيف الحالية."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"خروج"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"هل تريد حفظ النشاط في وضع الضيف؟"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"يمكنك حفظ نشاط من الجلسة الحالية أو حذف كلّ التطبيقات والبيانات."</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"حذف"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"حِفظ"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"الخروج من وضع الضيف"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"إعادة ضبط جلسة الضيف"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"الخروج من وضع الضيف"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"سيتم حذف جميع الأنشطة عند الخروج من وضع الضيف."</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"يمكنك حفظ نشاطك أو حذفه عند الخروج من وضع الضيف."</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"يمكنك إجراء إعادة ضبط لحذف نشاط الجلسة الآن، أو حِفظ النشاط أو حذفه عند الخروج من وضع الضيف."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"التقاط صورة"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"اختيار صورة"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"اختيار صورة"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 89cf67e..a2d5c14 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"দ্ৰুততাৰে চাৰ্জ হৈছে"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"লাহে লাহে চাৰ্জ হৈছে"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"বেতাঁৰৰ মাধ্যমেৰে চাৰ্জ হৈ আছে"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"চাৰ্জিং ড’ক"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"চ্চাৰ্জ কৰা নাই"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"সংযোগ হৈ আছে, চাৰ্জ হৈ থকা নাই"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"চাৰ্জ হ’ল"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ৰিছেট কৰক"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"আঁতৰাওক"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"অতিথিৰ ছেশ্বন ৰিছেট কৰি থকা হৈছে…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"অতিথিৰ ছেশ্বন ৰিছেট কৰিবনে?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"এইটোৱে এটা অতিথিৰ ছেশ্বন আৰম্ভ কৰিব আৰু বৰ্তমানৰ ছেশ্বনটোৰ পৰা আটাইবোৰ এপ্ আৰু ডেটা মচিব"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"অতিথি ম’ডৰ পৰা বাহিৰ হ’বনে?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"এইটোৱে বৰ্তমানৰ অতিথিৰ ছেশ্বনটোৰ পৰা এপ্ আৰু ডেটা মচিব"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"বাহিৰ হওক"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"অতিথিৰ কাৰ্যকলাপ ছেভ কৰিবনে?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"আপুনি বৰ্তমানৰ ছেশ্বনটোৰ পৰা কাৰ্যকলাপ ছেভ কৰিব পাৰে অথবা আটাইবোৰ এপ্ আৰু ডেটা মচিব পাৰে"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"মচক"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"ছেভ কৰক"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"অতিথি ম’ডৰ পৰা বাহিৰ হওক"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"অতিথিৰ ছেশ্বন ৰিছেট কৰক"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"অতিথিৰ ছেশ্বনৰ পৰা বাহিৰ হওক"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"বাহিৰ হওঁতে আটাইবোৰ কাৰ্যকলাপ মচা হ’ব"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"আপুনি বাহিৰ হওঁতে নিজৰ কাৰ্যকলাপ ছেভ কৰিব অথবা মচিব পাৰে"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"এতিয়াই ছেশ্বনৰ কাৰ্যকলাপ ৰিছেট কৰক অথবা মচক অথবা আপুনি বাহিৰ হওঁতে কাৰ্যকলাপ ছেভ কৰিব অথবা মচিব পাৰে"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"এখন ফট’ তোলক"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ফট’ বাছনি কৰক"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index ca894e6..33c3e6a 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Sürətlə doldurulur"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Asta doldurulur"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Simsiz şarj edilir"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Şarj Doku"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Doldurulmur"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Qoşulub, şarj edilmir"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Şarj edilib"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Sıfırlayın"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Silin"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Qonaq məlumatı sıfırlanır…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Qonaq sessiyası sıfırlansın?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Bu, yeni qonaq sessiyası başladacaq və cari sessiyadan bütün tətbiqləri və datanı siləcək"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Qonaq rejimindən çıxılsın?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Bununla cari qonaq sessiyasındakı bütün tətbiqlər və data silinəcək"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Çıxın"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Qonaq fəaliyyəti saxlansın?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Cari sessiyadakı fəaliyyəti saxlaya və ya bütün tətbiq və datanı silə bilərsiniz"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Silin"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Yadda saxlayın"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Qonaq rejimindən çıxın"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Qonaq sessiyasını sıfırlayın"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Qonaq rejimindən çıxın"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Çıxış zamanı bütün fəaliyyətlər silinəcək"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Çıxışda fəaliyyətinizi saxlaya və ya silə bilərsiniz"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Sessiya fəaliyyətini indi silmək üçün sıfırlayın və ya çıxışda fəaliyyəti saxlaya və ya silə bilərsiniz"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Foto çəkin"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Şəkil seçin"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Foto seçin"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 175842e..fb202d3 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo se puni"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Sporo se puni"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Bežično punjenje"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Stanica za punjenje"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Povezano, ne puni se"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Napunjeno"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetuj"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ukloni"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Sesija gosta se resetuje…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Želite da resetujete sesiju gosta?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Time ćete pokrenuti novu sesiju gosta i izbrisati sve aplikacije i podatke iz aktuelne sesije"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Izaći ćete iz režima gosta?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Time ćete izbrisati sve aplikacije i podatke iz aktuelne sesije gosta"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Izađi"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Sačuvaćete aktivnosti gosta?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Sačuvajte aktivnosti iz aktuelne sesije ili izbrišite sve aplikacije i podatke"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Izbriši"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Sačuvaj"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Izađi iz režima gosta"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Resetuj sesiju gosta"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Izađi iz režima gosta"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sve aktivnosti će biti izbrisane pri izlazu"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Možete da sačuvate ili izbrišete aktivnosti pri izlazu"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetujete za brisanje aktivnosti sesije, ili sačuvajte ili izbrišite aktivnosti pri izlazu"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Izaberite sliku"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 9bb441a..12b8f1b 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Хуткая зарадка"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Павольная зарадка"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Бесправадная зарадка"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Зарадная док-станцыя"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не зараджаецца"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Падключана, не зараджаецца"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Зараджаны"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Скінуць"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Выдаліць"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Ідзе скід гасцявога сеанса…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Скінуць гасцявы сеанс?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Будзе запушчаны новы гасцявы сеанс. Усе праграмы і даныя бягучага сеанса будуць выдалены"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Выйсці з гасцявога рэжыму?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Будуць выдалены праграмы і даныя бягучага гасцявога сеанса"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Выйсці"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Захаваць дзеянні госця?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Можна захаваць даныя пра дзеянні ў бягучым сеансе ці выдаліць праграмы і даныя"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Выдаліць"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Захаваць"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Выйсці з гасцявога рэжыму"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Скінуць гасцявы сеанс"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Выйсці з гасцявога рэжыму"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Падчас выхаду будуць выдалены ўсе звесткі пра дзеянні"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Падчас выхаду можна захаваць ці выдаліць звесткі пра дзеянні"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Скіньце звесткі пра дзеянні падчас сеанса зараз. Вы таксама можаце захаваць ці выдаліць іх у час выхаду."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Зрабіць фота"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбраць відарыс"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Выбраць фота"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 96ff08b..b8fe104 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Зарежда се бързо"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Зарежда се бавно"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Зарежда се безжично"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Докинг станция за зарежд."</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не се зарежда"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Свързано, не се зарежда"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Заредена"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Нулиране"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Премахване"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Сесията като гост се нулира…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Да се нулира ли сесията като гост?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Така ще стартирате нова сесия като гост и ще изтриете всички приложения и данни от текущата сесия"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Изход от режима на гост?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Така ще изтриете приложенията и данните от текущата сесия като гост"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Изход"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Запазване на активността като гост?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Можете да запазите активността от сесията или да изтриете всички прил. и данни"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Изтриване"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Запазване"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Изход от режима на гост"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Нулиране на сесията като гост"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Изход от сесията като гост"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Цялата активност ще бъде изтрита при изход"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"При изход можете да запазите активността или да я изтриете"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Нулирайте, за да изтриете активността в сесията сега. Можете също да я запазите или изтриете при изход"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Правене на снимка"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Избиране на изображение"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Избиране на снимката"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 9cc930f..abcd1f4 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"দ্রুত চার্জ হচ্ছে"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ধীরে চার্জ হচ্ছে"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"কেবল ছাড়া চার্জ হচ্ছে"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"চার্জিং ডক"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"চার্জ হচ্ছে না"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"কানেক্ট করা থাকলেও চার্জ করা হচ্ছে না"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"চার্জ হয়েছে"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"রিসেট করুন"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"সরান"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"গেস্ট সেশন রিসেট করা হচ্ছে..."</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"অতিথি সেশন রিসেট করতে চান?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"এটি নতুন অতিথি সেশন চালু করবে এবং বর্তমান সেশন থেকে সব অ্যাপ ও ডেটা মুছে দেবে"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"\'অতিথি মোড\' ছেড়ে বেরিয়ে আসবেন?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"এটি বর্তমান অতিথি সেশন থেকে অ্যাপ ও ডেটা মুছে দেবে"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"বেরিয়ে আসুন"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"অতিথি মোডের অ্যাক্টিভিটি সেভ করবেন?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"আপনি বর্তমান সেশন থেকে অ্যাক্টিভিটি সেভ করতে বা সব অ্যাপ ও ডেটা মুছতে পারবেন"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"মুছুন"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"সেভ করুন"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"\'অতিথি মোড\' ছেড়ে বেরিয়ে আসুন"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"অতিথি সেশন রিসেট করুন"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"\'অতিথি মোড\' ছেড়ে বেরিয়ে আসুন"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ছেড়ে বেরিয়ে যাওয়ার সময় সব অ্যাক্টিভিটি মুছে দেওয়া হবে"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ছেড়ে বেরিয়ে যাওয়ার সময় আপনি অ্যাক্টিভিটি সেভ করতে পারবেন বা মুছতে পারবেন"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"সেশন অ্যাক্টিভিটি মুছে দিতে এখন রিসেট করুন বা ছেড়ে বেরিয়ে আসার সময় আপনি অ্যাক্টিভিটি সেভ করতে বা মুছতে পারবেন"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ফটো তুলুন"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"একটি ইমেজ বেছে নিন"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ফটো বেছে নিন"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index f8b1452..d8e0958 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Sporo punjenje"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Bežično punjenje"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Priključna stanica"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Povezano, ne puni se"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Napunjeno"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Poništi"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ukloni"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Poništavanje sesije gosta…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Poništiti sesiju gosta?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Ovim ćete pokrenuti novu sesiju gosta i izbrisati sve aplikacije i podatke iz trenutne sesije"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Napustiti način rada za gosta?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ovim ćete izbrisati aplikacije i podatke iz trenutne sesije gosta"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Napusti"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Sačuvati aktivnost gosta?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Možete sačuvati aktivnost iz ove sesije ili izbrisati sve aplikacije i podatke"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Izbriši"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Sačuvaj"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Napusti način rada za gosta"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Poništi sesiju gosta"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Izlazak iz sesije gosta"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sva aktivnost će se izbrisati pri napuštanju"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Možete sačuvati ili izbrisati svoju aktivnost pri izlasku"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Poništite da odmah izbrišete aktivnost iz sesije ili je možete sačuvati ili izbrisati pri izlasku"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Snimite fotografiju"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberite sliku"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Odabir fotografije"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 9387d0b..d8201de 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregant ràpidament"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carregant lentament"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Carregant sense fil"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Base de càrrega"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"No s\'està carregant"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connectat; no s\'està carregant"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Carregada"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restableix"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Suprimeix"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"S\'està restablint el convidat…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Vols restablir la sessió de convidat?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Aquesta acció iniciarà una nova sessió de convidat i suprimirà totes les aplicacions i dades de la sessió actual"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sortir del mode de convidat?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Aquesta acció suprimirà les aplicacions i dades de la sessió de convidat actual"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Surt"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Desar l\'activitat de convidat?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Pots desar l\'activitat de la sessió actual o suprimir totes les apps i dades"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Suprimeix"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Desa"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Surt del mode de convidat"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Restableix la sessió de convidat"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Surt del mode de convidat"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Se suprimirà tota l\'activitat en sortir"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Pots desar o suprimir l\'activitat en sortir"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restableix la sessió per suprimir l\'activitat ara, o desa o suprimeix l\'activitat en sortir."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fes una foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Tria una imatge"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecciona una foto"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 52b4924..0ad57cf 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rychlé nabíjení"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Pomalé nabíjení"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Bezdrátové nabíjení"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Nabíjecí dok"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nenabíjí se"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Připojeno, nenabíjí se"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Nabito"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetovat"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Odstranit"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetování hosta…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Resetovat relaci hosta?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tímto zahájíte novou relaci hosta a smažete všechny aplikace a data z aktuální relace"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Ukončit režim hosta?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tímto smažete aplikace a data z aktuální relace hosta"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Ukončit"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Uložit aktivitu hosta?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Aktivitu z aktuální relace můžete uložit, nebo všechny aplikace a data smazat"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Smazat"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Uložit"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Ukončit režim hosta"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Resetovat relaci hosta"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Ukončit režim hosta"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Veškerá aktivita bude při ukončení smazána"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Aktivitu můžete při ukončení uložit nebo smazat"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Aktivitu relace můžete ihned smazat resetováním, případně ji můžete uložit nebo smazat při ukončení"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Pořídit fotku"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrat obrázek"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Vybrat fotku"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 34295fd..6c6dd97 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Oplader hurtigt"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Oplader langsomt"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Trådløs opladning"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Dockingstation"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Oplader ikke"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Tilsluttet, oplader ikke"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Opladet"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Nulstil"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Fjern"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Nulstiller gæst…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Vil du nulstille gæstesessionen?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Denne handling starter en ny gæstesession og sletter alle apps og data fra den aktuelle session"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Vil du afslutte gæstetilstanden?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Denne handling sletter apps og data fra den aktuelle gæstesession."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Luk"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vil du gemme gæsteaktiviteten?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Du kan gemme aktivitet fra den aktuelle session eller slette alle apps og data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Slet"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Gem"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Afslut gæstetilstand"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Nulstil gæstesession"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Afslut gæstesession"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Al aktivitet slettes ved afslutning"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Du kan gemme eller slette din aktivitet ved afslutning"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Nulstil for at slette sessionsaktiviteten nu, eller gem eller slet aktivitet ved afslutning"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Tag et billede"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Vælg et billede"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Vælg billede"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 63d3c1e..85e42f5 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Schnelles Aufladen"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Langsames Aufladen"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Kabelloses Laden"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Wird am Dock geladen"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Wird nicht geladen"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Verbunden, wird nicht geladen"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Aufgeladen"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Zurücksetzen"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Entfernen"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Gast wird zurückgesetzt…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Gastsitzung zurücksetzen?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Hierdurch wird eine neue Gastsitzung gestartet und alle Apps und Daten der aktuellen Sitzung werden gelöscht"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Gastmodus beenden?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Hierdurch werden Apps und Daten der aktuellen Gastsitzung gelöscht"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Beenden"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Gastaktivität speichern?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Speichere Aktivitäten der aktuellen Sitzung oder lösche alle Apps und Daten"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Löschen"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Speichern"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Gastmodus beenden"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Gastsitzung zurücksetzen"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Gastmodus beenden"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Beim Beenden werden alle Aktivitäten gelöscht"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Speichere oder lösche deine Aktivitäten beim Beenden"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Zurücksetzen, um jetzt die Sitzungsaktivitäten zu löschen, oder Aktivitäten beim Beenden speichern oder löschen"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Foto machen"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Bild auswählen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Foto auswählen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 1a7bb61..5241417 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ταχεία φόρτιση"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Αργή φόρτιση"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Ασύρματη φόρτιση"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Βάση φόρτισης"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Δεν φορτίζει"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Συνδεδεμένη, δεν φορτίζει"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Φορτισμένη"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Επαναφορά"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Κατάργηση"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Επαναφορά επισκέπτη…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Επαναφορά περιόδου σύνδεσης επισκέπτη;"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Με αυτόν τον τρόπο θα ξεκινήσει μια νέα περίοδος σύνδεσης επισκέπτη και θα διαγραφούν όλες οι εφαρμογές και τα δεδομένα από την τρέχουσα περίοδο σύνδεσης"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Έξοδος από λειτ. επισκέπτη;"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Θα διαγραφούν εφαρμογές και δεδομένα από την τρέχουσα περίοδο σύνδεσης επισκέπτη"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Έξοδος"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Αποθήκευση δραστ. επισκέπτη;"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Αποθήκευση δραστ. τρέχουσας περιόδου σύνδεσης ή διαγραφή εφαρμογών και δεδομένων"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Διαγραφή"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Αποθήκευση"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Έξοδος από λειτ. επισκέπτη"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Επαναφορά περ. σύνδεσης επισκέπτη"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Έξοδος επισκέπτη"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Όλη η δραστηριότητα θα διαγραφεί κατά την έξοδο"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Αποθηκεύστε ή διαγράψτε τη δραστηριότητά σας κατά την έξοδο"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Επαναφορά για διαγραφή της δραστηριότητας της περιόδου σύνδεσης ή αποθήκευση ή διαγραφή κατά την έξοδο."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Λήψη φωτογραφίας"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Επιλογή εικόνας"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Επιλογή φωτογραφίας"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 506617b..a7bbdb5 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Charging slowly"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Charging wirelessly"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Charging dock"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Not charging"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connected, not charging"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Charged"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remove"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Reset guest session?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"This will start a new guest session and delete all apps and data from the current session"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Exit guest mode?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"This will delete apps and data from the current guest session"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Exit"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Save guest activity?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"You can save activity from the current session or delete all apps and data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Delete"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Save"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Exit guest mode"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Reset guest session"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Exit guest"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 637295a..2919aa6 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Charging slowly"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Charging wirelessly"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Charging dock"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Not charging"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connected, not charging"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Charged"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remove"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Reset guest session?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"This will start a new guest session and delete all apps and data from the current session"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Exit guest mode?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"This will delete apps and data from the current guest session"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Exit"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Save guest activity?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"You can save activity from the current session or delete all apps and data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Delete"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Save"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Exit guest mode"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Reset guest session"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Exit guest"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 506617b..a7bbdb5 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Charging slowly"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Charging wirelessly"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Charging dock"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Not charging"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connected, not charging"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Charged"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remove"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Reset guest session?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"This will start a new guest session and delete all apps and data from the current session"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Exit guest mode?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"This will delete apps and data from the current guest session"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Exit"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Save guest activity?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"You can save activity from the current session or delete all apps and data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Delete"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Save"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Exit guest mode"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Reset guest session"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Exit guest"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 506617b..a7bbdb5 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Charging slowly"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Charging wirelessly"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Charging dock"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Not charging"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connected, not charging"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Charged"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remove"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Reset guest session?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"This will start a new guest session and delete all apps and data from the current session"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Exit guest mode?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"This will delete apps and data from the current guest session"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Exit"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Save guest activity?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"You can save activity from the current session or delete all apps and data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Delete"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Save"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Exit guest mode"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Reset guest session"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Exit guest"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index bb4de3d..f0aa3d6 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎Charging rapidly‎‏‎‎‏‎"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎Charging slowly‎‏‎‎‏‎"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎Charging wirelessly‎‏‎‎‏‎"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎Charging Dock‎‏‎‎‏‎"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‏‎‏‎Not charging‎‏‎‎‏‎"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎Connected, not charging‎‏‎‎‏‎"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‎Charged‎‏‎‎‏‎"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‏‎Reset‎‏‎‎‏‎"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎Remove‎‏‎‎‏‎"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎Resetting guest…‎‏‎‎‏‎"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎Reset guest session?‎‏‎‎‏‎"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎This will start a new guest session and delete all apps and data from the current session‎‏‎‎‏‎"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎‏‎‏‏‎‎‎Exit guest mode?‎‏‎‎‏‎"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎This will delete apps and data from the current guest session‎‏‎‎‏‎"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎Exit‎‏‎‎‏‎"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‎Save guest activity?‎‏‎‎‏‎"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎You can save activity from the current session or delete all apps and data‎‏‎‎‏‎"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎Delete‎‏‎‎‏‎"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎Save‎‏‎‎‏‎"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎Exit guest mode‎‏‎‎‏‎"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎Reset guest session‎‏‎‎‏‎"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‎Exit guest‎‏‎‎‏‎"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎All activity will be deleted on exit‎‏‎‎‏‎"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‎You can save or delete your activity on exit‎‏‎‎‏‎"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎Reset to delete session activity now, or you can save or delete activity on exit‎‏‎‎‏‎"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎Take a photo‎‏‎‎‏‎"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎Choose an image‎‏‎‎‏‎"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‎‏‎Select photo‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index db0a617..4672e3e 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápidamente"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carga lenta"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Carga inalámbrica"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Base de carga"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"No se está cargando."</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado; no se está cargando"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Cargada"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Quitar"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Restableciendo invitado…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"¿Quieres restablecer la sesión de invitado?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Esta acción comenzará una nueva sesión de invitado y borrará todas las apps y los datos de la sesión actual"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"¿Salir del modo de invitado?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Esta acción borrará todas las apps y los datos de la sesión de invitado actual"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Salir"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"¿Guardar actividad de invitado?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puedes guardar la actividad de la sesión actual o borrar las apps y los datos"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Borrar"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Guardar"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Salir del modo de invitado"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Restablecer la sesión de invitado"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Salir del modo de invitado"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Cuando salgas, se borrará toda la actividad"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puedes guardar o borrar la actividad cuando salgas"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece la sesión para eliminar la actividad ahora; o guarda o borra la actividad cuando salgas"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Tomar una foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Elegir una imagen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index d69b446..24cb2eb 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carga rápida"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carga lenta"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Carga inalámbrica"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Base de carga"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"No se está cargando"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado pero sin cargar"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Cargada"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Quitar"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Restableciendo invitado…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"¿Restablecer sesión de invitado?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Se iniciará una nueva sesión de invitado y se borrarán todas las aplicaciones y datos de esta sesión"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"¿Salir del modo Invitado?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Se eliminarán todas las aplicaciones y datos de la sesión de invitado actual"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Salir"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"¿Guardar actividad de invitado?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puedes guardar la actividad de esta sesión o eliminar todas las aplicaciones y datos"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Eliminar"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Guardar"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Salir del modo Invitado"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Restablecer sesión de invitado"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Salir del modo Invitado"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toda la actividad se eliminará cuando salgas"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puedes guardar o eliminar tu actividad al salir"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece la sesión para eliminar la actividad ahora, o guarda o borra la actividad al salir"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Hacer foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Seleccionar una imagen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 30f0350..bc847e2 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Kiirlaadimine"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Aeglaselt laadimine"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Juhtmevaba laadimine"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Laadimisdokk"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ei lae"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ühendatud, ei laeta"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Laetud"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Lähtesta"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Eemalda"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Külastajaseansi lähtestamine …"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Kas lähtestada külastajaseanss?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"See alustab uut külastajaseanssi ning kustutab kõik praeguse seansi rakendused ja andmed."</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Kas väljuda külalisrežiimist?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"See kustutab praeguse külastajaseansi rakendused ja andmed"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Välju"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Kas salvestada külalise tegevus?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Võite selle seansi tegevused salvestada või kustutada kõik rakendused ja andmed."</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Kustuta"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Salvesta"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Välju külalisrežiimist"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Lähtesta külastajaseanss"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Välju külastajaseansist"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Kõik tegevused kustutatakse väljumisel"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Võite tegevused salvestada või kustutada väljumisel."</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Seansi tegevuste kohe kustutamiseks lähtestage; või salvestage või kustutage need väljumisel."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Pildistage"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Valige pilt"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Valige foto"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 3a38abd..6795662 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Bizkor kargatzen"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Mantso kargatzen"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Hari gabe kargatzen"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Oinarrian kargatzen"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ez da kargatzen ari"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Konektatuta dago, baina ez da kargatzen ari"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Kargatuta"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Berrezarri"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Kendu"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Gonbidatuentzako saioa berrezartzen…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Gonbidatuentzako saioa berrezarri nahi duzu?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Gonbidatuentzako saio berri bat abiaraziko da, eta saio honetako aplikazio eta datu guztiak ezabatuko"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Gonbidatu modutik irten nahi duzu?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Gonbidatuentzako saio honetako aplikazioak eta datuak ezabatuko dira"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Irten"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Gonbidatuaren jarduerak gorde nahi dituzu?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Saio honetako jarduerak gorde ditzakezu, edo aplikazio eta datu guztiak ezabatu"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Ezabatu"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Gorde"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Irten gonbidatu modutik"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Berrezarri gonbidatuentzako saioa"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Irten gonbidatu modutik"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Irtetean, jarduera guztiak ezabatuko dira"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Irtetean, jarduerak gorde edo ezabatu egin ditzakezu"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Berrezarri saioa jarduerak ezabatzeko; bestela, aukeratu jarduerak irtetean gordetzea edo ezabatzea"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Atera argazki bat"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Aukeratu irudi bat"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Hautatu argazki bat"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index b1aeebe..946bbb5 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"درحال شارژ شدن سریع"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"درحال شارژ شدن آهسته"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"درحال شارژ بی‌سیم"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"پایه شارژ"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"شارژ نمی‌شود"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"متصل، شارژ نمی‌شود"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"شارژ کامل شد"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"بازنشانی"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"برداشتن"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"درحال بازنشانی مهمان…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"جلسه مهمان بازنشانی شود؟"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"با این کار، جلسه مهمان جدیدی شروع خواهد شد و همه برنامه‌ها و داده‌ها از جلسه کنونی حذف خواهند شد"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"از حالت مهمان خارج می‌شوید؟"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"با این کار، برنامه‌ها و داده‌ها از جلسه مهمان کنونی حذف خواهند شد."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"خروج"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"فعالیت مهمان ذخیره شود؟"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"می‌توانید فعالیت جلسه کنونی را ذخیره کنید یا همه برنامه و داده‌ها را حذف کنید"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"حذف"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"ذخیره"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"خروج از حالت مهمان"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"بازنشاندن جلسه مهمان"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"خروج مهمان"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"همه فعالیت‌ها هنگام خروج حذف خواهد شد"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"می‌توانید فعالیتتان را هنگام خروج ذخیره یا حذف کنید"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"برای حذف فعالیت جلسه در این لحظه، بازنشانی کنید یا می‌توانید فعالیت را هنگام خروج ذخیره یا حذف کنید"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"عکس گرفتن"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"انتخاب تصویر"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"انتخاب عکس"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index b643784..d383919 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Nopea lataus"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Hidas lataus"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Langaton lataus"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Latausteline"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ei laturissa"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Yhdistetty, ei ladata"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Ladattu"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Nollaa"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Poista"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Nollataan vierasta…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Nollataanko vierailija-käyttökerta?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tämä aloittaa uuden vierailija-käyttökerran ja kaikki nykyisen istunnon sovellukset ja data poistetaan"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Poistutaanko vierastilasta?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tämä poistaa nykyisen vierailija-käyttökerran sovellukset ja datan"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Sulje"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Tallennetaanko vierastoiminta?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Voit tallentaa tämän istunnon toimintaa tai poistaa kaikki sovellukset ja datan"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Poista"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Tallenna"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Poistu vierastilasta"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Nollaa vierailija-käyttökerta"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Kirjaa vieras ulos"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Kaikki toiminta poistetaan uloskirjaamisen aikana"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Voit tallentaa tai poistaa toiminnan poistuessasi"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Nollaa poistaaksesi istunnon toiminnan nyt, tai voit tallentaa tai poistaa toimintaa poistuessasi"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Ota kuva"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Valitse kuva"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Valitse kuva"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 5325fbc..24ce0012 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Recharge rapide"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Recharge lente"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"En recharge sans fil"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Station de recharge"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"N\'est pas en charge"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connecté, pas en charge"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Chargée"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Réinitialiser"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Retirer"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Réinitialisation de la session Invité en cours…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Réinitialiser la session d\'invité?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Une nouvelle session d\'invité sera lancée, et toutes les applications et données de la session en cours seront supprimées"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Quitter le mode Invité?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Les applications et les données de la session d\'invité en cours seront supprimées"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Quitter"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Enregistrer l\'activité d\'invité?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Vous pouvez enregistrer l\'activité de session ou supprimer les applis et données"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Supprimer"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Enregistrer"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Quitter le mode Invité"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Réinitialiser la session d\'invité"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Quitter la session d\'invité"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toute l\'activité sera supprimée à la fin de la session"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Vous pouvez enregistrer ou supprimer votre activité à la fin"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Réinitialisez pour supprimer l\'activité de la session maintenant, ou vous pouvez enregistrer ou supprimer l\'activité à la fin de la session"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Sélectionner une image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionnez une photo"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index b667fc0..637cc8a 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charge rapide"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Charge lente"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"En charge sans fil"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Station de charge"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Pas en charge"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connectée, pas en charge"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Chargée"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Réinitialiser"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Supprimer"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Réinitialisation de la session Invité…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Réinitialiser la session Invité ?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Cette action lancera une nouvelle session Invité et supprimera toutes les applis et données de la session actuelle"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Quitter le mode Invité ?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Cette action supprimera les applis et données de la session Invité actuelle."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Quitter"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Enregistrer l\'activité ?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Enregistrez l\'activité de la session actuelle ou supprimez les applis et données"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Supprimer"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Enregistrer"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Quitter le mode Invité"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Réinitialiser la session Invité"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Quitter le mode Invité"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toute l\'activité sera supprimée à la fin de la session"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Vous pouvez enregistrer ou supprimer l\'activité en quittant"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Réinitialisez la session pour supprimer immédiatement l\'activité. Vous pourrez aussi l\'enregistrer ou la supprimer en quittant la session."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Choisir une image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionner une photo"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index da66e92..211f8a5 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rapidamente"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Cargando lentamente"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Cargando sen fíos"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Base de carga"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Non se está cargando"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado, sen cargar"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Cargada"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Quitar"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Restablecendo sesión de convidado…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Queres restablecer a sesión de convidado?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Iniciarase unha nova sesión de convidado e eliminaranse todas as aplicacións e datos desta sesión"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Saír do modo de convidado?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Eliminaranse as aplicacións e os datos da sesión de convidado actual"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Saír"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Gardar actividade do convidado?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Podes gardar a actividade da sesión ou eliminar todas as aplicacións e datos"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Eliminar"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Gardar"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Saír do modo de convidado"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Restablecer sesión de convidado"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Saír do modo de convidado"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Eliminarase toda a actividade ao saír"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Podes gardar ou eliminar a túa actividade ao saír"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece a sesión para eliminar a actividade agora, ou ben gárdaa ou elimínaa ao saír"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escoller imaxe"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index de2fc03..0344f4f 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ઝડપથી ચાર્જ થાય છે"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ધીમેથી ચાર્જ થાય છે"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"વાયરલેસથી ચાર્જિંગ"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"ડૉકથી ચાર્જ થઈ રહ્યું છે"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ચાર્જ થઈ રહ્યું નથી"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"કનેક્ટ કરેલું છે, પણ ચાર્જ થઈ રહ્યું નથી"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ચાર્જ થયું"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"રીસેટ કરો"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"કાઢી નાખો"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"અતિથિને રીસેટ કરી રહ્યાં છીએ…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"શું અતિથિ સત્ર રીસેટ કરીએ?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"આમ કરવાથી કોઈ નવું અતિથિ સત્ર ચાલુ થશે તેમજ હાલના સત્રમાંની તમામ ઍપ અને ડેટા ડિલીટ થશે"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"શું અતિથિ મોડમાંથી બહાર નીકળીએ?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"આમ કરવાથી હાલના અતિથિ સત્રની તમામ ઍપ અને ડેટા ડિલીટ કરવામાં આવશે"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"બહાર નીકળો"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"શું અતિથિ પ્રવૃત્તિ સાચવીએ?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"તમે હાલના સત્રની પ્રવૃત્તિ સાચવી શકો છો અથવા તમામ ઍપ અને ડેટા ડિલીટ કરી શકો છો"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ડિલીટ કરો"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"સાચવો"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"અતિથિ મોડમાંથી બહાર નીકળો"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"અતિથિ સત્ર રીસેટ કરો"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"અતિથિ મોડમાંથી બહાર નીકળો"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"બહાર નીકળતી વખતે તમામ પ્રવૃત્તિ ડિલીટ કરવામાં આવશે"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"બહાર નીકળતી વખતે તમે પ્રવૃત્તિ સાચવી કે ડિલીટ કરી શકશો"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"સત્રની પ્રવૃત્તિ હમણાં ડિલીટ કરવા માટે રીસેટ કરો અથવા બહાર નીકળતી વખતે તમે પ્રવૃત્તિ સાચવી કે ડિલીટ કરી શકશો"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ફોટો લો"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"છબી પસંદ કરો"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ફોટો પસંદ કરો"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 9eccbf9..8522098 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"तेज़ चार्ज हो रही है"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"धीरे चार्ज हो रही है"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"वायरलेस चार्जिंग"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"चार्जिंग डॉक"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"चार्ज नहीं हो रही है"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"कनेक्ट किया गया, चार्ज नहीं हो रहा है"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"बैटरी चार्ज हो गई"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"रीसेट करें"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"हटाएं"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"मेहमान के तौर पर ब्राउज़ करने का सेशन रीसेट किया जा रहा है…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"क्या मेहमान मोड के मौजूदा सेशन को रीसेट करना है?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ऐसा करने पर, मेहमान के तौर पर ब्राउज़ करने का एक नया सेशन शुरू हो जाएगा. साथ ही, पिछले सेशन में मौजूद डेटा और इस्तेमाल किए जा रहे ऐप्लिकेशन को मिटा दिया जाएगा"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"मेहमान मोड से बाहर निकलना है?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"इससे, मेहमान मोड के मौजूदा सेशन का डेटा और इसमें इस्तेमाल हो रहे ऐप मिट जाएंगे"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"बाहर निकलें"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"मेहमान मोड की गतिविधि को सेव करना है?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"मौजूदा सेशन की गतिविधि को सेव किया जा सकता है या सभी ऐप और डेटा को मिटाया जा सकता है"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"मिटाएं"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"सेव करें"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"मेहमान मोड से बाहर निकलें"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"मेहमान मोड के सेशन को रीसेट करें?"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"मेहमान मोड से बाहर निकलें"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"बाहर निकलने पर, सारी गतिविधि मिट जाएगी"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"बाहर निकलने पर, गतिविधि को मिटाया या सेव किया जा सकता है"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"सेशन की गतिविधि को अभी मिटाने के लिए, रीसेट करें. इसके अलावा, बाहर निकलने पर, गतिविधि को मिटाया या सेव किया जा सकता है"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"फ़ोटो खींचें"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"कोई इमेज चुनें"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"फ़ोटो चुनें"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 2714d6e..7480836 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Sporo punjenje"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Bežično punjenje"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Stanica za punjenje"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Povezano, ne puni se"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Napunjeno"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Poništi"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ukloni"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Poništavanje gostujuće sesije…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Želite li poništiti gostujuću sesiju?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Time će se pokrenuti nova gostujuća sesija i izbrisati sve aplikacije i podaci iz trenutačne sesije."</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Napustiti način rada za goste?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Time će se izbrisati aplikacije i podaci iz trenutačne gostujuće sesije."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Izlaz"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Spremiti aktivnosti gosta?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Možete spremiti aktivnosti iz ove sesije ili izbrisati sve aplikacije i podatke"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Izbriši"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Spremi"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Izlaz iz načina rada za goste"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Poništi gostujuću sesiju"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Izlaz iz gostujuće sesije"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sve će se aktivnosti izbrisati na izlasku"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Svoje aktivnosti možete spremiti ili izbrisati na izlasku."</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Poništite da odmah izbrišete aktivnost sesije. Inače je možete spremiti ili izbrisati na izlasku."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiraj"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Odabir slike"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index c613d0a..fb8a737 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Gyorstöltés"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Lassú töltés"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Vezeték nélküli töltés"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Töltődokk"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nem tölt"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Csatlakoztatva, nem töltődik"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Feltöltve"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Visszaállítás"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Eltávolítás"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Vendég munkamenet visszaállítása…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Visszaállítja a vendégmunkamenetet?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"A művelettel új vendégmunkamenetet indít, valamint az összes alkalmazást és adatot törli az aktuális munkamenetből"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Kilép a vendég módból?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"A művelettel törlődnek az aktuális vendégmunkamenet alkalmazásai és adatai"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Kilépés"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Menti a vendégtevékenységeket?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Tevékenységeket menthet az aktuális munkamenetből, vagy minden appot és adatot törölhet"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Törlés"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Mentés"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Kilépés a vendég módból"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Vendégmunkamenet visszaállítása"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Vendég kiléptetése"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"A kilépéssel minden tevékenység törlődik"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"A kilépéskor mentheti vagy törölheti a tevékenységeket"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Visszaállítással azonnal törölheti, illetve kilépéskor mentheti vagy törölheti a tevékenységeket"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotó készítése"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Kép kiválasztása"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Fotó kiválasztása"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index c7a8e4d..7176ae5 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Արագ լիցքավորում"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Դանդաղ լիցքավորում"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Անլար լիցքավորում"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Լիցքավորում դոկ-կայանի միջոցով"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Չի լիցքավորվում"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Միացված է, չի լիցքավորվում"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Լիցքավորված է"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Զրոյացնել"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Հեռացնել"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Հյուրի աշխատաշրջանը վերակայվում է…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Զրոյացնե՞լ հյուրի աշխատաշրջանը"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Կսկսվի հյուրի նոր աշխատաշրջան, իսկ նախորդ աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Դուրս գա՞լ հյուրի ռեժիմից"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Հյուրի ընթացիկ աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Դուրս գալ"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Պահե՞լ հյուրի ռեժիմի պատմությունը"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Պահեք ընթացիկ աշխատաշրջանի պատմությունը կամ ջնջեք հավելվածներն ու տվյալները"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Ջնջել"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Պահել"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Դուրս գալ հյուրի ռեժիմից"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Զրոյացնել հյուրի աշխատաշրջանը"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Դուրս գալ հյուրի ռեժիմից"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Եթե դուրս գաք, ամբողջ պատմությունը կջնջվի"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Դուրս գալիս կարող եք պահել կամ ջնջել ձեր պատմությունը"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Վերակայեք աշխատաշրջանի պատմությունը հիմա կամ պահեք/ջնջեք այն դուրս գալիս"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Լուսանկարել"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Ընտրել պատկեր"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Ընտրեք լուսանկար"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 3104fe1..6e1bff8 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengisi daya cepat"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Mengisi daya lambat"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Mengisi daya nirkabel"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Mengisi Daya di Dok"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Tidak mengisi daya"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Terhubung, tidak mengisi daya"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Terisi"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Hapus"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Mereset tamu …"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Reset sesi tamu?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tindakan ini akan memulai sesi tamu baru dan menghapus semua aplikasi serta data dari sesi saat ini"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Keluar dari mode tamu?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tindakan ini akan menghapus aplikasi dan data dari sesi tamu saat ini"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Keluar"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Simpan aktivitas tamu?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Anda bisa menyimpan aktivitas sesi saat ini atau menghapus semua aplikasi &amp; data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Hapus"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Simpan"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Keluar dari mode tamu"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Reset sesi tamu"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Keluar dari mode tamu"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Semua aktivitas akan dihapus saat Anda keluar"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Anda dapat menyimpan atau menghapus aktivitas saat keluar"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset untuk hapus aktivitas sesi sekarang, atau simpan atau hapus aktivitas saat keluar"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih gambar"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pilih foto"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index c4814249..9c8933d 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hröð hleðsla"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Hæg hleðsla"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Hleður þráðlaust"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Hleður í dokku"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ekki í hleðslu"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Tengt, ekki í hleðslu"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Fullhlaðin"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Endurstilla"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Fjarlægja"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Endurstillir gest…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Endurstilla gestalotu?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Þetta opnar nýja gestalotu og eyðir öllum forritum og gögnum úr núverandi lotu"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Loka gestastillingu?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Þetta eyðir forritum og gögnum úr núverandi gestalotu"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Hætta"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vista aðgerðir úr gestalotu?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Þú getur vistað aðgerðir úr núverandi lotu eða eytt öllum forritum og gögnum"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Eyða"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Vista"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Loka gestastillingu"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Endurstilla gestalotu"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Loka gestastillingu"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Öllum aðgerðum verður eytt þegar lotu er lokað"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Þú getur vistað eða eytt aðgerðum þegar þú lokar"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Endurstilltu til að eyða aðgerðum lotu núna, eða vistaðu eða eyddu aðgerðum þegar þú lokar"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Taka mynd"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Velja mynd"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Velja mynd"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 87fc4b7..52ef968 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ricarica veloce"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Ricarica lenta"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"In carica, wireless"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"In carica nel dock"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Non in carica"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Dispositivo connesso, non in carica"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Carica"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reimposta"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Rimuovi"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Reimpostazione sessione Ospite in corso…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Vuoi reimpostare la sessione Ospite?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Verrà avviata una nuova sessione Ospite e verranno eliminati tutti i dati e le app della sessione corrente"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Vuoi uscire da modalità Ospite?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Verranno eliminati i dati e le app della sessione Ospite corrente"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Esci"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vuoi salvare l\'attività Ospite?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puoi salvare l\'attività della sessione corrente o eliminare tutti i dati e le app"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Elimina"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Salva"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Esci dalla modalità Ospite"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Reimposta sessione Ospite"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Esci dalla modalità Ospite"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Quando esci verrà eliminata tutta l\'attività"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Quando esci puoi salvare o eliminare la tua attività"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reimposta la sessione per eliminare subito l\'attività, oppure salvala o eliminala quando esci"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Scatta una foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Scegli un\'immagine"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleziona la foto"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 5c3c304..d95590a 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"הסוללה נטענת מהר"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"הסוללה נטענת לאט"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"בטעינה אלחוטית"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"אביזר עגינה לטעינה"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"לא בטעינה"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"מחובר, לא בטעינה"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"הסוללה טעונה"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"איפוס"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"הסרה"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"מתבצע איפוס של הגלישה כאורח…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"לאפס את הגלישה כאורח?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"הפעולה הזו תתחיל גלישה חדשה כאורח ותמחק את כל האפליקציות והנתונים מהסשן הנוכחי"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"לצאת ממצב אורח?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"הפעולה הזו תמחק את האפליקציות והנתונים מהגלישה הנוכחית כאורח"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"יציאה"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"לשמור את פעילות האורח?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"אפשר לשמור את הפעילות מהסשן הנוכחי או למחוק את כל האפליקציות והנתונים"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"מחיקה"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"שמירה"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"יציאה ממצב אורח"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"איפוס הגלישה כאורח"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"יציאה ממצב אורח"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"כל הפעילות תימחק ביציאה"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"אפשר לשמור או למחוק את הפעילות שלך ביציאה"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ניתן לאפס כדי למחוק את הפעילות מהסשן כעת, או לשמור או למחוק את הפעילות ביציאה"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"צילום תמונה"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"לבחירת תמונה"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"בחירת תמונה"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index cf11237..5fa42a2 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"急速充電中"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"低速充電中"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"ワイヤレス充電中"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"充電ホルダー"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"充電していません"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"接続済み、充電していません"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"充電が完了しました"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"リセット"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"削除"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ゲストをリセットしています…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"ゲスト セッションをリセットしますか?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"新しいゲスト セッションが開始し、現在のセッションのすべてのアプリとデータが削除されます"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ゲストモードを終了しますか?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"現在のゲスト セッションからすべてのアプリとデータが削除されます"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"終了"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ゲストアクティビティの保存"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"現在のセッションのアクティビティの保存や、すべてのアプリとデータの削除を行えます"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"削除"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"保存"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"ゲストモードを終了"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"ゲスト セッションをリセット"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ゲストを終了"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"終了時にすべてのアクティビティが削除されます"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"終了時にアクティビティを保存、削除できます"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"アクティビティは、リセットして今すぐ削除するか、終了時に保存または削除できます"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"写真を撮る"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"画像を選択"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"写真を選択"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 540f1fc8..8ea0961 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"სწრაფად იტენება"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ნელა იტენება"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"უსადენოდ დატენა"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"დამტენი სამაგრი"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"არ იტენება"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"დაკავშირებულია, არ იტენება"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"დატენილია"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"გადაყენება"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ამოშლა"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"მიმდინარეობს სტუმრის გადაყენება…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"გსურთ სტუმრის სესიის გადაყენება?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ამ ქმედებით დაიწყება სტუმრის ახალი სესია და წაიშლება ყველა აპი და მონაცემი მიმდინარე სესიიდან"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"გსურთ სტუმრის რეჟიმიდან გასვლა?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ეს ქმედება წაშლის აპებსა და მონაცემებს სტუმრის რეჟიმის მიმდინარე სესიიდან"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"გასვლა"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"გსურთ სტუმრის აქტივობის შენახვა?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"შეგიძლიათ შეინახოთ აქტივობა მიმდინარე სესიიდან ან წაშალოთ ყველა აპი და მონაცემი"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"წაშლა"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"შენახვა"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"სტუმრის რეჟიმიდან გასვლა"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"სტუმრის სესიის გადაყენება"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"სტუმრის გასვლა"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"გასვლისას ყველა აქტივობა წაიშლება"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"გასვლისას შეგიძლიათ შეინახოთ ან წაშალოთ თქვენი აქტივობა"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"გადააყენეთ სესიის აქტივობის ახლა წასაშლელად. შენახვა/წაშლა გასვლისასაც შეიძლება."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ფოტოს გადაღება"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"აირჩიეთ სურათი"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ფოტოს არჩევა"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 2277479..91aea7b 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Жылдам зарядталуда"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Баяу зарядталуда"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Сымсыз зарядталуда"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Қондыру станциясы зарядталуда"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Зарядталу орындалып жатқан жоқ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Жалғанған, зарядталып жатқан жоқ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Зарядталды"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Бастапқы күйге қайтару"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Өшіру"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Қонақ сеансы бастапқы күйге қайтарылуда…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Қонақ сеансын бастапқы күйге қайтару керек пе?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Мұндайда жаңа қонақ сеансы басталады және ағымдағы сеанстағы барлық қолданба мен дерек жойылады."</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Қонақ режимінен шығу керек пе?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ағымдағы қонақ сеансындағы барлық қолданба мен дерек жойылады."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Шығу"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Қонақ әрекетін сақтау керек пе?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Ағымдағы сеанстағы әрекетті сақтай не барлық қолданба мен деректі жоя аласыз."</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Жою"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Сақтау"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Қонақ режимінен шығу"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Қонақ режимін қалпына келтіру"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Қонақ режимінен шығу"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Шыққанда барлық әрекет жойылады."</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Шыққанда барлық әрекетті сақтай немесе жоя аласыз."</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Сеанс дерегін жою үшін оны бастапқы күйге қайтарыңыз. Деректі шығар кезде де сақтауға не жоюға болады."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Фотосуретке түсіру"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Сурет таңдау"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Фотосурет таңдау"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index eb8ae47..fcbe6e5 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"កំពុងសាកថ្មយ៉ាងឆាប់រហ័ស"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"កំពុង​សាកថ្មយឺត"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"កំពុង​សាកថ្ម​ឥតខ្សែ"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"ឧបករណ៍ភ្ជាប់សាកថ្ម"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"មិនកំពុង​សាក​ថ្ម"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"បានភ្ជាប់ មិនកំពុង​សាកថ្ម"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"បាន​សាក​ថ្មពេញ"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"កំណត់​ឡើងវិញ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ដកចេញ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"កំពុងកំណត់​ភ្ញៀវឡើងវិញ…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"កំណត់វគ្គភ្ញៀវឡើងវិញឬ?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ការធ្វើបែបនេះនឹងចាប់ផ្ដើមវគ្គភ្ញៀវថ្មី និងលុបកម្មវិធី និងទិន្នន័យទាំងអស់ចេញពីវគ្គបច្ចុប្បន្ន"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ចាកចេញពីមុខងារភ្ញៀវឬ?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ការធ្វើបែបនេះនឹងលុបកម្មវិធី និងទិន្នន័យចេញពីវគ្គភ្ញៀវបច្ចុប្បន្ន"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ចាកចេញ"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"រក្សាទុកសកម្មភាពភ្ញៀវឬ?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"អ្នកអាចរក្សាទុកសកម្មភាពពីវគ្គបច្ចុប្បន្ន ឬលុបកម្មវិធីនិងទិន្នន័យទាំងអស់"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"លុប"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"រក្សាទុក"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"ចាកចេញពីមុខងារភ្ញៀវ"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"កំណត់វគ្គភ្ញៀវឡើងវិញ"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ចាកចេញពីមុខងារភ្ញៀវ"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"សកម្មភាពទាំងអស់នឹងត្រូវលុបនៅពេលចាកចេញ"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"អ្នកអាចរក្សាទុក ឬលុបសកម្មភាពរបស់អ្នកនៅពេលចាកចេញ"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"កំណត់ឡើងវិញ ដើម្បីលុបសកម្មភាពក្នុងវគ្គឥឡូវនេះ ឬអ្នកអាចរក្សាទុកឬលុបសកម្មភាពនៅពេលចាកចេញ"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ថតរូប"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ជ្រើសរើស​រូបភាព"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ជ្រើសរើស​​រូបថត"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 0536960..4f3b1b1 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ವೇಗದ ಚಾರ್ಜಿಂಗ್"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ನಿಧಾನ ಗತಿಯ ಚಾರ್ಜಿಂಗ್"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"ವೈರ್‌ಲೆಸ್ ಚಾರ್ಜಿಂಗ್"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"ಚಾರ್ಜಿಂಗ್ ಡಾಕ್"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ಚಾರ್ಜ್‌ ಆಗುತ್ತಿಲ್ಲ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ಕನೆಕ್ಟ್ ಆಗಿದೆ, ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ರೀಸೆಟ್ ಮಾಡಿ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ತೆಗೆದುಹಾಕಿ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ಅತಿಥಿ ಬಳಕೆದಾರರ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"ಅತಿಥಿ ಸೆಷನ್ ಅನ್ನು ರೀಸೆಟ್ ಮಾಡಬೇಕೇ?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ಈ ಪ್ರಕ್ರಿಯೆಯು ಹೊಸ ಅತಿಥಿ ಸೆಶನ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ ಮತ್ತು ಪ್ರಸ್ತುತ ಸೆಶನ್‌ನಿಂದ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಹಾಗೂ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ಅತಿಥಿ ಮೋಡ್‌ನಿಂದ ನಿರ್ಗಮಿಸಬೇಕೆ?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ಈ ಪ್ರಕ್ರಿಯೆಯು ಪ್ರಸ್ತುತ ಅತಿಥಿ ಸೆಷನ್‌ನಿಂದ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ನಿರ್ಗಮಿಸಿ"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ಅತಿಥಿ ಚಟುವಟಿಕೆಯನ್ನು ಉಳಿಸಬೇಕೆ?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"ನೀವು ಪ್ರಸ್ತುತ ಸೆಶನ್‌ನ ಚಟುವಟಿಕೆಯನ್ನು ಉಳಿಸಬಹುದು ಅಥವಾ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಬಹುದು"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ಅಳಿಸಿ"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"ಉಳಿಸಿ"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"ಅತಿಥಿ ಮೋಡ್‌ನಿಂದ ನಿರ್ಗಮಿಸಿ"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"ಅತಿಥಿ ಸೆಷನ್ ಅನ್ನು ರೀಸೆಟ್ ಮಾಡಿ"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ಅತಿಥಿ ಮೋಡ್‌ನಿಂದ ನಿರ್ಗಮಿಸಿ"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ನಿರ್ಗಮಿಸುವಾಗ ಎಲ್ಲಾ ಚಟುವಟಿಕೆಯನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ನಿರ್ಗಮಿಸುವಾಗ ನಿಮ್ಮ ಚಟುವಟಿಕೆಯನ್ನು ನೀವು ಉಳಿಸಬಹುದು ಅಥವಾ ಅಳಿಸಬಹುದು"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ಸೆಶನ್ ಚಟುವಟಿಕೆಯನ್ನು ಈಗ ಅಳಿಸಲು ರೀಸೆಟ್ ಮಾಡಿ ಅಥವಾ ನಿರ್ಗಮಿಸುವಾಗ ನೀವು ಚಟುವಟಿಕೆಯನ್ನು ಉಳಿಸಬಹುದು ಅಥವಾ ಅಳಿಸಬಹುದು"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ಫೋಟೋ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ಚಿತ್ರವನ್ನು ಆರಿಸಿ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ಫೋಟೋ ಆಯ್ಕೆಮಾಡಿ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 4fb2385..2133724 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"고속 충전 중"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"저속 충전 중"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"무선 충전 중"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"충전 도크"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"충전 안함"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"연결됨, 충전 중 아님"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"충전됨"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"재설정"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"삭제"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"게스트 재설정 중…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"게스트 세션을 재설정하시겠습니까?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"새로운 게스트 세션이 시작되고 기존 세션의 모든 앱과 데이터가 삭제됩니다."</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"게스트 모드를 종료하시겠습니까?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"현재 게스트 세션의 앱과 데이터가 삭제됩니다."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"종료"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"게스트 활동을 저장하시겠습니까?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"기존 세션의 활동을 저장하거나 모든 앱과 데이터를 삭제할 수 있습니다."</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"삭제"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"저장"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"게스트 모드 종료"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"게스트 세션 재설정"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"게스트 종료"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"종료하면 모든 활동이 삭제됩니다."</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"종료 시 활동을 저장하거나 삭제할 수 있습니다."</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"지금 재설정하여 활동 세션을 삭제하거나 종료 시 활동을 저장 또는 삭제할 수 있습니다."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"사진 찍기"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"이미지 선택"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"사진 선택"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index b4f7817..b10056f1 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ыкчам кубатталууда"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Жай кубатталууда"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Зымсыз кубатталууда"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Кубаттоо док бекети"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Кубат алган жок"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Туташты, кубатталган жок"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Кубатталды"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Баштапкы абалга келтирүү"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Өчүрүү"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Конок сеансы баштапкы абалга келтирилүүдө…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Конок сеансын баштапкы абалга келтиресизби?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Бул аракет жаңы конок сеансын баштап, учурдагы сеанстагы бардык колдонмолорду жана алардагы нерселерди жок кылат"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Конок режиминен чыгасызбы?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Бул учурдагы конок сеансындагы колдонмолорду жана алардагы нерселерди жок кылат"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Чыгуу"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Коноктун аракеттерин сактайсызбы?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Учурдагы сеанстагы аракеттерди сактап же бардык колдонмолорду жана алардагы нерселерди жок кылсаңыз болот"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Өчүрүү"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Сактоо"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Конок режиминен чыгуу"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Конок сеансын кайра коюу"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Конок режиминен чыгуу"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Чыксаңыз, бардык аракеттер өчүрүлөт"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Чыгуудан мурун аракеттериңизди сактап же жок кылсаңыз болот"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Сеанстагы аракеттерди азыр өчүрсөңүз болот же чыгып баратып өчүрүп же сактап коюңуз"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Сүрөткө тартуу"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Сүрөт тандаңыз"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Сүрөт тандаңыз"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 4462137..74acbc8 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ກຳລັງສາກໄຟດ່ວນ"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ກຳລັງສາກໄຟຊ້າໆ"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"ກຳລັງສາກໄຟໄຮ້ສາຍ"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"ກຳລັງສາກໄຟຜ່ານດັອກ"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ບໍ່ໄດ້ສາກໄຟ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ເຊື່ອມຕໍ່ແລ້ວ, ບໍ່ໄດ້ສາກໄຟ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ສາກເຕັມແລ້ວ"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ຣີເຊັດ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ລຶບອອກ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ກຳລັງຣີເຊັດແຂກ…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"ຣີເຊັດເຊດຊັນຂອງແຂກບໍ?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ນີ້ຈະເລີ່ມໄລຍະເວລາຂອງແຂກໃໝ່ ແລະ ລຶບແອັບ ແລະ ຂໍ້ມູນທັງໝົດອອກຈາກເຊດຊັນປັດຈຸບັນ"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ອອກຈາກໂໝດແຂກບໍ?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ນີ້ຈະລຶບແອັບ ແລະ ຂໍ້ມູນອອກຈາກເຊດຊັນແຂກປັດຈຸບັນ"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ອອກ"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ບັນທຶກການເຄື່ອນໄຫວແຂກບໍ?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"ທ່ານສາມາດບັນທຶກການເຄື່ອນໄຫວຈາກເຊດຊັນປັດຈຸບັນ ຫຼື ລຶບແອັບ ແລະ ຂໍ້ມູນທັງໝົດໄດ້"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ລຶບ"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"ບັນທຶກ"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"ອອກຈາກໂໝດແຂກ"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"ຣີເຊັດເຊດຊັນຂອງແຂກ"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ອອກຈາກແຂກ"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ການເຄື່ອນໄຫວທັງໝົດຈະຖືກລຶບໃນຕອນອອກ"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ທ່ານສາມາດບັນທຶກ ຫຼື ລຶບການເຄື່ອນໄຫວຂອງທ່ານໃນຕອນອອກໄດ້"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ຣີເຊັດເພື່ອລຶບການເຄື່ອນໄຫວເຊດຊັນຕອນນີ້ ຫຼື ທ່ານສາມາດບັນທຶກ ຫຼື ລຶບການເຄື່ອນໄຫວໃນຕອນອອກໄດ້"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ຖ່າຍຮູບ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ເລືອກຮູບ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ເລືອກຮູບ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index b3866dc..13eb792 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Greitai įkraunama"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Lėtai įkraunama"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Kraunama be laidų"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Įkrovimo dokas"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nekraunama"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Prijungta, neįkraunama"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Įkrauta"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Nustatyti iš naujo"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Pašalinti"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Svečias nustatomas iš naujo…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Nustatyti svečio sesiją iš naujo?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Bus pradėta nauja svečio sesija ir iš esamos sesijos bus ištrintos visos programos ir duomenys"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Išeiti iš svečio režimo?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Bus ištrintos esamos svečio sesijos programos ir duomenys"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Išeiti"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Išsaugoti svečio veiklą?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Galite išsaugoti esamos sesijos veiklą arba ištrinti visas programas ir duomenis"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Ištrinti"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Išsaugoti"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Išeiti iš svečio režimo"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Nustatyti svečio sesiją iš naujo"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Išeiti iš svečio režimo"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Išėjus iš režimo visa veikla bus ištrinta"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Išeidami galite išsaugoti arba ištrinti savo veiklą"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Nustatykite iš naujo, jei norite ištrinti sesijos veiklą dabar, arba galite išeidami išsaugoti ar ištrinti veiklą"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotografuoti"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Pasirinkti vaizdą"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pasirinkti nuotrauką"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 1fa6bc8..1a9a6c3 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Notiek ātrā uzlāde"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Notiek lēnā uzlāde"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Bezvadu uzlāde"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Uzlādes doks"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nenotiek uzlāde"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ierīce pievienota, uzlāde nenotiek"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Uzlādēts"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Atiestatīt"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Noņemt"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Notiek viesa sesijas atiestatīšana…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Vai atiestatīt viesa sesiju?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tādējādi tiks sākta jauna viesa sesijas un visas pašreizējās sesijas lietotnes un dati tiks dzēsti"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Vai iziet no viesa režīma?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tādējādi tiks dzēstas pašreizējās viesa sesijas lietotnes un dati."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Iziet"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vai saglabāt viesa darbības?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Varat saglabāt pašreizējās sesijas darbības vai dzēst visas lietotnes un datus"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Dzēst"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Saglabāt"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Iziet no viesa režīma"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Atiestatīt viesa sesiju"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Iziet no viesa režīma"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Izejot tiks dzēstas visas darbības"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Izejot varat saglabāt vai dzēst savas darbības"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Atiestatiet, lai tagad dzēstu sesijas darbības. Izejot varēsiet saglabāt vai dzēst darbības."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Uzņemt fotoattēlu"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Izvēlēties attēlu"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Atlasīt fotoattēlu"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 43fe5e4..98fd004 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо полнење"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Бавно полнење"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Се полни безжично"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Се полни на док"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не се полни"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Поврзано, не се полни"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Полна"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетирај"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Отстрани"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Се ресетира гостинот…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Да се ресетира гостинската сесија?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Ова ќе започне нова гостинска сесија и ќе ги избрише сите апликации и податоци од тековната сесија"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Да се излезе од режим на гостин?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ова ќе ги избрише сите апликации и податоци од тековната гостинска сесија"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Излези"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Да се зачува активност на гостин?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Може да зачувате активност од тековната сесија или да ги избришете сите апликации и податоци"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Избриши"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Зачувај"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Излези од режим на гостин"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Ресетирај ја гостинската сесија"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Излези од режим на гостин"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Целата активност ќе се избрише при излегувањето"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Можете да ја зачувате или избришете вашата активност при излегувањето"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ресетирајте за да ја избришете активноста на сесијата сега или може да ја зачувате или избришете активноста при излегувањето"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Фотографирајте"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Одберете слика"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Изберете фотографија"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 64bf8f7..5c4cbf3 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"അതിവേഗ ചാർജിംഗ്"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"പതുക്കെയുള്ള ചാർജിംഗ്"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"വയർലെസായി ചാർജുചെയ്യുന്നു"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"ചാർജിംഗ് ഡോക്ക്"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"കണക്റ്റ് ചെയ്‌തിരിക്കുന്നു, ചാർജ് ചെയ്യുന്നില്ല"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ചാർജായി"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"റീസെറ്റ് ചെയ്യുക"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"നീക്കം ചെയ്യുക"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"അതിഥിയെ റീസെറ്റ് ചെയ്യുന്നു…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"അതിഥി സെഷൻ റീസെറ്റ് ചെയ്യണോ?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ഇത് പുതിയൊരു അതിഥി സെഷൻ ആരംഭിക്കുകയും നിലവിലെ സെഷനിൽ നിന്ന് എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കുകയും ചെയ്യും"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"അതിഥി മോഡിൽ നിന്ന് പുറത്തുകടക്കണോ?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"നിലവിലെ അതിഥി സെഷനിൽ നിന്ന് ആപ്പുകളും ഡാറ്റയും ഇത് ഇല്ലാതാക്കും"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"പുറത്തുകടക്കുക"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"അതിഥി ആക്‌റ്റിവിറ്റി സംരക്ഷിക്കണോ?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"നിലവിലെ സെഷനിൽ നിന്നുള്ള ആക്‌റ്റിവിറ്റി സംരക്ഷിക്കാം അല്ലെങ്കിൽ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കാം"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ഇല്ലാതാക്കുക"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"സംരക്ഷിക്കുക"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"പുറത്തുകടക്കുക"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"അതിഥി സെഷൻ റീസെറ്റ് ചെയ്യുക"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"അതിഥി മോഡിൽ നിന്ന് പുറത്തുകടക്കുക"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"പുറത്തുകടക്കുമ്പോൾ എല്ലാ ആക്‌റ്റിവിറ്റിയും ഇല്ലാതാക്കും"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"പുറത്തുകടക്കുമ്പോൾ ആക്‌റ്റിവിറ്റി സംരക്ഷിക്കുകയോ ഇല്ലാതാക്കുകയോ ചെയ്യാം"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"സെഷൻ ആക്‌റ്റിവിറ്റി ഇപ്പോൾ ഇല്ലാതാക്കാൻ റീസെറ്റ് ചെയ്യുക അല്ലെങ്കിൽ പുറത്തുകടക്കുമ്പോൾ ആക്‌റ്റിവിറ്റി സംരക്ഷിക്കുകയോ ഇല്ലാതാക്കുകയോ ചെയ്യാം"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ഒരു ഫോട്ടോ എടുക്കുക"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ഫോട്ടോ തിരഞ്ഞെടുക്കുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 5dc88cd..475178e 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Хурдан цэнэглэж байна"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Удаан цэнэглэж байна"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Утасгүй цэнэглэж байна"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Цэнэглэх холбогч"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Цэнэглэхгүй байна"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Холбогдсон, цэнэглээгүй байна"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Цэнэглэсэн"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Шинэчлэх"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Хасах"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Зочныг шинэчилж байна…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Зочны харилцан үйлдлийг шинэчлэх үү?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Энэ нь шинэ зочны харилцан үйлдэл эхлүүлж, одоогийн харилцан үйлдлээс бүх апп болон өгөгдлийг устгана"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Зочны горимоос гарах уу?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Энэ нь одоогийн зочны харилцан үйлдлээс аппууд болон өгөгдлийг устгана"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Гарах"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Зочны үйл ажиллагааг хадгалах уу?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Та одоогийн харилцан үйлдлээс үйл ажиллагаа хадгалах эсвэл бүх апп, өгөгдлийг устгаж болно"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Устгах"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Хадгалах"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Зочны горимоос гарах"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Зочны харилцан үйлдлийг шинэчлэх"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Зочны горимоос гарах"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Бүх үйл ажиллагааг гарах үед устгана"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Та гарахдаа үйл ажиллагаагаа хадгалах эсвэл устгах боломжтой"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Харилцан үйлдлийн үйл ажиллагааг одоо устгахын тулд шинэчлэх эсвэл та гарахдаа үйл ажиллагааг хадгалах, устгах боломжтой"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Зураг авах"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Зураг сонгох"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Зураг сонгох"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 1f89b8f..d18a1f9 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"वेगाने चार्ज होत आहे"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"हळू चार्ज होत आहे"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"वायरलेसने चार्ज होत आहे"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"चार्जिंग डॉक"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"चार्ज होत नाही"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"कनेक्ट केले, चार्ज होत नाही"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"चार्ज झाली"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"रीसेट करा"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"काढून टाका"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"अतिथीला रीसेट करत आहे…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"अतिथी सत्र रीसेट करायचे का?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"हे नवीन अतिथी सत्र सुरू करेल आणि सध्याच्या सत्रातील सर्व अ‍ॅप्स व डेटा हटवेल"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"अतिथी मोडमधून बाहेर पडायचे का?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"हे सध्याच्या अतिथी सत्रातील अ‍ॅप्स आणि डेटा हटवेल"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"बाहेर पडा"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"अतिथी अ‍ॅक्टिव्हिटी सेव्ह करायची का?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"सध्याच्या सत्रातील अ‍ॅक्टिव्हिटी सेव्ह करू किंवा सर्व अ‍ॅप्स व डेटा हटवू शकता"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"हटवा"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"सेव्ह करा"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"अतिथी मोडमधून बाहेर पडा"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"अतिथी सत्र रीसेट करा"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"अतिथी मोडमधून बाहेर पडा"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"बाहेर पडल्यावर सर्व अ‍ॅक्टिव्हिटी हटवली जाईल"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"बाहेर पडल्यावर तुमची अ‍ॅक्टिव्हिटी सेव्ह करू किंवा हटवू शकता"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"सत्र अ‍ॅक्टिव्हिटी आता हटवण्यासाठी रीसेट करा किंवा तुम्ही बाहेर पडल्यावर अ‍ॅक्टिव्हिटी सेव्ह करू अथवा हटवू शकता"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"फोटो काढा"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"इमेज निवडा"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"फोटो निवडा"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 2034af2..efdf989 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengecas dgn cepat"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Mengecas perlahan"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Mengecas tanpa wayar"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Dok Pengecasan"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Tidak mengecas"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Bersambung, tidak mengecas"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Sudah dicas"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tetapkan semula"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Alih keluar"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Menetapkan semula tetamu…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Tetapkan semula sesi tetamu?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tindakan ini akan memulakan sesi tetamu baharu dan memadamkan semua apl dan data daripada sesi semasa"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Keluar daripada mod tetamu?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tindakan ini akan memadamkan apl dan data daripada sesi tetamu semasa"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Keluar"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Simpan aktiviti tetamu?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Anda boleh menyimpan aktiviti daripada sesi semasa atau memadamkan semua apl dan data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Padam"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Simpan"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Keluar daripada mod tetamu"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Tetapkan semula sesi tetamu"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Keluar mod tetamu"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Semua aktiviti akan dipadamkan semasa keluar"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Aktiviti anda boleh disimpan atau dipadam semasa keluar"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Tetapkan semula sesi untuk memadamkan aktiviti sesi sekarang atau anda boleh menyimpan atau memadamkan aktiviti semasa keluar"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih imej"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pilih foto"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 2514eff..c3dac35 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"အမြန် အားသွင်းနေသည်"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"နှေးကွေးစွာ အားသွင်း"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"ကြိုးမဲ့ အားသွင်းနေသည်"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"အားသွင်းအထိုင်"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"အားသွင်းမနေပါ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ချိတ်ဆက်ထားသည်၊ အားသွင်းမနေပါ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"အားသွင်းပြီးပါပြီ"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ပြင်ဆင်သတ်မှတ်ရန်"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ဖယ်ရှားရန်"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ဧည့်သည်ကို ပြင်ဆင်သတ်မှတ်နေသည်…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"ဧည့်သည် စက်ရှင် ပြင်ဆင်သတ်မှတ်မလား။"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"၎င်းသည် ဧည့်သည် စက်ရှင်အသစ်ကို စတင်မည်ဖြစ်ပြီး လက်ရှိစက်ရှင်မှ အက်ပ်နှင့် ဒေတာအားလုံးကို ဖျက်ပါမည်"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ဧည့်သည်မုဒ်မှ ထွက်မလား။"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"၎င်းသည် လက်ရှိဧည့်သည် စက်ရှင်မှ အက်ပ်နှင့် ဒေတာအားလုံးကို ဖျက်လိုက်ပါမည်"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ထွက်ရန်"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ဧည့်သည်လုပ်ဆောင်ချက် သိမ်းမလား။"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"လက်ရှိစက်ရှင်မှ လုပ်ဆောင်ချက် သိမ်းနိုင်သည် (သို့) အက်ပ်နှင့် ဒေတာအားလုံး ဖျက်နိုင်သည်"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ဖျက်ရန်"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"သိမ်းရန်"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"ဧည့်သည်မုဒ်မှ ထွက်ရန်"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"ဧည့်သည် စက်ရှင် ပြင်ဆင်သတ်မှတ်ရန်"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ဧည့်သည့်မှ ထွက်ရန်"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ထွက်သည့်အခါ လုပ်ဆောင်ချက်အားလုံးကို ဖျက်လိုက်မည်"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ထွက်သည့်အခါ လုပ်ဆောင်ချက်ကို သိမ်းနိုင် (သို့) ဖျက်နိုင်သည်"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"စက်ရှင်လုပ်ဆောင်ချက်ကို ယခုဖျက်ရန် ပြင်ဆင်သတ်မှတ်နိုင်သည် (သို့) ထွက်သည့်အခါ သိမ်းနိုင်၊ ဖျက်နိုင်သည်"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ဓာတ်ပုံရိုက်ရန်"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ပုံရွေးရန်"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ဓာတ်ပုံရွေးရန်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 2f0b46f..f6c82f8 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Lader raskt"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Lader sakte"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Lader trådløst"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Ladedokk"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Lader ikke"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Tilkoblet, lader ikke"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Ladet"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tilbakestill"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Fjern"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Tilbakestiller gjesten …"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Vil du tilbakestille gjesteøkten?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Dette starter en ny gjesteøkt og sletter alle apper og data fra den gjeldende økten"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Vil du avslutte gjestemodus?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Dette sletter apper og data fra den gjeldende gjesteøkten"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Avslutt"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vil du lagre gjesteaktivitet?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Du kan lagre aktivitet fra den gjeldende økten eller slette alle apper og data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Slett"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Lagre"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Avslutt gjestemodus"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Tilbakestill gjesteøkten"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Avslutt gjesteøkten"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All aktivitet slettes når du avslutter"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Du kan lagre eller slette aktiviteten når du avslutter"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Tilbakestill for å slette øktaktivitet nå, eller du kan lagre eller slette aktivitet når du avslutter"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Ta et bilde"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Velg et bilde"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Velg et bilde"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 34da9a7..5fa4daa 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"द्रुत गतिमा चार्ज गरिँदै छ"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ढिलो चार्ज हुँदै छ"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"वायरलेस तरिकाले चार्ज गरिँदै छ"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"डक चार्ज हुँदै छ"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"चार्ज भइरहेको छैन"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"कनेक्ट गरिएको छ, चार्ज भइरहेको छैन"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"चार्ज भयो"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"रिसेट गर्नुहोस्"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"हटाउनुहोस्"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"अतिथिका रूपमा ब्राउज गर्ने सेसन रिसेट गरिँदै छ…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"अतिथि सत्र रिसेट गर्ने हो?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"यसो गर्नाले नयाँ अतिथि सत्र सुरु हुने छ र हालको अतिथि सत्रका सबै एप तथा डेटा मेटिने छ"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"अतिथि मोडबाट बाहिरिने हो?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"यसो गर्नाले हालको अतिथि सत्रका एप तथा डेटा मेटिने छ"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"बाहिरिनुहोस्"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"अतिथि सत्रमा गरिएका क्रियाकलाप सेभ गर्ने हो?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"तपाईं हालको सत्रमा गरिएका क्रियाकलाप सेभ गर्न वा सबै एप तथा डेटा मेटाउन सक्नुहुन्छ"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"मेटाउनुहोस्"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"सेभ गर्नुहोस्"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"अतिथि मोडबाट बाहिरिनुहोस्"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"अतिथि सत्र रिसेट गर्नुहोस्"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"अतिथि मोडबाट बाहिरिनुहोस्"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"अतिथि मोडबाट बाहिरिँदा सबै क्रियाकलाप मेटाइने छ"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"तपाईं अतिथि मोडबाट बाहिरिँदा आफ्ना क्रियाकलाप सेभ गर्ने वा मेटाउने विकल्प रोज्न सक्नुहुन्छ"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"यो सत्रमा गरिएका क्रियाकलाप अहिले नै मेटाउन रिसेट गर्नुहोस्, अथवा तपाईं अतिथि मोडबाट बाहिरिँदा आफ्ना क्रियाकलाप सेभ गर्ने वा मेटाउने विकल्प रोज्न सक्नुहुन्छ"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"फोटो खिच्नुहोस्"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"कुनै फोटो छनौट गर्नुहोस्"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"फोटो चयन गर्नुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index f250b60..360582f 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Snel opladen"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Langzaam opladen"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Draadloos opladen"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Oplaaddock"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Wordt niet opgeladen"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Verbonden, wordt niet opgeladen"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Opgeladen"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetten"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Verwijderen"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Gast resetten…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Gastsessie resetten?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Hierdoor wordt een nieuwe gastsessie gestart en worden alle apps en gegevens van de huidige sessie verwijderd"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Gastmodus sluiten?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Hierdoor worden apps en gegevens van de huidige gastsessie verwijderd"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Sluiten"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Gastactiviteit opslaan?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Sla activiteit van de huidige sessie op of verwijder alle apps en gegevens"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Verwijderen"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Opslaan"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Gastmodus sluiten"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Gastsessie resetten"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Gastmodus verlaten"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Alle activiteit wordt na het afsluiten verwijderd"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Je kunt je activiteit bij afsluiten opslaan of verwijderen"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Voer een reset uit om de sessie-activiteit nu te verwijderen of verwijder of sla je activiteit op bij afsluiten"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Foto maken"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Afbeelding kiezen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Foto selecteren"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index fa57c63..e25124c 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ଶୀଘ୍ର ଚାର୍ଜ ହେଉଛି"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ଧୀରେ ଚାର୍ଜ ହେଉଛି"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"ୱେୟରଲେସ ଭାବେ ଚାର୍ଜିଂ"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"ଡକ ଚାର୍ଜ ହେଉଛି"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ଚାର୍ଜ ହେଉନାହିଁ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ସଂଯୋଗ କରାଯାଇଛି, ଚାର୍ଜ ହେଉନାହିଁ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ଚାର୍ଜ ହୋଇଯାଇଛି"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ରିସେଟ୍ କରନ୍ତୁ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ଅତିଥି ସେସନକୁ ରିସେଟ୍ କରାଯାଉଛି…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"ଅତିଥି ସେସନକୁ ରିସେଟ କରିବେ?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ଏହା ଏକ ନୂଆ ଅତିଥି ସେସନ ଆରମ୍ଭ କରିବ ଏବଂ ବର୍ତ୍ତମାନର ସେସନରୁ ସମସ୍ତ ଆପ୍ସ ଏବଂ ଡାଟାକୁ ଡିଲିଟ କରିବ"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ଅତିଥି ମୋଡରୁ ବାହାରି ଯିବେ?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ଏହା ବର୍ତ୍ତମାନର ଅତିଥି ସେସନରୁ ଆପ୍ସ ଏବଂ ଡାଟାକୁ ଡିଲିଟ କରିବ"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ବାହାରି ଯାଆନ୍ତୁ"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ଅତିଥି କାର୍ଯ୍ୟକଳାପ ସେଭ କରିବେ?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"ଆପଣ ଏବେର ସେସନରୁ କାର୍ଯ୍ୟକଳାପକୁ ସେଭ କରିପାରିବେ ବା ସବୁ ଆପ୍ସ ଓ ଡାଟାକୁ ଡିଲିଟ କରିପାରିବେ"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ଡିଲିଟ କରନ୍ତୁ"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"ସେଭ କରନ୍ତୁ"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"ଅତିଥି ମୋଡରୁ ବାହାରି ଯାଆନ୍ତୁ"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"ଅତିଥି ସେସନକୁ ରିସେଟ କରନ୍ତୁ"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ଅତିଥି ମୋଡରୁ ବାହାରି ଯାଆନ୍ତୁ"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ବାହାରିବା ସମୟରେ ସମସ୍ତ କାର୍ଯ୍ୟକଳାପକୁ ଡିଲିଟ କରାଯିବ"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ବାହାରିବା ସମୟରେ ଆପଣଙ୍କର କାର୍ଯ୍ୟକଳାପକୁ ସେଭ ବା ଡିଲିଟ କରିପାରିବେ"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ବର୍ତ୍ତମାନ ସେସନ କାର୍ଯ୍ୟକଳାପକୁ ଡିଲିଟ କରିବାକୁ ରିସେଟ କରନ୍ତୁ କିମ୍ବା ବାହାରିବା ସମୟରେ ଆପଣ କାର୍ଯ୍ୟକଳାପକୁ ସେଭ କିମ୍ବା ଡିଲିଟ କରିପାରିବେ"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ଗୋଟିଏ ଫଟୋ ଉଠାନ୍ତୁ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ଏକ ଛବି ବାଛନ୍ତୁ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ଫଟୋ ବାଛନ୍ତୁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 90f2b0f..ca58fe9 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ਤੇਜ਼ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"ਬਿਨਾਂ ਤਾਰ ਤੋਂ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"ਡੌਕ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ਕਨੈਕਟ ਹੈ, ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਹੀ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ਚਾਰਜ ਹੋ ਗਈ"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ਰੀਸੈੱਟ ਕਰੋ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ਹਟਾਓ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ਮਹਿਮਾਨ ਨੂੰ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"ਕੀ ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਨੂੰ ਰੀਸੈੱਟ ਕਰਨਾ ਹੈ?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ਇਸ ਨਾਲ ਨਵਾਂ ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਸ਼ੁਰੂ ਹੋ ਜਾਵੇਗਾ ਅਤੇ ਮੌਜੂਦਾ ਸੈਸ਼ਨ ਦੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ਕੀ ਮਹਿਮਾਨ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਣਾ ਹੈ?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ਇਸ ਨਾਲ ਮੌਜੂਦਾ ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਦੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ਬਾਹਰ ਜਾਓ"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ਕੀ ਮਹਿਮਾਨ ਸਰਗਰਮੀ ਰੱਖਿਅਤ ਕਰਨੀ ਹੈ?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"ਤੁਸੀਂ ਮੌਜੂਦਾ ਸੈਸ਼ਨ ਦੀ ਸਰਗਰਮੀ ਨੂੰ ਰੱਖਿਅਤ ਕਰ ਸਕਦੇ ਹੋ ਜਾਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਮਿਟਾ ਸਕਦੇ ਹੋ"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ਮਿਟਾਓ"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"ਰੱਖਿਅਤ ਕਰੋ"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"ਮਹਿਮਾਨ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਨੂੰ ਰੀਸੈੱਟ ਕਰੋ"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ਮਹਿਮਾਨ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ਬਾਹਰ ਜਾਣ \'ਤੇ ਸਾਰੀ ਸਰਗਰਮੀ ਮਿਟਾਈ ਜਾਵੇਗੀ"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ਤੁਸੀਂ ਬਾਹਰ ਜਾਣ \'ਤੇ ਆਪਣੀ ਸਰਗਰਮੀ ਰੱਖਿਅਤ ਕਰ ਜਾਂ ਮਿਟਾ ਸਕਦੇ ਹੋ"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ਸੈਸ਼ਨ ਦੀ ਸਰਗਰਮੀ ਹੁਣੇ ਮਿਟਾਉਣ ਲਈ ਰੀਸੈੱਟ ਕਰੋ ਜਾਂ ਤੁਸੀਂ ਬਾਹਰ ਜਾਣ \'ਤੇ ਸਰਗਰਮੀ ਨੂੰ ਰੱਖਿਅਤ ਕਰ ਜਾਂ ਮਿਟਾ ਸਕਦੇ ਹੋ"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ਇੱਕ ਫ਼ੋਟੋ ਖਿੱਚੋ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ਕੋਈ ਚਿੱਤਰ ਚੁਣੋ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ਫ਼ੋਟੋ ਚੁਣੋ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 93e5c88..aec96a2 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Szybkie ładowanie"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Wolne ładowanie"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Ładowanie bezprzewodowe"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Ładowanie na stacji dokującej"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nie podłączony"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Podłączono, brak ładowania"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Naładowana"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetuj"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Usuń"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetuję sesję gościa…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Zresetować sesję gościa?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Zostanie uruchomiona nowa sesja gościa. Wszystkie aplikacje i dane z obecnej sesji zostaną usunięte."</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Zamknąć tryb gościa?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Wszystkie aplikacje i dane z obecnej sesji gościa zostaną usunięte."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Wyjdź"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Zapisać aktywność gościa?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Możesz zapisać aktywność z obecnej sesji lub usunąć wszystkie aplikacje i dane"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Usuń"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Zapisz"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Zamknij tryb gościa"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Zresetuj sesję gościa"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Zakończ tryb gościa"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Cała aktywność zostanie usunięta po zamknięciu"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Możesz zapisać lub usunąć swoją aktywność podczas zamykania."</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Zresetuj, aby teraz usunąć aktywność z tej sesji. Możesz też ją zapisać lub usunąć podczas zamykania sesji."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Zrób zdjęcie"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Wybierz obraz"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Wybierz zdjęcie"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 861c183..e883c8d 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregando rápido"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carregando devagar"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Carregando sem fio"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Base de carregamento"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Não está carregando"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado sem carregar"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Carregada"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Redefinir"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remover"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Redefinindo visitante…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Redefinir Sessão de visitante?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Essa ação vai iniciar uma nova Sessão de visitante e excluir todos os apps e dados da sessão atual"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sair do modo visitante?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Essa ação vai excluir apps e dados da Sessão de visitante atual"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Sair"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Salvar a atividade do visitante?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Você pode salvar a atividade da sessão atual ou excluir todos os apps e dados"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Excluir"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Salvar"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Sair do modo visitante"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Redefinir Sessão de visitante"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Sair do modo visitante"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Todas as atividades serão excluídas ao sair"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Você pode salvar ou excluir sua atividade ao sair"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Redefina para excluir a atividade da sessão agora. Salve ou exclua a atividade ao sair"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index ab0da74..2ebf1d7 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregamento rápido"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carregamento lento"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"A carregar sem fios"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Est. ancor. carreg."</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Não está a carregar"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ligado, não está a carregar"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Carregada"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Repor"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remover"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"A repor o convidado…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Repor sessão de convidado?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Esta ação inicia uma nova sessão de convidado e elimina todas as apps e dados da sessão atual"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sair do modo convidado?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Esta ação elimina as apps e os dados da sessão de convidado atual"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Sair"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Guardar atividade de convidado?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Pode guardar a atividade da sessão atual ou eliminar todas as apps e dados"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Eliminar"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Guardar"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Sair do modo convidado"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Repor sessão de convidado"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Sair do modo de convidado"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toda a atividade é eliminada ao sair"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Pode guardar ou eliminar a sua atividade ao sair"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reponha para eliminar agora a atividade da sessão. Pode ainda guardar ou eliminar a atividade ao sair"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 861c183..e883c8d 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregando rápido"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carregando devagar"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Carregando sem fio"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Base de carregamento"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Não está carregando"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado sem carregar"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Carregada"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Redefinir"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remover"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Redefinindo visitante…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Redefinir Sessão de visitante?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Essa ação vai iniciar uma nova Sessão de visitante e excluir todos os apps e dados da sessão atual"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Sair do modo visitante?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Essa ação vai excluir apps e dados da Sessão de visitante atual"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Sair"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Salvar a atividade do visitante?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Você pode salvar a atividade da sessão atual ou excluir todos os apps e dados"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Excluir"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Salvar"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Sair do modo visitante"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Redefinir Sessão de visitante"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Sair do modo visitante"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Todas as atividades serão excluídas ao sair"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Você pode salvar ou excluir sua atividade ao sair"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Redefina para excluir a atividade da sessão agora. Salve ou exclua a atividade ao sair"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index f84dec6..39f304c 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Se încarcă rapid"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Se încarcă lent"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Se încarcă wireless"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Suport de încărcare"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nu se încarcă"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectat, nu se încarcă"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Încărcată"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetați"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Eliminați"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Se resetează invitatul…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Resetați sesiunea pentru invitați?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Astfel, va începe o nouă sesiune pentru invitați și se vor șterge toate aplicațiile și datele din sesiunea actuală"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Ieșiți din modul pentru invitați?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Se vor șterge toate aplicațiile și datele din sesiunea pentru invitați actuală"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Ieșiți"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Salvați activitatea invitatului?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Salvați activitatea din sesiunea actuală sau ștergeți aplicațiile și datele"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Ștergeți"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Salvați"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Ieșiți din modul pentru invitați"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Resetați sesiunea pentru invitați"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Ieșiți din modul pentru invitați"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toate activitățile vor fi șterse la ieșire"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puteți să salvați sau să ștergeți activitatea la ieșire"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetați pentru a șterge acum activitatea din sesiune sau salvați ori ștergeți activitatea la ieșire"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Faceți o fotografie"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Alegeți o imagine"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selectați fotografia"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index d70e31a..68543a0 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Быстрая зарядка"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Медленная зарядка"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Беспроводная зарядка"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Док-станция: зарядка"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не заряжается"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Подключено, не заряжается"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Батарея заряжена"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Сбросить"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Удалить"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Сброс гостевого сеанса…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Сбросить гостевой сеанс?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"При этом начнется новый гостевой сеанс, а все данные и приложения предыдущего сеанса будут удалены."</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Выйти из гостевого режима?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Все приложения и данные текущего гостевого сеанса будут удалены."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Выйти"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Сохранить историю сеанса?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Сохраните историю текущего сеанса или удалите данные и приложения."</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Удалить"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Сохранить"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Выйти из гостевого режима"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Сбросить гостевой сеанс"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Выйти из гостевого режима"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"История будет удалена сразу после выхода."</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"При выходе вы можете сохранить или удалить историю."</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Можно сбросить историю сеанса прямо сейчас, либо удалить или сохранить ее при выходе."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Сделать снимок"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбрать фото"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Выбрать фотографию"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 217ba1d..dbc1fc2 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ශීඝ්‍ර ආරෝපණය"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"සෙමින් ආරෝපණය"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"නොරැහැන්ව ආරෝපණය වේ"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"ආරෝපණ ඩොකය"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ආරෝපණය නොවේ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"සම්බන්ධයි, ආරෝපණය නොවේ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"අරෝපිතයි"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"යළි සකසන්න"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ඉවත් කරන්න"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"අමුත්තා යළි සකසමින්…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"ආගන්තුක සැසිය යළි සකසන්නද?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"මෙය නව ආගන්තුක සැසියක් ආරම්භ කර වත්මන් සැසියෙන් සියලු යෙදුම් සහ දත්ත මකනු ඇත"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ආගන්තුක ප්‍රකාරයෙන් පිටවන්නද?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"මෙය වත්මන් ආගන්තුක සැසියෙන් යෙදුම් සහ දත්ත මකනු ඇත"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"පිටවන්න"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"ආගන්තුක ක්‍රියාකාරකම් සුරකින්නද?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"ඔබට වත්මන් සැසියෙන් ක්‍රියාකාරකම් සුරැකීමට හෝ සියලු යෙදුම් සහ දත්ත මැකීමට හැකිය"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"මකන්න"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"සුරකින්න"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"ආගන්තුක ප්‍රකාරයෙන් පිටවන්න"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"ආගන්තුක සැසිය යළි සකසන්න"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"අමුත්තා පිටවීම"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"පිටවීමේදී සියලු ක්‍රියාකාරකම් මකනු ඇත"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ඔබට පිටවීමේදී ඔබගේ ක්‍රියාකාරකම් සුරැකීමට හෝ මැකීමට හැකිය"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"දැන් සැසි ක්‍රියාකාරකම් මැකීමට යළි සකසන්න, නැතහොත් ඔබට පිටවීමේදී ක්‍රියාකාරකම් සුරැකීමට හෝ මැකීමට හැකිය"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ඡායාරූපයක් ගන්න"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"රූපයක් තෝරන්න"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ඡායාරූපය තෝරන්න"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 51588e3..a3a0e23 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rýchle nabíjanie"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Pomalé nabíjanie"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Nabíja sa bezdrôtovo"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Nabíjací dok"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nenabíja sa"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Pripojené, nenabíja sa"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Nabité"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetovať"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Odstrániť"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Relácia hosťa sa resetuje…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Chcete resetovať reláciu hosťa?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Týmto sa spustí nová relácia hosťa a odstránia sa všetky aplikácie a údaje z aktuálnej relácie"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Chcete ukončiť režim pre hostí?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ukončí sa režim pre hostí a odstránia sa aplikácie a údaje z relácie hosťa"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Ukončiť"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Chcete uložiť aktivitu hosťa?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Môžte uložiť aktivitu aktuálnej relácie alebo odstrániť všetky aplikácie a údaje"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Odstrániť"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Uložiť"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Ukončiť režim pre hostí"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Resetovať reláciu hosťa"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Ukončiť režim pre hostí"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Pri ukončení sa všetka aktivita odstráni"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Aktivitu môžete pri ukončení uložiť alebo odstrániť"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetovaním ihneď odstránite aktivitu relácie alebo ju uložte či odstráňte pri ukončení relácie"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Odfotiť"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrať obrázok"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Vybrať fotku"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index d1c3558..7e2172f 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hitro polnjenje"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Počasno polnjenje"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Brezžično polnjenje"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Polnjenje na nosilcu"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Se ne polni"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Povezano, se ne polni"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Napolnjeno"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ponastavi"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Odstrani"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Ponastavljanje gosta …"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Želite ponastaviti sejo gosta?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"S tem boste začeli novo sejo gosta ter izbrisali vse aplikacije in podatke v trenutni seji."</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Želite zapreti način za goste?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"S tem boste izbrisali aplikacije in podatke v trenutni seji gosta."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Zapri"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Želite shraniti dejavnost gosta?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Lahko shranite dejavnost v trenutni seji ali izbrišete vse aplikacije in podatke."</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Izbriši"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Shrani"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Zapri način za goste"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Ponastavi sejo gosta"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Zapri sejo gosta"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Ko zaprete način za goste, bo vsa dejavnost izbrisana."</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Ob zaprtju načina lahko shranite ali izbrišete dejavnost."</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ponastavite za izbris dejavnosti v seji zdaj, lahko pa jo shranite ali izbrišete, ko zaprete način za goste."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiranje"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Izberi sliko"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Izbira fotografije"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 57f059a..e6bf1c1 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Karikim i shpejtë"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Po karikohet ngadalë"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Po karikohet pa tel"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Në stacion karikimi"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nuk po karikohet"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Lidhur, jo në karikim"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Karikuar"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Rivendos"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Hiq"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Vizitori po rivendoset…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Të rivendoset sesioni për vizitorë?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Kjo do të fillojë një sesion të ri për vizitorë dhe do të fshijë të gjitha aplikacionet dhe të dhënat nga sesioni aktual"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Të hiqet modaliteti \"vizitor\"?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Kjo do të fshijë aplikacionet dhe të dhënat nga sesioni aktual për vizitorë"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Dil"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Të ruhet aktiviteti i vizitorit?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Ruaj aktivitetin nga sesioni aktual ose fshi të gjitha aplikacionet e të dhënat"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Fshi"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Ruaj"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Dil nga modaliteti \"vizitor\""</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Rivendos sesionin për vizitorë"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Dil nga modaliteti \"vizitor\""</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Të gjitha aktivitetet do të fshihen kur të dalësh"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Mund ta ruash ose ta fshish aktivitetin tënd kur të dalësh"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Rivendose për të fshirë aktivitetin e sesionit tani ose mund ta ruash ose ta fshish aktivitetin kur të dalësh"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Bëj një fotografi"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Zgjidh një imazh"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Zgjidh një fotografi"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 4d8a11f..e429a63 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо се пуни"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Споро се пуни"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Бежично пуњење"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Станица за пуњење"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не пуни се"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Повезано, не пуни се"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Напуњено"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетуј"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Уклони"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Сесија госта се ресетује…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Желите да ресетујете сесију госта?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Тиме ћете покренути нову сесију госта и избрисати све апликације и податке из актуелне сесије"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Изаћи ћете из режима госта?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Тиме ћете избрисати све апликације и податке из актуелне сесије госта"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Изађи"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Сачуваћете активности госта?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Сачувајте активности из актуелне сесије или избришите све апликације и податке"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Избриши"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Сачувај"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Изађи из режима госта"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Ресетуј сесију госта"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Изађи из режима госта"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Све активности ће бити избрисане при излазу"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Можете да сачувате или избришете активности при излазу"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ресетујете за брисање активности сесије, или сачувајте или избришите активности при излазу"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Изаберите слику"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index ea859e49..faf7c4b9e 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laddas snabbt"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Laddas långsamt"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Laddas trådlöst"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Dockningsstation"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Laddar inte"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ansluten, laddas inte"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Laddat"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Återställ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ta bort"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Gästsessionen återställs …"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Vill du återställa gästsessionen?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"En ny gästsession startas och alla appar och all data från den pågående sessionen raderas"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Vill du avsluta gästläget?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Appar och data från den pågående gästsessionen raderas"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Avsluta"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Vill du spara gästaktivitet?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Du kan spara aktivitet från den pågående sessionen eller radera appar och data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Radera"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Spara"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Avsluta gästläget"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Återställ gästsession"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Avsluta gästsession"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All aktivitet raderas när du avslutar"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Du kan spara eller radera aktivitet när du avslutar"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Återställ om du vill radera sessionsaktiviteten nu, eller spara eller radera aktivitet när du avslutar"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Ta ett foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Välj en bild"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Välj foto"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 2a3a6fb..71eb1a8 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Inachaji kwa kasi"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Inachaji pole pole"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Inachaji bila kutumia waya"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Kituo cha Kuchaji"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Haichaji"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Imeunganishwa, haichaji"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Imechajiwa"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Badilisha"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ondoa"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Inabadilisha kipindi cha mgeni…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Ungependa kuweka upya kipindi cha mgeni?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Hii itaanzisha upya kipindi cha mgeni na kufuta programu na data yote kwenye kipindi cha sasa"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Utafunga matumizi ya wageni?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Hatua hii itafuta programu na data kutoka kwenye kipindi cha mgeni cha sasa"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Funga"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Utahifadhi shughuli za mgeni?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Unaweza kuhifadhi shughuli kutoka kipindi cha sasa au kufuta programu na data yote"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Futa"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Hifadhi"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Funga matumizi ya wageni"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Weka upya kipindi cha mgeni"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Funga utumiaji wa mgeni"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Shughuli zote zitafutwa wakati wa kufunga"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Unaweza kuhifadhi au kufuta shughuli zako wakati wa kufunga"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Weka upya ili ufute shughuli za kipindi sasa au unaweza kuhifadhi au kufuta shughuli wakati wa kufunga"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Piga picha"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Chagua picha"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Chagua picha"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 6d4c579..1c60acc 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"வேகமாக சார்ஜாகிறது"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"மெதுவாக சார்ஜாகிறது"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"வயரின்றி சார்ஜாகிறது"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"சார்ஜிங் டாக்"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"சார்ஜ் செய்யப்படவில்லை"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"இணைக்கப்பட்டுள்ளது, சார்ஜாகவில்லை"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"சார்ஜாகிவிட்டது"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"மீட்டமை"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"அகற்று"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"கெஸ்ட்டை மீட்டமைக்கிறது…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"கெஸ்ட் அமர்வை ரீசெட் செய்யவா?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"புதிய கெஸ்ட் அமர்வு தொடங்கப்படும், மேலும் தற்போதைய கெஸ்ட் அமர்வின் ஆப்ஸ் மற்றும் தரவு அனைத்தும் நீக்கப்படும்"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"கெஸ்ட் முறையிலிருந்து வெளியேறவா?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"தற்போதைய கெஸ்ட் அமர்வின் ஆப்ஸ் மற்றும் தரவு அனைத்தும் நீக்கப்படும்"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"வெளியேறு"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"கெஸ்ட் செயல்பாடுகளைச் சேமிக்கவா?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"தற்போதைய அமர்வின் செயல்பாடுகளைச் சேமிக்கலாம் அல்லது ஆப்ஸையும் தரவையும் நீக்கலாம்"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"நீக்கு"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"சேமி"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"கெஸ்ட் பயன்முறையிலிருந்து வெளியேறு"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"கெஸ்ட் அமர்வை ரீசெட் செய்"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"கெஸ்ட் பயன்முறையிலிருந்து வெளியேறு"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"வெளியேறியவுடன் அனைத்துச் செயல்பாடுகளும் நீக்கப்படும்"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"வெளியேறும்போது செயல்பாடுகளைச் சேமிக்கலாம் அல்லது நீக்கலாம்"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"அமர்வின் செயல்பாடுகளை இப்போதே நீக்க ரீசெட் செய்யவும் அல்லது வெளியேறும்போது செயல்பாடுகளைச் சேமிக்கலாம் அல்லது நீக்கலாம்"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"படமெடுங்கள்"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"படத்தைத் தேர்வுசெய்யுங்கள்"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"படத்தைத் தேர்ந்தெடுங்கள்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 5e6fa8e..5963495 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"వేగవంతమైన ఛార్జింగ్"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"నెమ్మదిగా ఛార్జింగ్"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"వైర్‌లెస్ ఛార్జింగ్"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"ఛార్జింగ్ డాక్"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ఛార్జ్ కావడం లేదు"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"కనెక్ట్ చేయబడింది, ఛార్జ్ చేయబడలేదు"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ఛార్జ్ చేయబడింది"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"రీసెట్ చేయండి"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"తీసివేయండి"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"గెస్ట్ సెషన్‌ను రీసెట్ చేస్తోంది…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"గెస్ట్ సెషన్‌ను రీసెట్ చేయాలా?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ఇది కొత్త గెస్ట్ సెషన్‌ను ప్రారంభిస్తుంది, ప్రస్తుత సెషన్ నుండి అన్ని యాప్‌లు, డేటాను తొలగిస్తుంది."</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"గెస్ట్ మోడ్ నిష్క్రమించాలా?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"ఇది ప్రస్తుత గెస్ట్ సెషన్ నుండి యాప్‌లను వాటితో పాటు డేటాను తొలగిస్తుంది"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"నిష్క్రమించండి"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"గెస్ట్ యాక్టివిటీని సేవ్ చేయాలా?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"మీరు సెషన్ నుండి యాక్టివిటీని సేవ్ చేయవచ్చు, అన్ని యాప్‌లు, డేటాను తొలగించవచ్చు"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"తొలగించండి"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"సేవ్ చేయండి"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"గెస్ట్ మోడ్ నుండి వైదొలగండి"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"గెస్ట్ సెషన్‌ను రీసెట్ చేయండి"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"గెస్ట్ మోడ్ నుండి నిష్క్రమించండి"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"నిష్క్రమణ సమయంలో మొత్తం యాక్టివిటీ తొలగించబడుతుంది"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"మీ నిష్క్రమణలో, యాక్టివిటీని సేవ్ చేయవచ్చు లేదా తొలగించవచ్చు"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"సెషన్ యాక్టివిటీని తొలగించడానికి ఇప్పుడే రీసెట్ చేయండి లేదా మీరు నిష్క్రమించేటప్పుడు యాక్టివిటీని సేవ్ చేయవచ్చు లేదా తొలగించవచ్చు"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ఒక ఫోటో తీయండి"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ఇమేజ్‌ను ఎంచుకోండి"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ఫోటోను ఎంచుకోండి"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 772a979..e46bdc4 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"กำลังชาร์จอย่างเร็ว"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"กำลังชาร์จอย่างช้าๆ"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"กำลังชาร์จแบบไร้สาย"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"กำลังชาร์จบนแท่น"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ไม่ได้ชาร์จ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"เชื่อมต่ออยู่ ไม่ได้ชาร์จ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ชาร์จแล้ว"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"รีเซ็ต"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"นำออก"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"กำลังรีเซ็ตผู้เข้าร่วม…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"รีเซ็ตเซสชันผู้ใช้ชั่วคราวไหม"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"การดำเนินการนี้จะเริ่มเซสชันผู้ใช้ชั่วคราวใหม่ และจะลบแอปและข้อมูลทั้งหมดจากเซสชันปัจจุบัน"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"ออกจากโหมดผู้ใช้ชั่วคราวไหม"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"การดำเนินการนี้จะลบแอปและข้อมูลออกจากเซสชันผู้ใช้ชั่วคราวในปัจจุบัน"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"ออก"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"บันทึกกิจกรรมของผู้ใช้ชั่วคราวไหม"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"คุณสามารถบันทึกกิจกรรมจากเซสชันปัจจุบันหรือจะลบแอปและข้อมูลทั้งหมดก็ได้"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"ลบ"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"บันทึก"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"ออกจากโหมดผู้ใช้ชั่วคราว"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"รีเซ็ตเซสชันผู้ใช้ชั่วคราว"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ออกจากโหมดผู้ใช้ชั่วคราว"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ระบบจะลบกิจกรรมทั้งหมดเมื่อออก"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"คุณสามารถบันทึกหรือลบกิจกรรมเมื่อออก"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"รีเซ็ตเพื่อลบกิจกรรมของเซสชันตอนนี้เลย หรือจะ​บันทึกหรือลบกิจกรรมเมื่อออกก็ได้"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ถ่ายรูป"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"เลือกรูปภาพ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"เลือกรูปภาพ"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index d9d4e3a..21d07c1 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mabilis na charge"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Mabagal na charge"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Wireless na nagcha-charge"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Charging Dock"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Hindi nagcha-charge"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Nakakonekta, hindi nagcha-charge"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Nasingil"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"I-reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Alisin"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Nire-reset ang bisita…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"I-reset ang session ng bisita?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Magsisimula ito ng bagong session ng bisita at made-delete ang lahat ng app at data mula sa kasalukuyang session"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Umalis sa guest mode?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Ide-delete nito ang mga app at data mula sa kasalukuyang session ng bisita"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Umalis"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"I-save ang aktibidad ng bisita?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Puwedeng i-save ang aktibidad ng session ngayon o i-delete lahat ng app at data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"I-delete"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"I-save"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Umalis sa guest mode"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"I-reset ang session ng bisita"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Umalis sa pagiging bisita"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Made-delete ang lahat ng aktibidad kapag umalis"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puwede mong i-save o i-delete ang aktibidad pagkaalis"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Mag-reset para mag-delete ng aktibidad ng session ngayon, o puwede kang mag-save o mag-delete ng aktibidad pagkaalis"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Kumuha ng larawan"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Pumili ng larawan"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pumili ng larawan"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index c47e8ee..0a5f7da 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hızlı şarj oluyor"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Yavaş şarj oluyor"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Kablosuz şarj oluyor"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Şarj Yuvası"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Şarj olmuyor"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Bağlandı, şarj olmuyor"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Şarj oldu"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Sıfırla"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Kaldır"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Misafir oturumu sıfırlanıyor…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Misafir oturumu sıfırlansın mı?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Bu işlem, yeni bir misafir oturumu başlatarak mevcut oturumdaki tüm uygulamaları ve verileri siler"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Misafir modundan çıkılsın mı?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Bu işlem mevcut misafir oturumundaki tüm uygulamaları ve verileri siler"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Çık"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Misafir etkinliği kaydedilsin mi?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Oturumdaki etkinliği kaydedebilir ya da tüm uygulama ve verileri silebilirsiniz"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Sil"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Kaydet"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Misafir modundan çık"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Misafir oturumunu sıfırla"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Misafir modundan çık"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Çıkış yapıldığında tüm etkinlikler silinir"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Etkinliklerinizi çıkarken kaydedebilir veya silebilirsiniz"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Oturum etkinliklerini silmek için sıfırlayabilir ya da çıkarken kaydedebilir veya silebilirsiniz"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotoğraf çek"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Resim seç"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Fotoğraf seç"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 00c2153..769aab7 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Швидке заряджання"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Повільне заряджання"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Бездротове заряджання"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Зарядка: док-станція"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не заряджається"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Підключено, не заряджається"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Заряджено"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Скинути"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Вилучити"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Скидання сеансу в режимі \"Гість\"…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Скинути сеанс у режимі гостя?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Почнеться новий сеанс у режимі гостя, а всі додатки й дані з поточного сеансу буде видалено"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Вийти з режиму гостя?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Усі додатки й дані з поточного сеансу в режимі гостя буде видалено."</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Вийти"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Зберегти дії в режимі гостя?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Ви можете зберегти дії з поточного сеансу або видалити всі додатки й дані"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Видалити"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Зберегти"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Вийти з режиму гостя"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Скинути сеанс у режимі гостя"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Вийти з режиму гостя"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Під час виходу буде видалено історію всіх дій"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Під час виходу можна зберегти або видалити ваші дії"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Можна скинути історію сеансу просто зараз або видалити чи зберегти її під час виходу."</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Зробити фотографію"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Вибрати зображення"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Вибрати фотографію"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 43dee94..5d7928b 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"تیزی سے چارج ہو رہا ہے"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"آہستہ چارج ہو رہی ہے"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"وائرلیس طریقے سے چارج ہو رہی ہے"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"چارجنگ ڈاک"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"چارج نہیں ہو رہا ہے"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"منسلک ہے، چارج نہیں ہو رہی ہے"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"چارج ہو گئی"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ری سیٹ کریں"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ہٹائیں"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"مہمان کو ری سیٹ کرنا…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"مہمان سیشن کو ری سیٹ کریں؟"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"اس سے ایک نیا مہمان سیشن شروع ہو گا اور موجودہ سیشن سے تمام ایپس اور ڈیٹا حذف ہو جائے گا"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"مہمان وضع سے باہر نکلیں؟"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"یہ موجودہ مہمان سیشن سے ایپس اور ڈیٹا کو حذف کر دے گا"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"باہر نکلیں"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"مہمان کی سرگرمی محفوظ کریں؟"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"آپ موجودہ سیشن سے سرگرمی کو محفوظ یا تمام ایپس اور ڈیٹا کو حذف کر سکتے ہیں"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"حذف کریں"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"محفوظ کریں"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"مہمان وضع سے باہر نکلیں"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"مہمان سیشن کو ری سیٹ کریں"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"مہمان وضع سے باہر نکلیں"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"باہر نکلنے پر تمام سرگرمیاں حذف کر دی جائیں گی"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"باہر نکلنے پر آپ اپنی سرگرمی کو محفوظ یا حذف کر سکتے ہیں"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"سیشن کی سرگرمی کو ابھی حذف کرنے کے لیے ری سیٹ کریں، یا باہر نکلنے پر آپ اپنی سرگرمی کو محفوظ یا حذف کر سکتے ہیں"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"ایک تصویر لیں"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ایک تصویر منتخب کریں"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"تصویر منتخب کریں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 22251c3..46cd596 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Tezkor quvvat olmoqda"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Sekin quvvat olmoqda"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Simsiz quvvat olmoqda"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Quvvatlash doki"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Quvvat olmayapti"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ulangan, quvvat olmayapti"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Quvvat oldi"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tiklash"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Olib tashlash"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Mehmon seansi tiklanmoqda…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Mehmon seansi tiklansinmi?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Bunda yangi mehmon seansi ishga tushadi va joriy seans ilova va maʼlumotlari tozalanadi"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Mehmon rejimidan chiqasizmi?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Bunda joriy mehmon seansidagi ilova va ularning maʼlumotlari tozalanadi"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Chiqish"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Mehmon faoliyati saqlansinmi?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Joriy seansdagi faoliyatni saqlash yoki barcha ilova va maʼlumotlarni oʻchirib tashlashingiz mumkin"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Oʻchirish"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Saqlash"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Mehmon rejimidan chiqish"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Mehmon seansini tiklash"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Mehmon rejimidan chiqish"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Chiqishda faolliklar tarixi tozalab tashlanadi"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Chiqish vaqtida faoliyatni saqlash yoki tozalash mumkin"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Faoliyat hozir tozalanib tiklanishi yoki chiqish vaqtida saqlanishi yoki tozalanishi mumkin"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Suratga olish"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Rasm tanlash"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Surat tanlash"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index cb9a18f..22ead80 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Đang sạc nhanh"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Đang sạc chậm"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Đang sạc không dây"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Đế sạc"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Hiện không sạc"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Đã kết nối nhưng chưa sạc"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Đã sạc"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Đặt lại"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Xoá"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Đang đặt lại phiên khách…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Đặt lại phiên khách?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Thao tác này sẽ bắt đầu một phiên khách mới và xoá mọi ứng dụng cũng như dữ liệu trong phiên hiện tại"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Thoát khỏi chế độ khách?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Thao tác này sẽ xoá các ứng dụng và dữ liệu trong phiên khách hiện tại"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Thoát"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Lưu hoạt động ở chế độ khách?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Bạn có thể lưu hoạt động trong phiên hiện tại hoặc xoá mọi ứng dụng và dữ liệu"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Xoá"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Lưu"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Thoát khỏi chế độ khách"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Đặt lại phiên khách"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Thoát khỏi chế độ khách"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Mọi hoạt động sẽ bị xoá khi thoát"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Bạn có thể lưu hoặc xoá hoạt động của mình khi thoát"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Đặt lại để xoá hoạt động trong phiên ngay bây giờ, hoặc bạn có thể lưu hoặc xoá hoạt động khi thoát"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Chụp ảnh"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Chọn một hình ảnh"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Chọn ảnh"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index e5dd6a0..1a44ac2 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"正在快速充电"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"正在慢速充电"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"正在无线充电"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"充电基座"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"未在充电"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"已连接,未充电"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"已充满电"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"重置"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"移除"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"正在重置访客会话…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"要重置访客会话吗?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"此操作会开始新的访客会话,并删除当前会话中的所有应用和数据"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"要退出访客模式吗?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"此操作会删除当前访客会话中的所有应用和数据"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"退出"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"要保存访客活动记录吗?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"您可以保存当前会话中的活动记录,也可以删除所有应用和数据"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"删除"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"保存"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"退出访客模式"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"重置访客会话"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"退出访客模式"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"退出时所有活动记录都将被删除"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"您可以在退出时保存或删除您的活动记录"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"请立即重置以删除会话活动记录;或者,您也可以在退出时保存或删除活动记录"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"拍摄照片"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"选择图片"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"选择照片"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index cfa3c06..c497b58 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"慢速充電中"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"無線充電中"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"充電插座"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"非充電中"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"已連接,非充電中"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"已充滿電"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"重設"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"移除"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"正在重設訪客…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"要重設訪客工作階段嗎?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"此操作會開始新的訪客工作階段,並刪除目前工作階段的所有應用程式和資料"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"要結束訪客模式嗎?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"此操作會刪除目前訪客工作階段中的所有應用程式和資料"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"結束"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"要儲存訪客活動嗎?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"您可儲存目前工作階段中的活動或刪除所有應用程式和資料"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"刪除"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"儲存"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"結束訪客模式"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"重設訪客工作階段"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"結束訪客模式"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"結束時將會刪除所有活動"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"您可以在結束時儲存或刪除活動"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"重設可立即刪除工作階段活動,或者您可以在結束時儲存或刪除活動"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"揀相"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index e439ef5..bb126c2 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"慢速充電中"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"正在進行無線充電"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"充電座架"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"非充電中"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"已連接,尚未充電"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"充電完成"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"重設"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"移除"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"正在重設訪客…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"要重設訪客工作階段嗎?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"這麼做將開始新的訪客工作階段,並刪除目前工作階段中的所有應用程式和資料"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"要結束訪客模式嗎?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"這麼做將刪除目前訪客工作階段中的所有應用程式和資料"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"結束"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"要儲存訪客活動嗎?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"你可以儲存目前工作階段中的活動,也可以刪除所有應用程式和資料"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"刪除"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"儲存"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"結束訪客模式"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"重設訪客工作階段"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"結束訪客模式"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"結束時將刪除所有活動"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"你可以在結束時儲存或刪除活動"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"重設即可立即刪除工作階段活動,你也可以在結束時儲存或刪除活動"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"選取相片"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index ebc9cb7..c9d4b63 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -482,6 +482,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ishaja ngokushesha"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Ishaja kancane"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Iyashaja ngaphandle kwentambo"</string>
+    <string name="battery_info_status_charging_dock" msgid="3554147903321236585">"Idokhu yokushaja"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ayishaji"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ixhunyiwe, ayishaji"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Kushajiwe"</string>
@@ -598,6 +599,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Setha kabusha"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Susa"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Ukusetha kabusha isimenywa…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Sesha kabusha isikhathi sesihambeli?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Lokhu kuzoqala isikhathi sesihambeli esisha futhi kusule wonke ama-app nedatha kusuka esikhathini samanje"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Phuma kumodi yesihambeli?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Lokhu kuzosula ama-app nedatha kusuka esikhathini sesihambeli samanje"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Phuma"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Londoloza umsebenzi wesihambeli?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Ungalondoloza umsebenzi kusuka esikhathini samanje noma usule wonke ama-app nedatha"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Sula"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Londoloza"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Phuma kumodi yesivakashi"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Setha kabusha isikhathi sesihambeli"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Phuma kusivakashi"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Wonke umsebenzi uzosulwa lapho uphuma"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Ungalondoloza noma usule umsebenzi wakho lapho uphuma"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Setha kabusha ukuze usule umsebenzi wesikhathi manje, noma ungalondoloza noma usule umsebenzi lapho uphuma"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Thatha isithombe"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Khetha isithombe"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Khetha isithombe"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 847f1dc..f92cc8e 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1134,6 +1134,8 @@
     <string name="battery_info_status_charging_slow">Charging slowly</string>
     <!-- [CHAR_LIMIT=20] Battery use screen.  Battery status shown in chart label when charging wirelessly.  -->
     <string name="battery_info_status_charging_wireless">Charging wirelessly</string>
+    <!-- [CHAR_LIMIT=20] Battery use screen.  Battery status shown in chart label when the device is dock charging.  -->
+    <string name="battery_info_status_charging_dock">Charging Dock</string>
     <!-- Battery Info screen. Value for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="battery_info_status_discharging">Not charging</string>
     <!-- Battery Info screen. Value for a status item. A state which device is connected with any charger(e.g. USB, Adapter or Wireless) but not charging yet. Used for diagnostic info screens, precise translation isn't needed -->
@@ -1438,6 +1440,44 @@
     <string name="guest_remove_guest_confirm_button">Remove</string>
     <!-- Status message indicating the device is in the process of resetting the guest user. [CHAR_LIMIT=NONE] -->
     <string name="guest_resetting">Resetting guest\u2026</string>
+    <!-- Dialog title on action reset and restart guest [CHAR LIMIT=60] -->
+    <string name="guest_reset_and_restart_dialog_title">Reset guest session?</string>
+    <!-- Dialog message on action reset and restart guest [CHAR LIMIT=160] -->
+    <string name="guest_reset_and_restart_dialog_message">This will start a new guest
+        session and delete all apps and data from the current session</string>
+    <!-- Dialog title on action exit guest (ephemeral guest) [CHAR LIMIT=32] -->
+    <string name="guest_exit_dialog_title">Exit guest mode?</string>
+    <!-- Dialog message on action exit guest (ephemeral guest) [CHAR LIMIT=80] -->
+    <string name="guest_exit_dialog_message">This will delete
+        apps and data from the current guest session</string>
+    <!-- Dialog button on action exit guest (ephemeral guest) [CHAR LIMIT=80] -->
+    <string name="guest_exit_dialog_button">Exit</string>
+    <!-- Dialog title on action exit guest (non-ephemeral guest) [CHAR LIMIT=32] -->
+    <string name="guest_exit_dialog_title_non_ephemeral">Save guest activity?</string>
+    <!-- Dialog message on action exit guest (non-ephemeral guest) [CHAR LIMIT=80] -->
+    <string name="guest_exit_dialog_message_non_ephemeral">You can save activity from
+        the current session or delete all apps and data</string>
+    <!-- Button on guest exit, clear data (non-ephemeral guest) [CHAR LIMIT=80] -->
+    <string name="guest_exit_clear_data_button">Delete</string>
+    <!-- Button on guest exit, save data (non-ephemeral guest) [CHAR LIMIT=80] -->
+    <string name="guest_exit_save_data_button">Save</string>
+    <!-- Label for button in confirmation dialog when exiting guest user [CHAR LIMIT=35] -->
+    <string name="guest_exit_button">Exit guest mode</string>
+    <!-- Label for button in confirmation dialog when resetting guest user [CHAR LIMIT=35] -->
+    <string name="guest_reset_button">Reset guest session</string>
+    <!-- Label for guest icon in quick settings user switcher [CHAR LIMIT=35] -->
+    <string name="guest_exit_quick_settings_button">Exit guest</string>
+    <!-- Message of the notification when guest mode is entered
+         and it's a ephemeral guest [CHAR LIMIT=60] -->
+    <string name="guest_notification_ephemeral">All activity will be deleted on exit</string>
+    <!-- Message of the notification when guest mode is entered
+         and it's not a ephemeral guest and it's a first time guest login [CHAR LIMIT=60] -->
+    <string name="guest_notification_non_ephemeral">You can save or delete your activity on exit</string>
+    <!-- Message of the notification when guest mode is entered
+         and it's not a ephemeral guest and it's not a first time guest login [CHAR LIMIT=NONE] -->
+    <string name="guest_notification_non_ephemeral_non_first_login">Reset to delete session
+        activity now, or you can save or delete activity on exit</string>
+
     <!-- An option in a photo selection dialog to take a new photo [CHAR LIMIT=50] -->
     <string name="user_image_take_photo">Take a photo</string>
     <!-- An option in a photo selection dialog to choose a pre-existing image [CHAR LIMIT=50] -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index feb4212..b9c4030 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -239,6 +239,8 @@
                             statusString = res.getString(R.string.battery_info_status_charging);
                             break;
                     }
+                } else if (batteryStatus.isPluggedInDock()) {
+                    statusString = res.getString(R.string.battery_info_status_charging_dock);
                 } else {
                     statusString = res.getString(R.string.battery_info_status_charging_wireless);
                 }
diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp
index 64563be..d463170 100644
--- a/packages/SettingsLib/tests/integ/Android.bp
+++ b/packages/SettingsLib/tests/integ/Android.bp
@@ -25,7 +25,7 @@
     name: "SettingsLibTests",
     defaults: [
         "SettingsLibDefaults",
-        "framework-wifi-test-defaults"
+        "framework-wifi-test-defaults",
     ],
 
     certificate: "platform",
@@ -47,6 +47,7 @@
         "androidx.test.espresso.core",
         "mockito-target-minus-junit4",
         "truth-prebuilt",
+        "SettingsLibDeviceStateRotationLock",
         "SettingsLibSettingsSpinner",
         "SettingsLibUsageProgressBarPreference",
     ],
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index 09b2a2e..336cdd3 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -365,6 +365,17 @@
     }
 
     @Test
+    public void getBatteryStatus_chargingDock_returnDockChargingString() {
+        final Intent intent = new Intent();
+        intent.putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_CHARGING);
+        intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_DOCK);
+        final Resources resources = mContext.getResources();
+
+        assertThat(Utils.getBatteryStatus(mContext, intent, /* compactStatus= */ false)).isEqualTo(
+                resources.getString(R.string.battery_info_status_charging_dock));
+    }
+
+    @Test
     public void getBatteryStatus_chargingWireless_returnWirelessChargingString() {
         final Intent intent = new Intent();
         intent.putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_CHARGING);
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index f490c87..4a10427 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -32,6 +32,7 @@
     ],
     static_libs: [
         "junit",
+        "SettingsLibDeviceStateRotationLock",
         "SettingsLibDisplayDensityUtils",
     ],
     platform_apis: true,
@@ -55,6 +56,7 @@
     static_libs: [
         "androidx.test.rules",
         "mockito-target-minus-junit4",
+        "SettingsLibDeviceStateRotationLock",
         "SettingsLibDisplayDensityUtils",
         "platform-test-annotations",
         "truth-prebuilt",
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/DeviceSpecificSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/DeviceSpecificSettings.java
index e425790..3cb1439 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/DeviceSpecificSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/DeviceSpecificSettings.java
@@ -32,5 +32,6 @@
      */
     public static final String[] DEVICE_SPECIFIC_SETTINGS_TO_BACKUP = {
             Settings.Secure.DISPLAY_DENSITY_FORCED,
+            Settings.Secure.DEVICE_STATE_ROTATION_LOCK
     };
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index dc166b4..162bb2c 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -78,6 +78,7 @@
         Settings.Global.POWER_BUTTON_LONG_PRESS,
         Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
         Settings.Global.ADVANCED_BATTERY_USAGE_AMOUNT,
+        Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED,
         Settings.Global.POWER_BUTTON_LONG_PRESS_DURATION_MS,
         Settings.Global.USER_PREFERRED_REFRESH_RATE,
         Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT,
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 5eaf553..ce33160 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -37,6 +37,7 @@
         Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
         Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
         Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
+        Settings.Secure.ADAPTIVE_CHARGING_ENABLED,
         Settings.Secure.ADAPTIVE_SLEEP,
         Settings.Secure.CAMERA_AUTOROTATE,
         Settings.Secure.AUTOFILL_SERVICE,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index acb33c3..e82bf04 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -155,6 +155,7 @@
         VALIDATORS.put(Global.DEVICE_CONFIG_SYNC_DISABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Global.AUTOMATIC_POWER_SAVE_MODE, ANY_INTEGER_VALIDATOR);
         VALIDATORS.put(Global.ADVANCED_BATTERY_USAGE_AMOUNT, PERCENTAGE_INTEGER_VALIDATOR);
+        VALIDATORS.put(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Global.POWER_BUTTON_LONG_PRESS_DURATION_MS, NONE_NEGATIVE_LONG_VALIDATOR);
 
         VALIDATORS.put(Global.Wearable.HAS_PAY_TOKENS, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 9ee7b65..5d77378 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -59,6 +59,7 @@
         VALIDATORS.put(Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(
                 Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.ADAPTIVE_CHARGING_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ADAPTIVE_SLEEP, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.CAMERA_AUTOROTATE, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.AUTOFILL_SERVICE, NULLABLE_COMPONENT_NAME_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 440bb67..808ea9e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -41,6 +41,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.LocalePicker;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -200,6 +201,9 @@
             } else if (Settings.Global.POWER_BUTTON_LONG_PRESS.equals(name)) {
                 setLongPressPowerBehavior(cr, value);
                 return;
+            } else if (Settings.System.ACCELEROMETER_ROTATION.equals(name)
+                    && shouldSkipAutoRotateRestore()) {
+                return;
             }
 
             // Default case: write the restored value to settings
@@ -236,6 +240,12 @@
         }
     }
 
+    private boolean shouldSkipAutoRotateRestore() {
+        // When device state based auto rotation settings are available, let's skip the restoring
+        // of the standard auto rotation settings to avoid conflicting setting values.
+        return DeviceStateRotationLockSettingsManager.isDeviceStateRotationLockEnabled(mContext);
+    }
+
     public String onBackupValue(String name, String value) {
         // Special processing for backing up ringtones & notification sounds
         if (Settings.System.RINGTONE.equals(name)
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index cce5154..b1ce3bf 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -110,7 +110,6 @@
             newHashSet(
                     Settings.Global.ACTIVITY_MANAGER_CONSTANTS,
                     Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED,
-                    Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED,
                     Settings.Global.ADB_ALLOWED_CONNECTION_TIME,
                     Settings.Global.ADB_ENABLED,
                     Settings.Global.ADB_WIFI_ENABLED,
@@ -422,6 +421,7 @@
                     Settings.Global.RADIO_NFC,
                     Settings.Global.RADIO_WIFI,
                     Settings.Global.RADIO_WIMAX,
+                    Settings.Global.REMOVE_GUEST_ON_EXIT,
                     Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS,
                     Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT,
                     Settings.Global.RESTRICTED_NETWORKING_MODE,
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java
index 4f7b494..ee76dbf 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java
@@ -73,6 +73,8 @@
         when(mContext.getSystemService(eq(Context.TELEPHONY_SERVICE))).thenReturn(
                 mTelephonyManager);
         when(mContext.getResources()).thenReturn(mResources);
+        when(mContext.getApplicationContext()).thenReturn(mContext);
+        when(mContext.getContentResolver()).thenReturn(getContentResolver());
 
         mSettingsHelper = spy(new SettingsHelper(mContext));
     }
@@ -305,6 +307,63 @@
                         new String[] { "he-IL", "id-ID", "yi" }));  // supported
     }
 
+    @Test
+    public void restoreValue_autoRotation_deviceStateAutoRotationDisabled_restoresValue() {
+        when(mResources.getStringArray(R.array.config_perDeviceStateRotationLockDefaults))
+                .thenReturn(new String[]{});
+        int previousValue = 0;
+        int newValue = 1;
+        setAutoRotationSettingValue(previousValue);
+
+        restoreAutoRotationSetting(newValue);
+
+        assertThat(getAutoRotationSettingValue()).isEqualTo(newValue);
+    }
+
+    @Test
+    public void restoreValue_autoRotation_deviceStateAutoRotationEnabled_doesNotRestoreValue() {
+        when(mResources.getStringArray(R.array.config_perDeviceStateRotationLockDefaults))
+                .thenReturn(new String[]{"0:1", "1:1"});
+        int previousValue = 0;
+        int newValue = 1;
+        setAutoRotationSettingValue(previousValue);
+
+        restoreAutoRotationSetting(newValue);
+
+        assertThat(getAutoRotationSettingValue()).isEqualTo(previousValue);
+    }
+
+    private int getAutoRotationSettingValue() {
+        return Settings.System.getInt(
+                getContentResolver(),
+                Settings.System.ACCELEROMETER_ROTATION,
+                /* default= */ -1);
+    }
+
+    private void setAutoRotationSettingValue(int value) {
+        Settings.System.putInt(
+                getContentResolver(),
+                Settings.System.ACCELEROMETER_ROTATION,
+                value
+        );
+    }
+
+    private void restoreAutoRotationSetting(int newValue) {
+        mSettingsHelper.restoreValue(
+                mContext,
+                getContentResolver(),
+                new ContentValues(),
+                /* destination= */ Settings.System.CONTENT_URI,
+                /* name= */ Settings.System.ACCELEROMETER_ROTATION,
+                /* value= */ String.valueOf(newValue),
+                /* restoredFromSdkInt= */ 0);
+    }
+
+    private ContentResolver getContentResolver() {
+        return InstrumentationRegistry.getInstrumentation().getTargetContext()
+                .getContentResolver();
+    }
+
     private void clearLongPressPowerValues() {
         ContentResolver cr = InstrumentationRegistry.getInstrumentation().getTargetContext()
                 .getContentResolver();
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index f05c1e2..fa87de2 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -93,6 +93,7 @@
         "SystemUISharedLib",
         "SystemUI-statsd",
         "SettingsLib",
+        "androidx.core_core-ktx",
         "androidx.viewpager2_viewpager2",
         "androidx.legacy_legacy-support-v4",
         "androidx.recyclerview_recyclerview",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 6f22b49..1c13b16 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -713,7 +713,7 @@
 
         <service
             android:name=".dreams.DreamOverlayService"
-            android:enabled="@bool/config_dreamOverlayServiceEnabled"
+            android:enabled="false"
             android:exported="true" />
 
         <activity android:name=".keyguard.WorkLockActivity"
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index 3bd6d51..f9a9ef6 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -52,6 +52,17 @@
       ]
     },
     {
+      "name": "SystemUIGoogleScreenshotTests",
+      "options": [
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
+    },
+    {
       // Permission indicators
       "name": "CtsPermission4TestCases",
       "options": [
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index bb6eb78..fbe3356 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -59,31 +59,31 @@
     companion object {
         /** The timings when animating a View into an app. */
         @JvmField
-        val TIMINGS = LaunchAnimator.Timings(
-            totalDuration = 500L,
-            contentBeforeFadeOutDelay = 0L,
-            contentBeforeFadeOutDuration = 150L,
-            contentAfterFadeInDelay = 150L,
-            contentAfterFadeInDuration = 183L
-        )
+        val TIMINGS =
+            LaunchAnimator.Timings(
+                totalDuration = 500L,
+                contentBeforeFadeOutDelay = 0L,
+                contentBeforeFadeOutDuration = 150L,
+                contentAfterFadeInDelay = 150L,
+                contentAfterFadeInDuration = 183L
+            )
 
         /**
          * The timings when animating a Dialog into an app. We need to wait at least 200ms before
          * showing the app (which is under the dialog window) so that the dialog window dim is fully
          * faded out, to avoid flicker.
          */
-        val DIALOG_TIMINGS = TIMINGS.copy(
-            contentBeforeFadeOutDuration = 200L,
-            contentAfterFadeInDelay = 200L
-        )
+        val DIALOG_TIMINGS =
+            TIMINGS.copy(contentBeforeFadeOutDuration = 200L, contentAfterFadeInDelay = 200L)
 
         /** The interpolators when animating a View or a dialog into an app. */
-        val INTERPOLATORS = LaunchAnimator.Interpolators(
-            positionInterpolator = Interpolators.EMPHASIZED,
-            positionXInterpolator = createPositionXInterpolator(),
-            contentBeforeFadeOutInterpolator = Interpolators.LINEAR_OUT_SLOW_IN,
-            contentAfterFadeInInterpolator = PathInterpolator(0f, 0f, 0.6f, 1f)
-        )
+        val INTERPOLATORS =
+            LaunchAnimator.Interpolators(
+                positionInterpolator = Interpolators.EMPHASIZED,
+                positionXInterpolator = createPositionXInterpolator(),
+                contentBeforeFadeOutInterpolator = Interpolators.LINEAR_OUT_SLOW_IN,
+                contentAfterFadeInInterpolator = PathInterpolator(0f, 0f, 0.6f, 1f)
+            )
 
         /** Durations & interpolators for the navigation bar fading in & out. */
         private const val ANIMATION_DURATION_NAV_FADE_IN = 266L
@@ -98,11 +98,12 @@
         private const val LAUNCH_TIMEOUT = 1000L
 
         private fun createPositionXInterpolator(): Interpolator {
-            val path = Path().apply {
-                moveTo(0f, 0f)
-                cubicTo(0.1217f, 0.0462f, 0.15f, 0.4686f, 0.1667f, 0.66f)
-                cubicTo(0.1834f, 0.8878f, 0.1667f, 1f, 1f, 1f)
-            }
+            val path =
+                Path().apply {
+                    moveTo(0f, 0f)
+                    cubicTo(0.1217f, 0.0462f, 0.15f, 0.4686f, 0.1667f, 0.66f)
+                    cubicTo(0.1834f, 0.8878f, 0.1667f, 1f, 1f, 1f)
+                }
             return PathInterpolator(path)
         }
     }
@@ -150,29 +151,37 @@
             return
         }
 
-        val callback = this.callback ?: throw IllegalStateException(
-            "ActivityLaunchAnimator.callback must be set before using this animator")
+        val callback =
+            this.callback
+                ?: throw IllegalStateException(
+                    "ActivityLaunchAnimator.callback must be set before using this animator"
+                )
         val runner = Runner(controller)
         val hideKeyguardWithAnimation = callback.isOnKeyguard() && !showOverLockscreen
 
         // Pass the RemoteAnimationAdapter to the intent starter only if we are not hiding the
         // keyguard with the animation
-        val animationAdapter = if (!hideKeyguardWithAnimation) {
-            RemoteAnimationAdapter(
-                runner,
-                TIMINGS.totalDuration,
-                TIMINGS.totalDuration - 150 /* statusBarTransitionDelay */
-            )
-        } else {
-            null
-        }
+        val animationAdapter =
+            if (!hideKeyguardWithAnimation) {
+                RemoteAnimationAdapter(
+                    runner,
+                    TIMINGS.totalDuration,
+                    TIMINGS.totalDuration - 150 /* statusBarTransitionDelay */
+                )
+            } else {
+                null
+            }
 
         // Register the remote animation for the given package to also animate trampoline
         // activity launches.
         if (packageName != null && animationAdapter != null) {
             try {
-                ActivityTaskManager.getService().registerRemoteAnimationForNextActivityStart(
-                    packageName, animationAdapter, null /* launchCookie */)
+                ActivityTaskManager.getService()
+                    .registerRemoteAnimationForNextActivityStart(
+                        packageName,
+                        animationAdapter,
+                        null /* launchCookie */
+                    )
             } catch (e: RemoteException) {
                 Log.w(TAG, "Unable to register the remote animation", e)
             }
@@ -184,12 +193,15 @@
         // keyguard.
         val willAnimate =
             launchResult == ActivityManager.START_TASK_TO_FRONT ||
-                    launchResult == ActivityManager.START_SUCCESS ||
-                    (launchResult == ActivityManager.START_DELIVERED_TO_TOP &&
-                            hideKeyguardWithAnimation)
+                launchResult == ActivityManager.START_SUCCESS ||
+                (launchResult == ActivityManager.START_DELIVERED_TO_TOP &&
+                    hideKeyguardWithAnimation)
 
-        Log.i(TAG, "launchResult=$launchResult willAnimate=$willAnimate " +
-                "hideKeyguardWithAnimation=$hideKeyguardWithAnimation")
+        Log.i(
+            TAG,
+            "launchResult=$launchResult willAnimate=$willAnimate " +
+                "hideKeyguardWithAnimation=$hideKeyguardWithAnimation"
+        )
         controller.callOnIntentStartedOnMainThread(willAnimate)
 
         // If we expect an animation, post a timeout to cancel it in case the remote animation is
@@ -206,9 +218,7 @@
 
     private fun Controller.callOnIntentStartedOnMainThread(willAnimate: Boolean) {
         if (Looper.myLooper() != Looper.getMainLooper()) {
-            this.launchContainer.context.mainExecutor.execute {
-                this.onIntentStarted(willAnimate)
-            }
+            this.launchContainer.context.mainExecutor.execute { this.onIntentStarted(willAnimate) }
         } else {
             this.onIntentStarted(willAnimate)
         }
@@ -246,8 +256,7 @@
     }
 
     /** Create a new animation [Runner] controlled by [controller]. */
-    @VisibleForTesting
-    fun createRunner(controller: Controller): Runner = Runner(controller)
+    @VisibleForTesting fun createRunner(controller: Controller): Runner = Runner(controller)
 
     interface PendingIntentStarter {
         /**
@@ -271,19 +280,16 @@
 
     interface Listener {
         /** Called when an activity launch animation started. */
-        @JvmDefault
-        fun onLaunchAnimationStart() {}
+        @JvmDefault fun onLaunchAnimationStart() {}
 
         /**
          * Called when an activity launch animation is finished. This will be called if and only if
          * [onLaunchAnimationStart] was called earlier.
          */
-        @JvmDefault
-        fun onLaunchAnimationEnd() {}
+        @JvmDefault fun onLaunchAnimationEnd() {}
 
         /** Called when an activity launch animation made progress. */
-        @JvmDefault
-        fun onLaunchAnimationProgress(linearProgress: Float) {}
+        @JvmDefault fun onLaunchAnimationProgress(linearProgress: Float) {}
     }
 
     /**
@@ -327,6 +333,17 @@
             get() = false
 
         /**
+         * Whether the expandable controller by this [Controller] is below the launching window that
+         * is going to be animated.
+         *
+         * This should be `false` when launching an app from the shade or status bar, given that
+         * they are drawn above all apps. This is usually `true` when using this launcher in a
+         * normal app or a launcher, that are drawn below the animating activity/window.
+         */
+        val isBelowAnimatingWindow: Boolean
+            get() = false
+
+        /**
          * The intent was started. If [willAnimate] is false, nothing else will happen and the
          * animation will not be started.
          */
@@ -394,9 +411,7 @@
                 return
             }
 
-            context.mainExecutor.execute {
-                startAnimation(apps, nonApps, iCallback)
-            }
+            context.mainExecutor.execute { startAnimation(apps, nonApps, iCallback) }
         }
 
         private fun startAnimation(
@@ -408,9 +423,7 @@
                 Log.d(TAG, "Remote animation started")
             }
 
-            val window = apps?.firstOrNull {
-                it.mode == RemoteAnimationTarget.MODE_OPENING
-            }
+            val window = apps?.firstOrNull { it.mode == RemoteAnimationTarget.MODE_OPENING }
 
             if (window == null) {
                 Log.i(TAG, "Aborting the animation as no window is opening")
@@ -420,80 +433,96 @@
                 return
             }
 
-            val navigationBar = nonApps?.firstOrNull {
-                it.windowType == WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
-            }
+            val navigationBar =
+                nonApps?.firstOrNull {
+                    it.windowType == WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
+                }
 
             val windowBounds = window.screenSpaceBounds
-            val endState = LaunchAnimator.State(
-                top = windowBounds.top,
-                bottom = windowBounds.bottom,
-                left = windowBounds.left,
-                right = windowBounds.right
-            )
+            val endState =
+                LaunchAnimator.State(
+                    top = windowBounds.top,
+                    bottom = windowBounds.bottom,
+                    left = windowBounds.left,
+                    right = windowBounds.right
+                )
             val callback = this@ActivityLaunchAnimator.callback!!
-            val windowBackgroundColor = window.taskInfo?.let { callback.getBackgroundColor(it) }
-                    ?: window.backgroundColor
+            val windowBackgroundColor =
+                window.taskInfo?.let { callback.getBackgroundColor(it) } ?: window.backgroundColor
 
             // Make sure we use the modified timings when animating a dialog into an app.
-            val launchAnimator = if (controller.isDialogLaunch) {
-                dialogToAppAnimator
-            } else {
-                launchAnimator
-            }
+            val launchAnimator =
+                if (controller.isDialogLaunch) {
+                    dialogToAppAnimator
+                } else {
+                    launchAnimator
+                }
 
             // TODO(b/184121838): We should somehow get the top and bottom radius of the window
             // instead of recomputing isExpandingFullyAbove here.
             val isExpandingFullyAbove =
                 launchAnimator.isExpandingFullyAbove(controller.launchContainer, endState)
-            val endRadius = if (isExpandingFullyAbove) {
-                // Most of the time, expanding fully above the root view means expanding in full
-                // screen.
-                ScreenDecorationsUtils.getWindowCornerRadius(context)
-            } else {
-                // This usually means we are in split screen mode, so 2 out of 4 corners will have
-                // a radius of 0.
-                0f
-            }
+            val endRadius =
+                if (isExpandingFullyAbove) {
+                    // Most of the time, expanding fully above the root view means expanding in full
+                    // screen.
+                    ScreenDecorationsUtils.getWindowCornerRadius(context)
+                } else {
+                    // This usually means we are in split screen mode, so 2 out of 4 corners will
+                    // have
+                    // a radius of 0.
+                    0f
+                }
             endState.topCornerRadius = endRadius
             endState.bottomCornerRadius = endRadius
 
             // We animate the opening window and delegate the view expansion to [this.controller].
             val delegate = this.controller
-            val controller = object : LaunchAnimator.Controller by delegate {
-                override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
-                    listeners.forEach { it.onLaunchAnimationStart() }
-                    delegate.onLaunchAnimationStart(isExpandingFullyAbove)
-                }
-
-                override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
-                    listeners.forEach { it.onLaunchAnimationEnd() }
-                    iCallback?.invoke()
-                    delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
-                }
-
-                override fun onLaunchAnimationProgress(
-                    state: LaunchAnimator.State,
-                    progress: Float,
-                    linearProgress: Float
-                ) {
-                    // Apply the state to the window only if it is visible, i.e. when the expanding
-                    // view is *not* visible.
-                    if (!state.visible) {
-                        applyStateToWindow(window, state)
+            val controller =
+                object : Controller by delegate {
+                    override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
+                        listeners.forEach { it.onLaunchAnimationStart() }
+                        delegate.onLaunchAnimationStart(isExpandingFullyAbove)
                     }
-                    navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) }
 
-                    listeners.forEach { it.onLaunchAnimationProgress(linearProgress) }
-                    delegate.onLaunchAnimationProgress(state, progress, linearProgress)
+                    override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
+                        listeners.forEach { it.onLaunchAnimationEnd() }
+                        iCallback?.invoke()
+                        delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
+                    }
+
+                    override fun onLaunchAnimationProgress(
+                        state: LaunchAnimator.State,
+                        progress: Float,
+                        linearProgress: Float
+                    ) {
+                        // Apply the state to the window only if it is visible, i.e. when the
+                        // expanding view is *not* visible.
+                        if (!state.visible) {
+                            applyStateToWindow(window, state, linearProgress)
+                        }
+                        navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) }
+
+                        listeners.forEach { it.onLaunchAnimationProgress(linearProgress) }
+                        delegate.onLaunchAnimationProgress(state, progress, linearProgress)
+                    }
                 }
-            }
 
-            animation = launchAnimator.startAnimation(
-                controller, endState, windowBackgroundColor, drawHole = true)
+            animation =
+                launchAnimator.startAnimation(
+                    controller,
+                    endState,
+                    windowBackgroundColor,
+                    fadeOutWindowBackgroundLayer = !controller.isBelowAnimatingWindow,
+                    drawHole = !controller.isBelowAnimatingWindow,
+                )
         }
 
-        private fun applyStateToWindow(window: RemoteAnimationTarget, state: LaunchAnimator.State) {
+        private fun applyStateToWindow(
+            window: RemoteAnimationTarget,
+            state: LaunchAnimator.State,
+            linearProgress: Float,
+        ) {
             if (transactionApplierView.viewRootImpl == null) {
                 // If the view root we synchronize with was detached, don't apply any transaction
                 // (as [SyncRtSurfaceTransactionApplier.scheduleApply] would otherwise throw).
@@ -535,19 +564,38 @@
                 windowCropF.bottom.roundToInt()
             )
 
+            // The alpha of the opening window. If it opens above the expandable, then it should
+            // fade in progressively. Otherwise, it should be fully opaque and will be progressively
+            // revealed as the window background color layer above the window fades out.
+            val alpha =
+                if (controller.isBelowAnimatingWindow) {
+                    val windowProgress =
+                        LaunchAnimator.getProgress(
+                            TIMINGS,
+                            linearProgress,
+                            TIMINGS.contentAfterFadeInDelay,
+                            TIMINGS.contentAfterFadeInDuration
+                        )
+
+                    INTERPOLATORS.contentAfterFadeInInterpolator.getInterpolation(windowProgress)
+                } else {
+                    1f
+                }
+
             // The scale will also be applied to the corner radius, so we divide by the scale to
             // keep the original radius. We use the max of (topCornerRadius, bottomCornerRadius) to
             // make sure that the window does not draw itself behind the expanding view. This is
             // especially important for lock screen animations, where the window is not clipped by
             // the shade.
             val cornerRadius = maxOf(state.topCornerRadius, state.bottomCornerRadius) / scale
-            val params = SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(window.leash)
-                .withAlpha(1f)
-                .withMatrix(matrix)
-                .withWindowCrop(windowCrop)
-                .withCornerRadius(cornerRadius)
-                .withVisibility(true)
-                .build()
+            val params =
+                SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(window.leash)
+                    .withAlpha(alpha)
+                    .withMatrix(matrix)
+                    .withWindowCrop(windowCrop)
+                    .withCornerRadius(cornerRadius)
+                    .withVisibility(true)
+                    .build()
 
             transactionApplier.scheduleApply(params)
         }
@@ -563,14 +611,21 @@
                 return
             }
 
-            val fadeInProgress = LaunchAnimator.getProgress(TIMINGS, linearProgress,
-                ANIMATION_DELAY_NAV_FADE_IN, ANIMATION_DURATION_NAV_FADE_OUT)
+            val fadeInProgress =
+                LaunchAnimator.getProgress(
+                    TIMINGS,
+                    linearProgress,
+                    ANIMATION_DELAY_NAV_FADE_IN,
+                    ANIMATION_DURATION_NAV_FADE_OUT
+                )
 
             val params = SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(navigationBar.leash)
             if (fadeInProgress > 0) {
                 matrix.reset()
                 matrix.setTranslate(
-                    0f, (state.top - navigationBar.sourceContainerBounds.top).toFloat())
+                    0f,
+                    (state.top - navigationBar.sourceContainerBounds.top).toFloat()
+                )
                 windowCrop.set(state.left, 0, state.right, state.height)
                 params
                     .withAlpha(NAV_FADE_IN_INTERPOLATOR.getInterpolation(fadeInProgress))
@@ -578,8 +633,13 @@
                     .withWindowCrop(windowCrop)
                     .withVisibility(true)
             } else {
-                val fadeOutProgress = LaunchAnimator.getProgress(TIMINGS, linearProgress, 0,
-                    ANIMATION_DURATION_NAV_FADE_OUT)
+                val fadeOutProgress =
+                    LaunchAnimator.getProgress(
+                        TIMINGS,
+                        linearProgress,
+                        0,
+                        ANIMATION_DURATION_NAV_FADE_OUT
+                    )
                 params.withAlpha(1f - NAV_FADE_OUT_INTERPOLATOR.getInterpolation(fadeOutProgress))
             }
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DelegateLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DelegateLaunchAnimatorController.kt
index 258ca6b..b879ba0 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DelegateLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DelegateLaunchAnimatorController.kt
@@ -23,4 +23,4 @@
  */
 open class DelegateLaunchAnimatorController(
     protected val delegate: ActivityLaunchAnimator.Controller
-) : ActivityLaunchAnimator.Controller by delegate
\ No newline at end of file
+) : ActivityLaunchAnimator.Controller by delegate
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
index 63276c9..cb16d7c 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
@@ -34,6 +34,9 @@
 import android.view.WindowManager
 import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
 import android.widget.FrameLayout
+import com.android.internal.jank.InteractionJankMonitor
+import com.android.internal.jank.InteractionJankMonitor.Configuration
+import com.android.internal.jank.InteractionJankMonitor.CujType
 import kotlin.math.roundToInt
 
 private const val TAG = "DialogLaunchAnimator"
@@ -48,8 +51,11 @@
  * @see showFromDialog
  * @see createActivityLaunchController
  */
-class DialogLaunchAnimator @JvmOverloads constructor(
+class DialogLaunchAnimator
+@JvmOverloads
+constructor(
     private val dreamManager: IDreamManager,
+    private val interactionJankMonitor: InteractionJankMonitor,
     private val launchAnimator: LaunchAnimator = LaunchAnimator(TIMINGS, INTERPOLATORS),
     private val isForTesting: Boolean = false
 ) {
@@ -58,9 +64,10 @@
 
         // We use the same interpolator for X and Y axis to make sure the dialog does not move out
         // of the screen bounds during the animation.
-        private val INTERPOLATORS = ActivityLaunchAnimator.INTERPOLATORS.copy(
-            positionXInterpolator = ActivityLaunchAnimator.INTERPOLATORS.positionInterpolator
-        )
+        private val INTERPOLATORS =
+            ActivityLaunchAnimator.INTERPOLATORS.copy(
+                positionXInterpolator = ActivityLaunchAnimator.INTERPOLATORS.positionInterpolator
+            )
 
         private val TAG_LAUNCH_ANIMATION_RUNNING = R.id.tag_launch_animation_running
     }
@@ -89,18 +96,22 @@
     fun showFromView(
         dialog: Dialog,
         view: View,
-        animateBackgroundBoundsChange: Boolean = false
+        cuj: DialogCuj? = null,
+        animateBackgroundBoundsChange: Boolean = false,
     ) {
         if (Looper.myLooper() != Looper.getMainLooper()) {
             throw IllegalStateException(
                 "showFromView must be called from the main thread and dialog must be created in " +
-                    "the main thread")
+                    "the main thread"
+            )
         }
 
         // If the view we are launching from belongs to another dialog, then this means the caller
         // intent is to launch a dialog from another dialog.
-        val animatedParent = openedDialogs
-            .firstOrNull { it.dialog.window.decorView.viewRootImpl == view.viewRootImpl }
+        val animatedParent =
+            openedDialogs.firstOrNull {
+                it.dialog.window.decorView.viewRootImpl == view.viewRootImpl
+            }
         val animateFrom = animatedParent?.dialogContentWithBackground ?: view
 
         // Make sure we don't run the launch animation from the same view twice at the same time.
@@ -112,16 +123,19 @@
 
         animateFrom.setTag(TAG_LAUNCH_ANIMATION_RUNNING, true)
 
-        val animatedDialog = AnimatedDialog(
+        val animatedDialog =
+            AnimatedDialog(
                 launchAnimator,
                 dreamManager,
+                interactionJankMonitor,
                 animateFrom,
                 onDialogDismissed = { openedDialogs.remove(it) },
                 dialog = dialog,
                 animateBackgroundBoundsChange,
                 animatedParent,
-                isForTesting
-        )
+                isForTesting,
+                cuj
+            )
 
         openedDialogs.add(animatedDialog)
         animatedDialog.start()
@@ -138,13 +152,13 @@
         animateFrom: Dialog,
         animateBackgroundBoundsChange: Boolean = false
     ) {
-        val view = openedDialogs
-            .firstOrNull { it.dialog == animateFrom }
-            ?.dialogContentWithBackground
-            ?: throw IllegalStateException(
-                "The animateFrom dialog was not animated using " +
-                    "DialogLaunchAnimator.showFrom(View|Dialog)")
-        showFromView(dialog, view, animateBackgroundBoundsChange)
+        val view =
+            openedDialogs.firstOrNull { it.dialog == animateFrom }?.dialogContentWithBackground
+                ?: throw IllegalStateException(
+                    "The animateFrom dialog was not animated using " +
+                        "DialogLaunchAnimator.showFrom(View|Dialog)"
+                )
+        showFromView(dialog, view, animateBackgroundBoundsChange = animateBackgroundBoundsChange)
     }
 
     /**
@@ -166,9 +180,11 @@
         view: View,
         cujType: Int? = null
     ): ActivityLaunchAnimator.Controller? {
-        val animatedDialog = openedDialogs
-            .firstOrNull { it.dialog.window.decorView.viewRootImpl == view.viewRootImpl }
-            ?: return null
+        val animatedDialog =
+            openedDialogs.firstOrNull {
+                it.dialog.window.decorView.viewRootImpl == view.viewRootImpl
+            }
+                ?: return null
 
         // At this point, we know that the intent of the caller is to dismiss the dialog to show
         // an app, so we disable the exit animation into the touch surface because we will never
@@ -231,7 +247,7 @@
             }
 
             private fun disableDialogDismiss() {
-                dialog.setDismissOverride { /* Do nothing */ }
+                dialog.setDismissOverride { /* Do nothing */}
             }
 
             private fun enableDialogDismiss() {
@@ -248,9 +264,9 @@
      * Ensure that all dialogs currently shown won't animate into their touch surface when
      * dismissed.
      *
-     * This is a temporary API meant to be called right before we both dismiss a dialog and start
-     * an activity, which currently does not look good if we animate the dialog into the touch
-     * surface at the same time as the activity starts.
+     * This is a temporary API meant to be called right before we both dismiss a dialog and start an
+     * activity, which currently does not look good if we animate the dialog into the touch surface
+     * at the same time as the activity starts.
      *
      * TODO(b/193634619): Remove this function and animate dialog into opening activity instead.
      */
@@ -270,16 +286,24 @@
     }
 }
 
+/**
+ * The CUJ interaction associated with opening the dialog.
+ *
+ * The optional tag indicates the specific dialog being opened.
+ */
+data class DialogCuj(@CujType val cujType: Int, val tag: String? = null)
+
 private class AnimatedDialog(
     private val launchAnimator: LaunchAnimator,
     private val dreamManager: IDreamManager,
+    private val interactionJankMonitor: InteractionJankMonitor,
 
     /** The view that triggered the dialog after being tapped. */
     var touchSurface: View,
 
     /**
-     * A callback that will be called with this [AnimatedDialog] after the dialog was
-     * dismissed and the exit animation is done.
+     * A callback that will be called with this [AnimatedDialog] after the dialog was dismissed and
+     * the exit animation is done.
      */
     private val onDialogDismissed: (AnimatedDialog) -> Unit,
 
@@ -295,14 +319,17 @@
     /**
      * Whether synchronization should be disabled, which can be useful if we are running in a test.
      */
-    private val forceDisableSynchronization: Boolean
+    private val forceDisableSynchronization: Boolean,
+
+    /** Interaction to which the dialog animation is associated. */
+    private val cuj: DialogCuj? = null
 ) {
     /**
      * The DecorView of this dialog window.
      *
      * Note that we access this DecorView lazily to avoid accessing it before the dialog is created,
      * which can sometimes cause crashes (e.g. with the Cast dialog).
-      */
+     */
     private val decorView by lazy { dialog.window!!.decorView as ViewGroup }
 
     /**
@@ -313,9 +340,7 @@
      */
     var dialogContentWithBackground: ViewGroup? = null
 
-    /**
-     * The background color of [dialog], taking into consideration its window background color.
-     */
+    /** The background color of [dialog], taking into consideration its window background color. */
     private var originalDialogBackgroundColor = Color.BLACK
 
     /**
@@ -333,11 +358,12 @@
     private var isOriginalDialogViewLaidOut = false
 
     /** A layout listener to animate the dialog height change. */
-    private val backgroundLayoutListener = if (animateBackgroundBoundsChange) {
-        AnimatedBoundsLayoutListener()
-    } else {
-        null
-    }
+    private val backgroundLayoutListener =
+        if (animateBackgroundBoundsChange) {
+            AnimatedBoundsLayoutListener()
+        } else {
+            null
+        }
 
     /*
      * A layout listener in case the dialog (window) size changes (for instance because of a
@@ -346,6 +372,14 @@
     private var decorViewLayoutListener: View.OnLayoutChangeListener? = null
 
     fun start() {
+        if (cuj != null) {
+            val config = Configuration.Builder.withView(cuj.cujType, touchSurface)
+            if (cuj.tag != null) {
+                config.setTag(cuj.tag)
+            }
+            interactionJankMonitor.begin(config)
+        }
+
         // Create the dialog so that its onCreate() method is called, which usually sets the dialog
         // content.
         dialog.create()
@@ -353,99 +387,117 @@
         val window = dialog.window!!
         val isWindowFullScreen =
             window.attributes.width == MATCH_PARENT && window.attributes.height == MATCH_PARENT
-        val dialogContentWithBackground = if (isWindowFullScreen) {
-            // If the dialog window is already fullscreen, then we look for the first ViewGroup that
-            // has a background (and is not the DecorView, which always has a background) and
-            // animate towards that ViewGroup given that this is probably what represents the actual
-            // dialog view.
-            var viewGroupWithBackground: ViewGroup? = null
-            for (i in 0 until decorView.childCount) {
-                viewGroupWithBackground = findFirstViewGroupWithBackground(decorView.getChildAt(i))
-                if (viewGroupWithBackground != null) {
-                    break
+        val dialogContentWithBackground =
+            if (isWindowFullScreen) {
+                // If the dialog window is already fullscreen, then we look for the first ViewGroup
+                // that has a background (and is not the DecorView, which always has a background)
+                // and animate towards that ViewGroup given that this is probably what represents
+                // the actual dialog view.
+                var viewGroupWithBackground: ViewGroup? = null
+                for (i in 0 until decorView.childCount) {
+                    viewGroupWithBackground =
+                        findFirstViewGroupWithBackground(decorView.getChildAt(i))
+                    if (viewGroupWithBackground != null) {
+                        break
+                    }
                 }
-            }
 
-            // Animate that view with the background. Throw if we didn't find one, because otherwise
-            // it's not clear what we should animate.
-            viewGroupWithBackground
-                ?: throw IllegalStateException("Unable to find ViewGroup with background")
-        } else {
-            // We will make the dialog window (and therefore its DecorView) fullscreen to make it
-            // possible to animate outside its bounds.
-            //
-            // Before that, we add a new View as a child of the DecorView with the same size and
-            // gravity as that DecorView, then we add all original children of the DecorView to that
-            // new View. Finally we remove the background of the DecorView and add it to the new
-            // View, then we make the DecorView fullscreen. This new View now acts as a fake (non
-            // fullscreen) window.
-            //
-            // On top of that, we also add a fullscreen transparent background between the DecorView
-            // and the view that we added so that we can dismiss the dialog when this view is
-            // clicked. This is necessary because DecorView overrides onTouchEvent and therefore we
-            // can't set the click listener directly on the (now fullscreen) DecorView.
-            val fullscreenTransparentBackground = FrameLayout(dialog.context)
-            decorView.addView(
-                fullscreenTransparentBackground,
-                0 /* index */,
-                FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
-            )
-
-            val dialogContentWithBackground = FrameLayout(dialog.context)
-            dialogContentWithBackground.background = decorView.background
-
-            // Make the window background transparent. Note that setting the window (or DecorView)
-            // background drawable to null leads to issues with background color (not being
-            // transparent) or with insets that are not refreshed. Therefore we need to set it to
-            // something not null, hence we are using android.R.color.transparent here.
-            window.setBackgroundDrawableResource(android.R.color.transparent)
-
-            // Close the dialog when clicking outside of it.
-            fullscreenTransparentBackground.setOnClickListener { dialog.dismiss() }
-            dialogContentWithBackground.isClickable = true
-
-            // Make sure the transparent and dialog backgrounds are not focusable by accessibility
-            // features.
-            fullscreenTransparentBackground.importantForAccessibility =
-                View.IMPORTANT_FOR_ACCESSIBILITY_NO
-            dialogContentWithBackground.importantForAccessibility =
-                View.IMPORTANT_FOR_ACCESSIBILITY_NO
-
-            fullscreenTransparentBackground.addView(
-                dialogContentWithBackground,
-                FrameLayout.LayoutParams(
-                    window.attributes.width,
-                    window.attributes.height,
-                    window.attributes.gravity
+                // Animate that view with the background. Throw if we didn't find one, because
+                // otherwise
+                // it's not clear what we should animate.
+                viewGroupWithBackground
+                    ?: throw IllegalStateException("Unable to find ViewGroup with background")
+            } else {
+                // We will make the dialog window (and therefore its DecorView) fullscreen to make
+                // it possible to animate outside its bounds.
+                //
+                // Before that, we add a new View as a child of the DecorView with the same size and
+                // gravity as that DecorView, then we add all original children of the DecorView to
+                // that new View. Finally we remove the background of the DecorView and add it to
+                // the new View, then we make the DecorView fullscreen. This new View now acts as a
+                // fake (non fullscreen) window.
+                //
+                // On top of that, we also add a fullscreen transparent background between the
+                // DecorView and the view that we added so that we can dismiss the dialog when this
+                // view is clicked. This is necessary because DecorView overrides onTouchEvent and
+                // therefore we can't set the click listener directly on the (now fullscreen)
+                // DecorView.
+                val fullscreenTransparentBackground = FrameLayout(dialog.context)
+                decorView.addView(
+                    fullscreenTransparentBackground,
+                    0 /* index */,
+                    FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
                 )
-            )
 
-            // Move all original children of the DecorView to the new View we just added.
-            for (i in 1 until decorView.childCount) {
-                val view = decorView.getChildAt(1)
-                decorView.removeViewAt(1)
-                dialogContentWithBackground.addView(view)
-            }
+                val dialogContentWithBackground = FrameLayout(dialog.context)
+                dialogContentWithBackground.background = decorView.background
 
-            // Make the window fullscreen and add a layout listener to ensure it stays fullscreen.
-            window.setLayout(MATCH_PARENT, MATCH_PARENT)
-            decorViewLayoutListener = View.OnLayoutChangeListener {
-                v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
-                if (window.attributes.width != MATCH_PARENT ||
-                    window.attributes.height != MATCH_PARENT) {
-                    // The dialog size changed, copy its size to dialogContentWithBackground and
-                    // make the dialog window full screen again.
-                    val layoutParams = dialogContentWithBackground.layoutParams
-                    layoutParams.width = window.attributes.width
-                    layoutParams.height = window.attributes.height
-                    dialogContentWithBackground.layoutParams = layoutParams
-                    window.setLayout(MATCH_PARENT, MATCH_PARENT)
+                // Make the window background transparent. Note that setting the window (or
+                // DecorView) background drawable to null leads to issues with background color (not
+                // being transparent) or with insets that are not refreshed. Therefore we need to
+                // set it to something not null, hence we are using android.R.color.transparent
+                // here.
+                window.setBackgroundDrawableResource(android.R.color.transparent)
+
+                // Close the dialog when clicking outside of it.
+                fullscreenTransparentBackground.setOnClickListener { dialog.dismiss() }
+                dialogContentWithBackground.isClickable = true
+
+                // Make sure the transparent and dialog backgrounds are not focusable by
+                // accessibility
+                // features.
+                fullscreenTransparentBackground.importantForAccessibility =
+                    View.IMPORTANT_FOR_ACCESSIBILITY_NO
+                dialogContentWithBackground.importantForAccessibility =
+                    View.IMPORTANT_FOR_ACCESSIBILITY_NO
+
+                fullscreenTransparentBackground.addView(
+                    dialogContentWithBackground,
+                    FrameLayout.LayoutParams(
+                        window.attributes.width,
+                        window.attributes.height,
+                        window.attributes.gravity
+                    )
+                )
+
+                // Move all original children of the DecorView to the new View we just added.
+                for (i in 1 until decorView.childCount) {
+                    val view = decorView.getChildAt(1)
+                    decorView.removeViewAt(1)
+                    dialogContentWithBackground.addView(view)
                 }
-            }
-            decorView.addOnLayoutChangeListener(decorViewLayoutListener)
 
-            dialogContentWithBackground
-        }
+                // Make the window fullscreen and add a layout listener to ensure it stays
+                // fullscreen.
+                window.setLayout(MATCH_PARENT, MATCH_PARENT)
+                decorViewLayoutListener =
+                    View.OnLayoutChangeListener {
+                        v,
+                        left,
+                        top,
+                        right,
+                        bottom,
+                        oldLeft,
+                        oldTop,
+                        oldRight,
+                        oldBottom ->
+                        if (
+                            window.attributes.width != MATCH_PARENT ||
+                                window.attributes.height != MATCH_PARENT
+                        ) {
+                            // The dialog size changed, copy its size to dialogContentWithBackground
+                            // and make the dialog window full screen again.
+                            val layoutParams = dialogContentWithBackground.layoutParams
+                            layoutParams.width = window.attributes.width
+                            layoutParams.height = window.attributes.height
+                            dialogContentWithBackground.layoutParams = layoutParams
+                            window.setLayout(MATCH_PARENT, MATCH_PARENT)
+                        }
+                    }
+                decorView.addOnLayoutChangeListener(decorViewLayoutListener)
+
+                dialogContentWithBackground
+            }
         this.dialogContentWithBackground = dialogContentWithBackground
         dialogContentWithBackground.setTag(R.id.tag_dialog_background, true)
 
@@ -453,7 +505,8 @@
         originalDialogBackgroundColor =
             GhostedViewLaunchAnimatorController.findGradientDrawable(background)
                 ?.color
-                ?.defaultColor ?: Color.BLACK
+                ?.defaultColor
+                ?: Color.BLACK
 
         // Make the background view invisible until we start the animation. We use the transition
         // visibility like GhostView does so that we don't mess up with the accessibility tree (see
@@ -479,24 +532,26 @@
         }
 
         // Start the animation once the background view is properly laid out.
-        dialogContentWithBackground.addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
-            override fun onLayoutChange(
-                v: View,
-                left: Int,
-                top: Int,
-                right: Int,
-                bottom: Int,
-                oldLeft: Int,
-                oldTop: Int,
-                oldRight: Int,
-                oldBottom: Int
-            ) {
-                dialogContentWithBackground.removeOnLayoutChangeListener(this)
+        dialogContentWithBackground.addOnLayoutChangeListener(
+            object : View.OnLayoutChangeListener {
+                override fun onLayoutChange(
+                    v: View,
+                    left: Int,
+                    top: Int,
+                    right: Int,
+                    bottom: Int,
+                    oldLeft: Int,
+                    oldTop: Int,
+                    oldRight: Int,
+                    oldBottom: Int
+                ) {
+                    dialogContentWithBackground.removeOnLayoutChangeListener(this)
 
-                isOriginalDialogViewLaidOut = true
-                maybeStartLaunchAnimation()
+                    isOriginalDialogViewLaidOut = true
+                    maybeStartLaunchAnimation()
+                }
             }
-        })
+        )
 
         // Disable the dim. We will enable it once we start the animation.
         window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
@@ -522,10 +577,12 @@
         // Create a ghost of the touch surface (which will make the touch surface invisible) and add
         // it to the host dialog. We trigger a one off synchronization to make sure that this is
         // done in sync between the two different windows.
-        synchronizeNextDraw(then = {
-            isTouchSurfaceGhostDrawn = true
-            maybeStartLaunchAnimation()
-        })
+        synchronizeNextDraw(
+            then = {
+                isTouchSurfaceGhostDrawn = true
+                maybeStartLaunchAnimation()
+            }
+        )
         GhostView.addGhost(touchSurface, decorView)
 
         // The ghost of the touch surface was just created, so the touch surface is currently
@@ -587,14 +644,13 @@
             onLaunchAnimationEnd = {
                 touchSurface.setTag(R.id.tag_launch_animation_running, null)
 
-                // We hide the touch surface when the dialog is showing. We will make this
-                // view visible again when dismissing the dialog.
+                // We hide the touch surface when the dialog is showing. We will make this view
+                // visible again when dismissing the dialog.
                 touchSurface.visibility = View.INVISIBLE
 
                 isLaunching = false
 
-                // dismiss was called during the animation, dismiss again now to actually
-                // dismiss.
+                // dismiss was called during the animation, dismiss again now to actually dismiss.
                 if (dismissRequested) {
                     dialog.dismiss()
                 }
@@ -603,9 +659,11 @@
                 // at the end of the launch animation, because the lauch animation already correctly
                 // handles bounds changes.
                 if (backgroundLayoutListener != null) {
-                    dialogContentWithBackground!!
-                        .addOnLayoutChangeListener(backgroundLayoutListener)
+                    dialogContentWithBackground!!.addOnLayoutChangeListener(
+                        backgroundLayoutListener
+                    )
                 }
+                cuj?.run { interactionJankMonitor.end(cujType) }
             }
         )
     }
@@ -681,16 +739,19 @@
                 dialogContentWithBackground.visibility = View.INVISIBLE
 
                 if (backgroundLayoutListener != null) {
-                    dialogContentWithBackground
-                        .removeOnLayoutChangeListener(backgroundLayoutListener)
+                    dialogContentWithBackground.removeOnLayoutChangeListener(
+                        backgroundLayoutListener
+                    )
                 }
 
                 // Make sure that the removal of the ghost and making the touch surface visible is
                 // done at the same time.
-                synchronizeNextDraw(then = {
-                    onAnimationFinished(true /* instantDismiss */)
-                    onDialogDismissed(this@AnimatedDialog)
-                })
+                synchronizeNextDraw(
+                    then = {
+                        onAnimationFinished(true /* instantDismiss */)
+                        onDialogDismissed(this@AnimatedDialog)
+                    }
+                )
             }
         )
     }
@@ -710,56 +771,57 @@
         endViewController.launchContainer = decorView
 
         val endState = endViewController.createAnimatorState()
-        val controller = object : LaunchAnimator.Controller {
-            override var launchContainer: ViewGroup
-                get() = startViewController.launchContainer
-                set(value) {
-                    startViewController.launchContainer = value
-                    endViewController.launchContainer = value
+        val controller =
+            object : LaunchAnimator.Controller {
+                override var launchContainer: ViewGroup
+                    get() = startViewController.launchContainer
+                    set(value) {
+                        startViewController.launchContainer = value
+                        endViewController.launchContainer = value
+                    }
+
+                override fun createAnimatorState(): LaunchAnimator.State {
+                    return startViewController.createAnimatorState()
                 }
 
-            override fun createAnimatorState(): LaunchAnimator.State {
-                return startViewController.createAnimatorState()
+                override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
+                    // During launch, onLaunchAnimationStart will be used to remove the temporary
+                    // touch surface ghost so it is important to call this before calling
+                    // onLaunchAnimationStart on the controller (which will create its own ghost).
+                    onLaunchAnimationStart()
+
+                    startViewController.onLaunchAnimationStart(isExpandingFullyAbove)
+                    endViewController.onLaunchAnimationStart(isExpandingFullyAbove)
+                }
+
+                override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
+                    startViewController.onLaunchAnimationEnd(isExpandingFullyAbove)
+                    endViewController.onLaunchAnimationEnd(isExpandingFullyAbove)
+
+                    onLaunchAnimationEnd()
+                }
+
+                override fun onLaunchAnimationProgress(
+                    state: LaunchAnimator.State,
+                    progress: Float,
+                    linearProgress: Float
+                ) {
+                    startViewController.onLaunchAnimationProgress(state, progress, linearProgress)
+
+                    // The end view is visible only iff the starting view is not visible.
+                    state.visible = !state.visible
+                    endViewController.onLaunchAnimationProgress(state, progress, linearProgress)
+
+                    // If the dialog content is complex, its dimension might change during the
+                    // launch animation. The animation end position might also change during the
+                    // exit animation, for instance when locking the phone when the dialog is open.
+                    // Therefore we update the end state to the new position/size. Usually the
+                    // dialog dimension or position will change in the early frames, so changing the
+                    // end state shouldn't really be noticeable.
+                    endViewController.fillGhostedViewState(endState)
+                }
             }
 
-            override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
-                // During launch, onLaunchAnimationStart will be used to remove the temporary touch
-                // surface ghost so it is important to call this before calling
-                // onLaunchAnimationStart on the controller (which will create its own ghost).
-                onLaunchAnimationStart()
-
-                startViewController.onLaunchAnimationStart(isExpandingFullyAbove)
-                endViewController.onLaunchAnimationStart(isExpandingFullyAbove)
-            }
-
-            override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
-                startViewController.onLaunchAnimationEnd(isExpandingFullyAbove)
-                endViewController.onLaunchAnimationEnd(isExpandingFullyAbove)
-
-                onLaunchAnimationEnd()
-            }
-
-            override fun onLaunchAnimationProgress(
-                state: LaunchAnimator.State,
-                progress: Float,
-                linearProgress: Float
-            ) {
-                startViewController.onLaunchAnimationProgress(state, progress, linearProgress)
-
-                // The end view is visible only iff the starting view is not visible.
-                state.visible = !state.visible
-                endViewController.onLaunchAnimationProgress(state, progress, linearProgress)
-
-                // If the dialog content is complex, its dimension might change during the launch
-                // animation. The animation end position might also change during the exit
-                // animation, for instance when locking the phone when the dialog is open. Therefore
-                // we update the end state to the new position/size. Usually the dialog dimension or
-                // position will change in the early frames, so changing the end state shouldn't
-                // really be noticeable.
-                endViewController.fillGhostedViewState(endState)
-            }
-        }
-
         launchAnimator.startAnimation(controller, endState, originalDialogBackgroundColor)
     }
 
@@ -791,7 +853,7 @@
         return (touchSurface.parent as? View)?.isShown ?: true
     }
 
-    /** A layout listener to animate the change of bounds of the dialog background.  */
+    /** A layout listener to animate the change of bounds of the dialog background. */
     class AnimatedBoundsLayoutListener : View.OnLayoutChangeListener {
         companion object {
             private const val ANIMATION_DURATION = 500L
@@ -836,32 +898,35 @@
             currentAnimator?.cancel()
             currentAnimator = null
 
-            val animator = ValueAnimator.ofFloat(0f, 1f).apply {
-                duration = ANIMATION_DURATION
-                interpolator = Interpolators.STANDARD
+            val animator =
+                ValueAnimator.ofFloat(0f, 1f).apply {
+                    duration = ANIMATION_DURATION
+                    interpolator = Interpolators.STANDARD
 
-                addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationEnd(animation: Animator) {
-                        currentAnimator = null
+                    addListener(
+                        object : AnimatorListenerAdapter() {
+                            override fun onAnimationEnd(animation: Animator) {
+                                currentAnimator = null
+                            }
+                        }
+                    )
+
+                    addUpdateListener { animatedValue ->
+                        val progress = animatedValue.animatedFraction
+
+                        // Compute new bounds.
+                        bounds.left = MathUtils.lerp(startLeft, left, progress).roundToInt()
+                        bounds.top = MathUtils.lerp(startTop, top, progress).roundToInt()
+                        bounds.right = MathUtils.lerp(startRight, right, progress).roundToInt()
+                        bounds.bottom = MathUtils.lerp(startBottom, bottom, progress).roundToInt()
+
+                        // Set the new bounds.
+                        view.left = bounds.left
+                        view.top = bounds.top
+                        view.right = bounds.right
+                        view.bottom = bounds.bottom
                     }
-                })
-
-                addUpdateListener { animatedValue ->
-                    val progress = animatedValue.animatedFraction
-
-                    // Compute new bounds.
-                    bounds.left = MathUtils.lerp(startLeft, left, progress).roundToInt()
-                    bounds.top = MathUtils.lerp(startTop, top, progress).roundToInt()
-                    bounds.right = MathUtils.lerp(startRight, right, progress).roundToInt()
-                    bounds.bottom = MathUtils.lerp(startBottom, bottom, progress).roundToInt()
-
-                    // Set the new bounds.
-                    view.left = bounds.left
-                    view.top = bounds.top
-                    view.right = bounds.right
-                    view.bottom = bounds.bottom
                 }
-            }
 
             currentAnimator = animator
             animator.start()
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index 3f7e0f0..47f448d 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -105,9 +105,7 @@
             }
 
             // Perform a BFS to find the largest View with background.
-            val views = LinkedList<View>().apply {
-                add(view)
-            }
+            val views = LinkedList<View>().apply { add(view) }
 
             while (views.isNotEmpty()) {
                 val v = views.removeFirst()
@@ -161,10 +159,11 @@
     }
 
     override fun createAnimatorState(): LaunchAnimator.State {
-        val state = LaunchAnimator.State(
-            topCornerRadius = getCurrentTopCornerRadius(),
-            bottomCornerRadius = getCurrentBottomCornerRadius()
-        )
+        val state =
+            LaunchAnimator.State(
+                topCornerRadius = getCurrentTopCornerRadius(),
+                bottomCornerRadius = getCurrentBottomCornerRadius()
+            )
         fillGhostedViewState(state)
         return state
     }
@@ -255,13 +254,14 @@
 
         launchContainer.getLocationOnScreen(launchContainerLocation)
         ghostViewMatrix.postScale(
-            scale, scale,
+            scale,
+            scale,
             ghostedViewState.centerX - launchContainerLocation[0],
             ghostedViewState.centerY - launchContainerLocation[1]
         )
         ghostViewMatrix.postTranslate(
-                (leftChange + rightChange) / 2f,
-                (topChange + bottomChange) / 2f
+            (leftChange + rightChange) / 2f,
+            (topChange + bottomChange) / 2f
         )
         ghostView.animationMatrix = ghostViewMatrix
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchAnimator.kt
index a4c5c30..9668066 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchAnimator.kt
@@ -34,10 +34,7 @@
 private const val TAG = "LaunchAnimator"
 
 /** A base class to animate a window launch (activity or dialog) from a view . */
-class LaunchAnimator(
-    private val timings: Timings,
-    private val interpolators: Interpolators
-) {
+class LaunchAnimator(private val timings: Timings, private val interpolators: Interpolators) {
     companion object {
         internal const val DEBUG = false
         private val SRC_MODE = PorterDuffXfermode(PorterDuff.Mode.SRC)
@@ -75,10 +72,10 @@
          * with the opening window.
          *
          * This will be used to:
-         *  - Get the associated [Context].
-         *  - Compute whether we are expanding fully above the launch container.
-         *  - Get to overlay to which we initially put the window background layer, until the
-         *    opening window is made visible (see [openingWindowSyncView]).
+         * - Get the associated [Context].
+         * - Compute whether we are expanding fully above the launch container.
+         * - Get to overlay to which we initially put the window background layer, until the opening
+         * window is made visible (see [openingWindowSyncView]).
          *
          * This container can be changed to force this [Controller] to animate the expanding view
          * inside a different location, for instance to ensure correct layering during the
@@ -132,7 +129,6 @@
         var bottom: Int = 0,
         var left: Int = 0,
         var right: Int = 0,
-
         var topCornerRadius: Float = 0f,
         var bottomCornerRadius: Float = 0f
     ) {
@@ -202,18 +198,20 @@
     )
 
     /**
-     * Start a launch animation controlled by [controller] towards [endState]. An intermediary
-     * layer with [windowBackgroundColor] will fade in then fade out above the expanding view, and
-     * should be the same background color as the opening (or closing) window. If [drawHole] is
-     * true, then this intermediary layer will be drawn with SRC blending mode while it fades out.
+     * Start a launch animation controlled by [controller] towards [endState]. An intermediary layer
+     * with [windowBackgroundColor] will fade in then (optionally) fade out above the expanding
+     * view, and should be the same background color as the opening (or closing) window.
      *
-     * TODO(b/184121838): Remove [drawHole] and instead make the StatusBar draw this hole instead.
+     * If [fadeOutWindowBackgroundLayer] is true, then this intermediary layer will fade out during
+     * the second half of the animation, and will have SRC blending mode (ultimately punching a hole
+     * in the [launch container][Controller.launchContainer]) iff [drawHole] is true.
      */
     fun startAnimation(
         controller: Controller,
         endState: State,
         windowBackgroundColor: Int,
-        drawHole: Boolean = false
+        fadeOutWindowBackgroundLayer: Boolean = true,
+        drawHole: Boolean = false,
     ): Animation {
         val state = controller.createAnimatorState()
 
@@ -238,8 +236,12 @@
         val endBottomCornerRadius = endState.bottomCornerRadius
 
         fun maybeUpdateEndState() {
-            if (endTop != endState.top || endBottom != endState.bottom ||
-                endLeft != endState.left || endRight != endState.right) {
+            if (
+                endTop != endState.top ||
+                    endBottom != endState.bottom ||
+                    endLeft != endState.left ||
+                    endRight != endState.right
+            ) {
                 endTop = endState.top
                 endBottom = endState.bottom
                 endLeft = endState.left
@@ -256,10 +258,11 @@
         // color, which is usually the same color of the app background. We first fade in this layer
         // to hide the expanding view, then we fade it out with SRC mode to draw a hole in the
         // launch container and reveal the opening window.
-        val windowBackgroundLayer = GradientDrawable().apply {
-            setColor(windowBackgroundColor)
-            alpha = 0
-        }
+        val windowBackgroundLayer =
+            GradientDrawable().apply {
+                setColor(windowBackgroundColor)
+                alpha = 0
+            }
 
         // Update state.
         val animator = ValueAnimator.ofFloat(0f, 1f)
@@ -270,38 +273,41 @@
         // [Controller.openingWindowSyncView] once the opening app window starts to be visible.
         val openingWindowSyncView = controller.openingWindowSyncView
         val openingWindowSyncViewOverlay = openingWindowSyncView?.overlay
-        val moveBackgroundLayerWhenAppIsVisible = openingWindowSyncView != null &&
-            openingWindowSyncView.viewRootImpl != controller.launchContainer.viewRootImpl
+        val moveBackgroundLayerWhenAppIsVisible =
+            openingWindowSyncView != null &&
+                openingWindowSyncView.viewRootImpl != controller.launchContainer.viewRootImpl
 
         val launchContainerOverlay = launchContainer.overlay
         var cancelled = false
         var movedBackgroundLayer = false
 
-        animator.addListener(object : AnimatorListenerAdapter() {
-            override fun onAnimationStart(animation: Animator?, isReverse: Boolean) {
-                if (DEBUG) {
-                    Log.d(TAG, "Animation started")
+        animator.addListener(
+            object : AnimatorListenerAdapter() {
+                override fun onAnimationStart(animation: Animator?, isReverse: Boolean) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Animation started")
+                    }
+                    controller.onLaunchAnimationStart(isExpandingFullyAbove)
+
+                    // Add the drawable to the launch container overlay. Overlays always draw
+                    // drawables after views, so we know that it will be drawn above any view added
+                    // by the controller.
+                    launchContainerOverlay.add(windowBackgroundLayer)
                 }
-                controller.onLaunchAnimationStart(isExpandingFullyAbove)
 
-                // Add the drawable to the launch container overlay. Overlays always draw
-                // drawables after views, so we know that it will be drawn above any view added
-                // by the controller.
-                launchContainerOverlay.add(windowBackgroundLayer)
-            }
+                override fun onAnimationEnd(animation: Animator?) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Animation ended")
+                    }
+                    controller.onLaunchAnimationEnd(isExpandingFullyAbove)
+                    launchContainerOverlay.remove(windowBackgroundLayer)
 
-            override fun onAnimationEnd(animation: Animator?) {
-                if (DEBUG) {
-                    Log.d(TAG, "Animation ended")
-                }
-                controller.onLaunchAnimationEnd(isExpandingFullyAbove)
-                launchContainerOverlay.remove(windowBackgroundLayer)
-
-                if (moveBackgroundLayerWhenAppIsVisible) {
-                    openingWindowSyncViewOverlay?.remove(windowBackgroundLayer)
+                    if (moveBackgroundLayerWhenAppIsVisible) {
+                        openingWindowSyncViewOverlay?.remove(windowBackgroundLayer)
+                    }
                 }
             }
-        })
+        )
 
         animator.addUpdateListener { animation ->
             if (cancelled) {
@@ -333,12 +339,13 @@
 
             // The expanding view can/should be hidden once it is completely covered by the opening
             // window.
-            state.visible = getProgress(
-                timings,
-                linearProgress,
-                timings.contentBeforeFadeOutDelay,
-                timings.contentBeforeFadeOutDuration
-            ) < 1
+            state.visible =
+                getProgress(
+                    timings,
+                    linearProgress,
+                    timings.contentBeforeFadeOutDelay,
+                    timings.contentBeforeFadeOutDuration
+                ) < 1
 
             if (moveBackgroundLayerWhenAppIsVisible && !state.visible && !movedBackgroundLayer) {
                 // The expanding view is not visible, so the opening app is visible. If this is the
@@ -352,17 +359,19 @@
                 ViewRootSync.synchronizeNextDraw(launchContainer, openingWindowSyncView, then = {})
             }
 
-            val container = if (movedBackgroundLayer) {
-                openingWindowSyncView!!
-            } else {
-                controller.launchContainer
-            }
+            val container =
+                if (movedBackgroundLayer) {
+                    openingWindowSyncView!!
+                } else {
+                    controller.launchContainer
+                }
 
             applyStateToWindowBackgroundLayer(
                 windowBackgroundLayer,
                 state,
                 linearProgress,
                 container,
+                fadeOutWindowBackgroundLayer,
                 drawHole
             )
             controller.onLaunchAnimationProgress(state, progress, linearProgress)
@@ -391,6 +400,7 @@
         state: State,
         linearProgress: Float,
         launchContainer: View,
+        fadeOutWindowBackgroundLayer: Boolean,
         drawHole: Boolean
     ) {
         // Update position.
@@ -415,23 +425,25 @@
 
         // We first fade in the background layer to hide the expanding view, then fade it out
         // with SRC mode to draw a hole punch in the status bar and reveal the opening window.
-        val fadeInProgress = getProgress(
-            timings,
-            linearProgress,
-            timings.contentBeforeFadeOutDelay,
-            timings.contentBeforeFadeOutDuration
-        )
+        val fadeInProgress =
+            getProgress(
+                timings,
+                linearProgress,
+                timings.contentBeforeFadeOutDelay,
+                timings.contentBeforeFadeOutDuration
+            )
         if (fadeInProgress < 1) {
             val alpha =
                 interpolators.contentBeforeFadeOutInterpolator.getInterpolation(fadeInProgress)
             drawable.alpha = (alpha * 0xFF).roundToInt()
-        } else {
-            val fadeOutProgress = getProgress(
-                timings,
-                linearProgress,
-                timings.contentAfterFadeInDelay,
-                timings.contentAfterFadeInDuration
-            )
+        } else if (fadeOutWindowBackgroundLayer) {
+            val fadeOutProgress =
+                getProgress(
+                    timings,
+                    linearProgress,
+                    timings.contentAfterFadeInDelay,
+                    timings.contentAfterFadeInDuration
+                )
             val alpha =
                 1 - interpolators.contentAfterFadeInInterpolator.getInterpolation(fadeOutProgress)
             drawable.alpha = (alpha * 0xFF).roundToInt()
@@ -439,6 +451,8 @@
             if (drawHole) {
                 drawable.setXfermode(SRC_MODE)
             }
+        } else {
+            drawable.alpha = 0xFF
         }
     }
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
index 80a3eb8..7499302 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
@@ -27,4 +27,4 @@
      * [transition][android.view.View.setTransitionVisibility] visibility changes must be blocked.
      */
     fun setShouldBlockVisibilityChanges(block: Boolean)
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt
index 47c1101..f9c6841 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteTransitionAdapter.kt
@@ -40,6 +40,7 @@
     companion object {
         /**
          * Almost a copy of Transitions#setupStartState.
+         *
          * TODO: remove when there is proper cross-process transaction sync.
          */
         @SuppressLint("NewApi")
@@ -50,7 +51,8 @@
             info: TransitionInfo,
             t: SurfaceControl.Transaction
         ) {
-            val isOpening = info.type == WindowManager.TRANSIT_OPEN ||
+            val isOpening =
+                info.type == WindowManager.TRANSIT_OPEN ||
                     info.type == WindowManager.TRANSIT_TO_FRONT
             // Put animating stuff above this line and put static stuff below it.
             val zSplitLine = info.changes.size
@@ -59,15 +61,19 @@
 
             // Launcher animates leaf tasks directly, so always reparent all task leashes to root.
             t.reparent(leash, info.rootLeash)
-            t.setPosition(leash, (change.startAbsBounds.left - info.rootOffset.x).toFloat(), (
-                    change.startAbsBounds.top - info.rootOffset.y).toFloat())
+            t.setPosition(
+                leash,
+                (change.startAbsBounds.left - info.rootOffset.x).toFloat(),
+                (change.startAbsBounds.top - info.rootOffset.y).toFloat()
+            )
             t.show(leash)
             // Put all the OPEN/SHOW on top
             if (mode == WindowManager.TRANSIT_OPEN || mode == WindowManager.TRANSIT_TO_FRONT) {
                 if (isOpening) {
                     t.setLayer(leash, zSplitLine + info.changes.size - layer)
-                    if (change.flags
-                            and TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT == 0) {
+                    if (
+                        change.flags and TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT == 0
+                    ) {
                         // if transferred, it should be left visible.
                         t.setAlpha(leash, 0f)
                     }
@@ -75,8 +81,9 @@
                     // put on bottom and leave it visible
                     t.setLayer(leash, zSplitLine - layer)
                 }
-            } else if (mode == WindowManager.TRANSIT_CLOSE ||
-                    mode == WindowManager.TRANSIT_TO_BACK) {
+            } else if (
+                mode == WindowManager.TRANSIT_CLOSE || mode == WindowManager.TRANSIT_TO_BACK
+            ) {
                 if (isOpening) {
                     // put on bottom and leave visible
                     t.setLayer(leash, zSplitLine - layer)
@@ -102,10 +109,15 @@
                 // making leashes means we have to handle them specially.
                 return change.leash
             }
-            val leashSurface = SurfaceControl.Builder()
+            val leashSurface =
+                SurfaceControl.Builder()
                     .setName(change.leash.toString() + "_transition-leash")
-                    .setContainerLayer().setParent(if (change.parent == null)
-                            info.rootLeash else info.getChange(change.parent!!)!!.leash).build()
+                    .setContainerLayer()
+                    .setParent(
+                        if (change.parent == null) info.rootLeash
+                        else info.getChange(change.parent!!)!!.leash
+                    )
+                    .build()
             // Copied Transitions setup code (which expects bottom-to-top order, so we swap here)
             setupLeash(leashSurface, change, info.changes.size - order, info, t)
             t.reparent(change.leash, leashSurface)
@@ -118,10 +130,10 @@
 
         private fun newModeToLegacyMode(newMode: Int): Int {
             return when (newMode) {
-                WindowManager.TRANSIT_OPEN, WindowManager.TRANSIT_TO_FRONT
-                        -> RemoteAnimationTarget.MODE_OPENING
-                WindowManager.TRANSIT_CLOSE, WindowManager.TRANSIT_TO_BACK
-                        -> RemoteAnimationTarget.MODE_CLOSING
+                WindowManager.TRANSIT_OPEN,
+                WindowManager.TRANSIT_TO_FRONT -> RemoteAnimationTarget.MODE_OPENING
+                WindowManager.TRANSIT_CLOSE,
+                WindowManager.TRANSIT_TO_BACK -> RemoteAnimationTarget.MODE_CLOSING
                 else -> RemoteAnimationTarget.MODE_CHANGING
             }
         }
@@ -138,12 +150,13 @@
             info: TransitionInfo,
             t: SurfaceControl.Transaction
         ): RemoteAnimationTarget {
-            val target = RemoteAnimationTarget(
+            val target =
+                RemoteAnimationTarget(
                     /* taskId */ if (change.taskInfo != null) change.taskInfo!!.taskId else -1,
                     /* mode */ newModeToLegacyMode(change.mode),
                     /* leash */ createLeash(info, change, order, t),
                     /* isTranslucent */ (change.flags and TransitionInfo.FLAG_TRANSLUCENT != 0 ||
-                    change.flags and TransitionInfo.FLAG_SHOW_WALLPAPER != 0),
+                        change.flags and TransitionInfo.FLAG_SHOW_WALLPAPER != 0),
                     /* clipRect */ null,
                     /* contentInsets */ Rect(0, 0, 0, 0),
                     /* prefixOrderIndex */ order,
@@ -151,15 +164,16 @@
                     /* localBounds */ rectOffsetTo(change.endAbsBounds, change.endRelOffset),
                     /* screenSpaceBounds */ Rect(change.endAbsBounds),
                     /* windowConfig */ if (change.taskInfo != null)
-                            change.taskInfo!!.configuration.windowConfiguration else
-                                    WindowConfiguration(),
-                    /* isNotInRecents */ if (change.taskInfo != null)
-                            !change.taskInfo!!.isRunning else true,
+                        change.taskInfo!!.configuration.windowConfiguration
+                    else WindowConfiguration(),
+                    /* isNotInRecents */ if (change.taskInfo != null) !change.taskInfo!!.isRunning
+                    else true,
                     /* startLeash */ null,
                     /* startBounds */ Rect(change.startAbsBounds),
                     /* taskInfo */ change.taskInfo,
                     /* allowEnterPip */ change.allowEnterPip,
-                    /* windowType */ WindowManager.LayoutParams.INVALID_WINDOW_TYPE)
+                    /* windowType */ WindowManager.LayoutParams.INVALID_WINDOW_TYPE
+                )
             target.backgroundColor = change.backgroundColor
             return target
         }
@@ -192,9 +206,7 @@
         }
 
         @JvmStatic
-        fun adaptRemoteRunner(
-            runner: IRemoteAnimationRunner
-        ): IRemoteTransition.Stub {
+        fun adaptRemoteRunner(runner: IRemoteAnimationRunner): IRemoteTransition.Stub {
             return object : IRemoteTransition.Stub() {
                 override fun startAnimation(
                     token: IBinder,
@@ -218,18 +230,24 @@
                     var displayH = 0f
                     for (i in info.changes.indices.reversed()) {
                         val change = info.changes[i]
-                        if (change.taskInfo != null &&
-                                change.taskInfo!!.activityType
-                                        == WindowConfiguration.ACTIVITY_TYPE_HOME) {
-                            isReturnToHome = (change.mode == WindowManager.TRANSIT_OPEN ||
+                        if (
+                            change.taskInfo != null &&
+                                change.taskInfo!!.activityType ==
+                                    WindowConfiguration.ACTIVITY_TYPE_HOME
+                        ) {
+                            isReturnToHome =
+                                (change.mode == WindowManager.TRANSIT_OPEN ||
                                     change.mode == WindowManager.TRANSIT_TO_FRONT)
                             launcherTask = change
                             launcherLayer = info.changes.size - i
                         } else if (change.flags and TransitionInfo.FLAG_IS_WALLPAPER != 0) {
                             wallpaper = change
                         }
-                        if (change.parent == null && change.endRotation >= 0 &&
-                                change.endRotation != change.startRotation) {
+                        if (
+                            change.parent == null &&
+                                change.endRotation >= 0 &&
+                                change.endRotation != change.startRotation
+                        ) {
                             rotateDelta = change.endRotation - change.startRotation
                             displayW = change.endAbsBounds.width().toFloat()
                             displayH = change.endAbsBounds.height().toFloat()
@@ -240,8 +258,13 @@
                     val counterLauncher = CounterRotator()
                     val counterWallpaper = CounterRotator()
                     if (launcherTask != null && rotateDelta != 0 && launcherTask.parent != null) {
-                        counterLauncher.setup(t, info.getChange(launcherTask.parent!!)!!.leash,
-                                rotateDelta, displayW, displayH)
+                        counterLauncher.setup(
+                            t,
+                            info.getChange(launcherTask.parent!!)!!.leash,
+                            rotateDelta,
+                            displayW,
+                            displayH
+                        )
                         if (counterLauncher.surface != null) {
                             t.setLayer(counterLauncher.surface!!, launcherLayer)
                         }
@@ -257,8 +280,10 @@
                             val mode = info.changes[i].mode
                             // Only deal with independent layers
                             if (!TransitionInfo.isIndependent(change, info)) continue
-                            if (mode == WindowManager.TRANSIT_CLOSE ||
-                                    mode == WindowManager.TRANSIT_TO_BACK) {
+                            if (
+                                mode == WindowManager.TRANSIT_CLOSE ||
+                                    mode == WindowManager.TRANSIT_TO_BACK
+                            ) {
                                 t.setLayer(leash!!, info.changes.size * 3 - i)
                                 counterLauncher.addChild(t, leash)
                             }
@@ -273,8 +298,13 @@
                             counterLauncher.addChild(t, leashMap[launcherTask.leash])
                         }
                         if (wallpaper != null && rotateDelta != 0 && wallpaper.parent != null) {
-                            counterWallpaper.setup(t, info.getChange(wallpaper.parent!!)!!.leash,
-                                    rotateDelta, displayW, displayH)
+                            counterWallpaper.setup(
+                                t,
+                                info.getChange(wallpaper.parent!!)!!.leash,
+                                rotateDelta,
+                                displayW,
+                                displayH
+                            )
                             if (counterWallpaper.surface != null) {
                                 t.setLayer(counterWallpaper.surface!!, -1)
                                 counterWallpaper.addChild(t, leashMap[wallpaper.leash])
@@ -282,37 +312,47 @@
                         }
                     }
                     t.apply()
-                    val animationFinishedCallback = object : IRemoteAnimationFinishedCallback {
-                        override fun onAnimationFinished() {
-                            val finishTransaction = SurfaceControl.Transaction()
-                            counterLauncher.cleanUp(finishTransaction)
-                            counterWallpaper.cleanUp(finishTransaction)
-                            // Release surface references now. This is apparently to free GPU memory
-                            // while doing quick operations (eg. during CTS).
-                            for (i in info.changes.indices.reversed()) {
-                                info.changes[i].leash.release()
+                    val animationFinishedCallback =
+                        object : IRemoteAnimationFinishedCallback {
+                            override fun onAnimationFinished() {
+                                val finishTransaction = SurfaceControl.Transaction()
+                                counterLauncher.cleanUp(finishTransaction)
+                                counterWallpaper.cleanUp(finishTransaction)
+                                // Release surface references now. This is apparently to free GPU
+                                // memory while doing quick operations (eg. during CTS).
+                                for (i in info.changes.indices.reversed()) {
+                                    info.changes[i].leash.release()
+                                }
+                                for (i in leashMap.size - 1 downTo 0) {
+                                    leashMap.valueAt(i).release()
+                                }
+                                try {
+                                    finishCallback.onTransitionFinished(
+                                        null /* wct */,
+                                        finishTransaction
+                                    )
+                                } catch (e: RemoteException) {
+                                    Log.e(
+                                        "ActivityOptionsCompat",
+                                        "Failed to call app controlled" +
+                                            " animation finished callback",
+                                        e
+                                    )
+                                }
                             }
-                            for (i in leashMap.size - 1 downTo 0) {
-                                leashMap.valueAt(i).release()
-                            }
-                            try {
-                                finishCallback.onTransitionFinished(null /* wct */,
-                                        finishTransaction)
-                            } catch (e: RemoteException) {
-                                Log.e("ActivityOptionsCompat", "Failed to call app controlled" +
-                                        " animation finished callback", e)
-                            }
-                        }
 
-                        override fun asBinder(): IBinder? {
-                            return null
+                            override fun asBinder(): IBinder? {
+                                return null
+                            }
                         }
-                    }
                     // TODO(bc-unlcok): Pass correct transit type.
                     runner.onAnimationStart(
-                            WindowManager.TRANSIT_OLD_NONE,
-                            appsCompat, wallpapersCompat, nonAppsCompat,
-                            animationFinishedCallback)
+                        WindowManager.TRANSIT_OLD_NONE,
+                        appsCompat,
+                        wallpapersCompat,
+                        nonAppsCompat,
+                        animationFinishedCallback
+                    )
                 }
 
                 override fun mergeAnimation(
@@ -329,18 +369,14 @@
         }
 
         @JvmStatic
-        fun adaptRemoteAnimation(
-            adapter: RemoteAnimationAdapter
-        ): RemoteTransition {
+        fun adaptRemoteAnimation(adapter: RemoteAnimationAdapter): RemoteTransition {
             return RemoteTransition(adaptRemoteRunner(adapter.runner), adapter.callingApplication)
         }
     }
 
-    /**
-     * Utility class that takes care of counter-rotating surfaces during a transition animation.
-     */
+    /** Utility class that takes care of counter-rotating surfaces during a transition animation. */
     class CounterRotator {
-        /** Gets the surface with the counter-rotation.  */
+        /** Gets the surface with the counter-rotation. */
         var surface: SurfaceControl? = null
             private set
 
@@ -358,7 +394,8 @@
             parentH: Float
         ) {
             if (rotateDelta == 0) return
-            val surface = SurfaceControl.Builder()
+            val surface =
+                SurfaceControl.Builder()
                     .setName("Transition Unrotate")
                     .setContainerLayer()
                     .setParent(parent)
@@ -378,21 +415,19 @@
             t.show(surface)
         }
 
-        /**
-         * Adds a surface that needs to be counter-rotate.
-         */
+        /** Adds a surface that needs to be counter-rotate. */
         fun addChild(t: SurfaceControl.Transaction, child: SurfaceControl?) {
             if (surface == null) return
             t.reparent(child!!, surface)
         }
 
         /**
-         * Clean-up. Since finishTransaction should reset all change leashes, we only need to remove the
-         * counter rotation surface.
+         * Clean-up. Since finishTransaction should reset all change leashes, we only need to remove
+         * the counter rotation surface.
          */
         fun cleanUp(finishTransaction: SurfaceControl.Transaction) {
             if (surface == null) return
             finishTransaction.remove(surface!!)
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ShadeInterpolation.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ShadeInterpolation.kt
index 0ee2bfe..a96f893 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ShadeInterpolation.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ShadeInterpolation.kt
@@ -31,7 +31,7 @@
         } else {
             val oneMinusFrac = 1f - mappedFraction
             (1f - 0.5f * (1f - Math.cos((3.14159f * oneMinusFrac * oneMinusFrac).toDouble())))
-                    .toFloat()
+                .toFloat()
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
index 4c3cd3c..4b0c62b 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
@@ -42,12 +42,13 @@
         private val DEFAULT_FADE_IN_INTERPOLATOR = Interpolators.ALPHA_IN
 
         /** The properties used to animate the view bounds. */
-        private val PROPERTIES = mapOf(
-            Bound.LEFT to createViewProperty(Bound.LEFT),
-            Bound.TOP to createViewProperty(Bound.TOP),
-            Bound.RIGHT to createViewProperty(Bound.RIGHT),
-            Bound.BOTTOM to createViewProperty(Bound.BOTTOM)
-        )
+        private val PROPERTIES =
+            mapOf(
+                Bound.LEFT to createViewProperty(Bound.LEFT),
+                Bound.TOP to createViewProperty(Bound.TOP),
+                Bound.RIGHT to createViewProperty(Bound.RIGHT),
+                Bound.BOTTOM to createViewProperty(Bound.BOTTOM)
+            )
 
         private fun createViewProperty(bound: Bound): IntProperty<View> {
             return object : IntProperty<View>(bound.label) {
@@ -104,7 +105,8 @@
             duration: Long,
             ephemeral: Boolean
         ): Boolean {
-            if (!isVisible(
+            if (
+                !isVisible(
                     rootView.visibility,
                     rootView.left,
                     rootView.top,
@@ -132,11 +134,7 @@
             duration: Long,
             ephemeral: Boolean
         ): View.OnLayoutChangeListener {
-            return createListener(
-                interpolator,
-                duration,
-                ephemeral
-            )
+            return createListener(interpolator, duration, ephemeral)
         }
 
         /**
@@ -178,7 +176,8 @@
             includeFadeIn: Boolean = false,
             fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR
         ): Boolean {
-            if (isVisible(
+            if (
+                isVisible(
                     rootView.visibility,
                     rootView.left,
                     rootView.top,
@@ -189,9 +188,13 @@
                 return false
             }
 
-            val listener = createAdditionListener(
-                origin, interpolator, duration, ignorePreviousValues = !includeMargins
-            )
+            val listener =
+                createAdditionListener(
+                    origin,
+                    interpolator,
+                    duration,
+                    ignorePreviousValues = !includeMargins
+                )
             addListener(rootView, listener, recursive = true)
 
             if (!includeFadeIn) {
@@ -300,24 +303,26 @@
                         return
                     }
 
-                    val startValues = processStartValues(
-                        origin,
-                        left,
-                        top,
-                        right,
-                        bottom,
-                        startLeft,
-                        startTop,
-                        startRight,
-                        startBottom,
-                        ignorePreviousValues
-                    )
-                    val endValues = mapOf(
-                        Bound.LEFT to left,
-                        Bound.TOP to top,
-                        Bound.RIGHT to right,
-                        Bound.BOTTOM to bottom
-                    )
+                    val startValues =
+                        processStartValues(
+                            origin,
+                            left,
+                            top,
+                            right,
+                            bottom,
+                            startLeft,
+                            startTop,
+                            startRight,
+                            startBottom,
+                            ignorePreviousValues
+                        )
+                    val endValues =
+                        mapOf(
+                            Bound.LEFT to left,
+                            Bound.TOP to top,
+                            Bound.RIGHT to right,
+                            Bound.BOTTOM to bottom
+                        )
 
                     val boundsToAnimate = mutableSetOf<Bound>()
                     if (startValues.getValue(Bound.LEFT) != left) boundsToAnimate.add(Bound.LEFT)
@@ -356,7 +361,8 @@
             interpolator: Interpolator = DEFAULT_REMOVAL_INTERPOLATOR,
             duration: Long = DEFAULT_DURATION
         ): Boolean {
-            if (!isVisible(
+            if (
+                !isVisible(
                     rootView.visibility,
                     rootView.left,
                     rootView.top,
@@ -370,11 +376,7 @@
             val parent = rootView.parent as ViewGroup
 
             // Ensure that rootView's siblings animate nicely around the removal.
-            val listener = createUpdateListener(
-                interpolator,
-                duration,
-                ephemeral = true
-            )
+            val listener = createUpdateListener(interpolator, duration, ephemeral = true)
             for (i in 0 until parent.childCount) {
                 val child = parent.getChildAt(i)
                 if (child == rootView) continue
@@ -389,19 +391,21 @@
             // them manually during the animation.
             parent.overlay.add(rootView)
 
-            val startValues = mapOf(
-                Bound.LEFT to rootView.left,
-                Bound.TOP to rootView.top,
-                Bound.RIGHT to rootView.right,
-                Bound.BOTTOM to rootView.bottom
-            )
-            val endValues = processEndValuesForRemoval(
-                destination,
-                rootView.left,
-                rootView.top,
-                rootView.right,
-                rootView.bottom
-            )
+            val startValues =
+                mapOf(
+                    Bound.LEFT to rootView.left,
+                    Bound.TOP to rootView.top,
+                    Bound.RIGHT to rootView.right,
+                    Bound.BOTTOM to rootView.bottom
+                )
+            val endValues =
+                processEndValuesForRemoval(
+                    destination,
+                    rootView.left,
+                    rootView.top,
+                    rootView.right,
+                    rootView.bottom
+                )
 
             val boundsToAnimate = mutableSetOf<Bound>()
             if (rootView.left != endValues.getValue(Bound.LEFT)) boundsToAnimate.add(Bound.LEFT)
@@ -443,20 +447,24 @@
                             (animation.animatedValue as Float) * startAlphas[i]
                     }
                 }
-                animator.addListener(object : AnimatorListenerAdapter() {
-                    override fun onAnimationEnd(animation: Animator) {
-                        rootView.animate()
-                            .alpha(0f)
-                            .setInterpolator(Interpolators.ALPHA_OUT)
-                            .setDuration(duration / 2)
-                            .withEndAction { parent.overlay.remove(rootView) }
-                            .start()
+                animator.addListener(
+                    object : AnimatorListenerAdapter() {
+                        override fun onAnimationEnd(animation: Animator) {
+                            rootView
+                                .animate()
+                                .alpha(0f)
+                                .setInterpolator(Interpolators.ALPHA_OUT)
+                                .setDuration(duration / 2)
+                                .withEndAction { parent.overlay.remove(rootView) }
+                                .start()
+                        }
                     }
-                })
+                )
                 animator.start()
             } else {
                 // Fade out the view during the second half of the removal.
-                rootView.animate()
+                rootView
+                    .animate()
                     .alpha(0f)
                     .setInterpolator(Interpolators.ALPHA_OUT)
                     .setDuration(duration / 2)
@@ -483,21 +491,23 @@
         ) {
             for (i in 0 until rootView.childCount) {
                 val child = rootView.getChildAt(i)
-                val childStartValues = mapOf(
-                    Bound.LEFT to child.left,
-                    Bound.TOP to child.top,
-                    Bound.RIGHT to child.right,
-                    Bound.BOTTOM to child.bottom
-                )
-                val childEndValues = processChildEndValuesForRemoval(
-                    destination,
-                    child.left,
-                    child.top,
-                    child.right,
-                    child.bottom,
-                    endValues.getValue(Bound.RIGHT) - endValues.getValue(Bound.LEFT),
-                    endValues.getValue(Bound.BOTTOM) - endValues.getValue(Bound.TOP)
-                )
+                val childStartValues =
+                    mapOf(
+                        Bound.LEFT to child.left,
+                        Bound.TOP to child.top,
+                        Bound.RIGHT to child.right,
+                        Bound.BOTTOM to child.bottom
+                    )
+                val childEndValues =
+                    processChildEndValuesForRemoval(
+                        destination,
+                        child.left,
+                        child.top,
+                        child.right,
+                        child.bottom,
+                        endValues.getValue(Bound.RIGHT) - endValues.getValue(Bound.LEFT),
+                        endValues.getValue(Bound.BOTTOM) - endValues.getValue(Bound.TOP)
+                    )
 
                 val boundsToAnimate = mutableSetOf<Bound>()
                 if (child.left != endValues.getValue(Bound.LEFT)) boundsToAnimate.add(Bound.LEFT)
@@ -543,6 +553,7 @@
          * not newly introduced margins are included.
          *
          * Base case
+         * ```
          *     1) origin=TOP
          *         x---------x    x---------x    x---------x    x---------x    x---------x
          *                        x---------x    |         |    |         |    |         |
@@ -561,11 +572,11 @@
          *              x      ->    x---x    ->   |     |   ->  |       |  -> |         |
          *                                         x-----x       x-------x     |         |
          *                                                                     x---------x
-         *
+         * ```
          * In case the start and end values differ in the direction of the origin, and
          * [ignorePreviousValues] is false, the previous values are used and a translation is
          * included in addition to the view expansion.
-         *
+         * ```
          *     origin=TOP_LEFT - (0,0,0,0) -> (30,30,70,70)
          *         x
          *                         x--x
@@ -574,6 +585,7 @@
          *                                         x----x          |      |
          *                                                         |      |
          *                                                         x------x
+         * ```
          */
         private fun processStartValues(
             origin: Hotspot?,
@@ -598,42 +610,54 @@
             var bottom = startBottom
 
             if (origin != null) {
-                left = when (origin) {
-                    Hotspot.CENTER -> (newLeft + newRight) / 2
-                    Hotspot.BOTTOM_LEFT, Hotspot.LEFT, Hotspot.TOP_LEFT -> min(startLeft, newLeft)
-                    Hotspot.TOP, Hotspot.BOTTOM -> newLeft
-                    Hotspot.TOP_RIGHT, Hotspot.RIGHT, Hotspot.BOTTOM_RIGHT -> max(
-                        startRight,
-                        newRight
-                    )
-                }
-                top = when (origin) {
-                    Hotspot.CENTER -> (newTop + newBottom) / 2
-                    Hotspot.TOP_LEFT, Hotspot.TOP, Hotspot.TOP_RIGHT -> min(startTop, newTop)
-                    Hotspot.LEFT, Hotspot.RIGHT -> newTop
-                    Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM, Hotspot.BOTTOM_LEFT -> max(
-                        startBottom,
-                        newBottom
-                    )
-                }
-                right = when (origin) {
-                    Hotspot.CENTER -> (newLeft + newRight) / 2
-                    Hotspot.TOP_RIGHT, Hotspot.RIGHT, Hotspot.BOTTOM_RIGHT -> max(
-                        startRight,
-                        newRight
-                    )
-                    Hotspot.TOP, Hotspot.BOTTOM -> newRight
-                    Hotspot.BOTTOM_LEFT, Hotspot.LEFT, Hotspot.TOP_LEFT -> min(startLeft, newLeft)
-                }
-                bottom = when (origin) {
-                    Hotspot.CENTER -> (newTop + newBottom) / 2
-                    Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM, Hotspot.BOTTOM_LEFT -> max(
-                        startBottom,
-                        newBottom
-                    )
-                    Hotspot.LEFT, Hotspot.RIGHT -> newBottom
-                    Hotspot.TOP_LEFT, Hotspot.TOP, Hotspot.TOP_RIGHT -> min(startTop, newTop)
-                }
+                left =
+                    when (origin) {
+                        Hotspot.CENTER -> (newLeft + newRight) / 2
+                        Hotspot.BOTTOM_LEFT,
+                        Hotspot.LEFT,
+                        Hotspot.TOP_LEFT -> min(startLeft, newLeft)
+                        Hotspot.TOP,
+                        Hotspot.BOTTOM -> newLeft
+                        Hotspot.TOP_RIGHT,
+                        Hotspot.RIGHT,
+                        Hotspot.BOTTOM_RIGHT -> max(startRight, newRight)
+                    }
+                top =
+                    when (origin) {
+                        Hotspot.CENTER -> (newTop + newBottom) / 2
+                        Hotspot.TOP_LEFT,
+                        Hotspot.TOP,
+                        Hotspot.TOP_RIGHT -> min(startTop, newTop)
+                        Hotspot.LEFT,
+                        Hotspot.RIGHT -> newTop
+                        Hotspot.BOTTOM_RIGHT,
+                        Hotspot.BOTTOM,
+                        Hotspot.BOTTOM_LEFT -> max(startBottom, newBottom)
+                    }
+                right =
+                    when (origin) {
+                        Hotspot.CENTER -> (newLeft + newRight) / 2
+                        Hotspot.TOP_RIGHT,
+                        Hotspot.RIGHT,
+                        Hotspot.BOTTOM_RIGHT -> max(startRight, newRight)
+                        Hotspot.TOP,
+                        Hotspot.BOTTOM -> newRight
+                        Hotspot.BOTTOM_LEFT,
+                        Hotspot.LEFT,
+                        Hotspot.TOP_LEFT -> min(startLeft, newLeft)
+                    }
+                bottom =
+                    when (origin) {
+                        Hotspot.CENTER -> (newTop + newBottom) / 2
+                        Hotspot.BOTTOM_RIGHT,
+                        Hotspot.BOTTOM,
+                        Hotspot.BOTTOM_LEFT -> max(startBottom, newBottom)
+                        Hotspot.LEFT,
+                        Hotspot.RIGHT -> newBottom
+                        Hotspot.TOP_LEFT,
+                        Hotspot.TOP,
+                        Hotspot.TOP_RIGHT -> min(startTop, newTop)
+                    }
             }
 
             return mapOf(
@@ -649,6 +673,7 @@
          * view's starting bounds.
          *
          * Examples:
+         * ```
          *     1) destination=TOP
          *         x---------x    x---------x    x---------x    x---------x    x---------x
          *         |         |    |         |    |         |    x---------x
@@ -667,6 +692,7 @@
          *         |         | ->  |       |  ->   |     |   ->    x---x    ->      x
          *         |         |     x-------x       x-----x
          *         x---------x
+         * ```
          */
         private fun processEndValuesForRemoval(
             destination: Hotspot,
@@ -675,32 +701,54 @@
             right: Int,
             bottom: Int
         ): Map<Bound, Int> {
-            val endLeft = when (destination) {
-                Hotspot.CENTER -> (left + right) / 2
-                Hotspot.BOTTOM, Hotspot.BOTTOM_LEFT, Hotspot.LEFT, Hotspot.TOP_LEFT, Hotspot.TOP ->
-                    left
-                Hotspot.TOP_RIGHT, Hotspot.RIGHT, Hotspot.BOTTOM_RIGHT -> right
-            }
-            val endTop = when (destination) {
-                Hotspot.CENTER -> (top + bottom) / 2
-                Hotspot.LEFT, Hotspot.TOP_LEFT, Hotspot.TOP, Hotspot.TOP_RIGHT, Hotspot.RIGHT ->
-                    top
-                Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM, Hotspot.BOTTOM_LEFT -> bottom
-            }
-            val endRight = when (destination) {
-                Hotspot.CENTER -> (left + right) / 2
-                Hotspot.TOP, Hotspot.TOP_RIGHT, Hotspot.RIGHT,
-                Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM ->
-                    right
-                Hotspot.BOTTOM_LEFT, Hotspot.LEFT, Hotspot.TOP_LEFT -> left
-            }
-            val endBottom = when (destination) {
-                Hotspot.CENTER -> (top + bottom) / 2
-                Hotspot.RIGHT, Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM,
-                Hotspot.BOTTOM_LEFT, Hotspot.LEFT ->
-                    bottom
-                Hotspot.TOP_LEFT, Hotspot.TOP, Hotspot.TOP_RIGHT -> top
-            }
+            val endLeft =
+                when (destination) {
+                    Hotspot.CENTER -> (left + right) / 2
+                    Hotspot.BOTTOM,
+                    Hotspot.BOTTOM_LEFT,
+                    Hotspot.LEFT,
+                    Hotspot.TOP_LEFT,
+                    Hotspot.TOP -> left
+                    Hotspot.TOP_RIGHT,
+                    Hotspot.RIGHT,
+                    Hotspot.BOTTOM_RIGHT -> right
+                }
+            val endTop =
+                when (destination) {
+                    Hotspot.CENTER -> (top + bottom) / 2
+                    Hotspot.LEFT,
+                    Hotspot.TOP_LEFT,
+                    Hotspot.TOP,
+                    Hotspot.TOP_RIGHT,
+                    Hotspot.RIGHT -> top
+                    Hotspot.BOTTOM_RIGHT,
+                    Hotspot.BOTTOM,
+                    Hotspot.BOTTOM_LEFT -> bottom
+                }
+            val endRight =
+                when (destination) {
+                    Hotspot.CENTER -> (left + right) / 2
+                    Hotspot.TOP,
+                    Hotspot.TOP_RIGHT,
+                    Hotspot.RIGHT,
+                    Hotspot.BOTTOM_RIGHT,
+                    Hotspot.BOTTOM -> right
+                    Hotspot.BOTTOM_LEFT,
+                    Hotspot.LEFT,
+                    Hotspot.TOP_LEFT -> left
+                }
+            val endBottom =
+                when (destination) {
+                    Hotspot.CENTER -> (top + bottom) / 2
+                    Hotspot.RIGHT,
+                    Hotspot.BOTTOM_RIGHT,
+                    Hotspot.BOTTOM,
+                    Hotspot.BOTTOM_LEFT,
+                    Hotspot.LEFT -> bottom
+                    Hotspot.TOP_LEFT,
+                    Hotspot.TOP,
+                    Hotspot.TOP_RIGHT -> top
+                }
 
             return mapOf(
                 Bound.LEFT to endLeft,
@@ -718,6 +766,7 @@
          * its center is at the [destination].
          *
          * Examples:
+         * ```
          *     1) destination=TOP
          *         The child maintains its left and right positions, but is shifted up so that its
          *         center is on the parent's end top edge.
@@ -725,6 +774,7 @@
          *         The child shifts so that its center is on the parent's end bottom left corner.
          *     3) destination=CENTER
          *         The child shifts so that its own center is on the parent's end center.
+         * ```
          */
         private fun processChildEndValuesForRemoval(
             destination: Hotspot,
@@ -738,32 +788,54 @@
             val halfWidth = (right - left) / 2
             val halfHeight = (bottom - top) / 2
 
-            val endLeft = when (destination) {
-                Hotspot.CENTER -> (parentWidth / 2) - halfWidth
-                Hotspot.BOTTOM_LEFT, Hotspot.LEFT, Hotspot.TOP_LEFT -> -halfWidth
-                Hotspot.TOP_RIGHT, Hotspot.RIGHT, Hotspot.BOTTOM_RIGHT -> parentWidth - halfWidth
-                Hotspot.TOP, Hotspot.BOTTOM -> left
-            }
-            val endTop = when (destination) {
-                Hotspot.CENTER -> (parentHeight / 2) - halfHeight
-                Hotspot.TOP_LEFT, Hotspot.TOP, Hotspot.TOP_RIGHT -> -halfHeight
-                Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM, Hotspot.BOTTOM_LEFT ->
-                    parentHeight - halfHeight
-                Hotspot.LEFT, Hotspot.RIGHT -> top
-            }
-            val endRight = when (destination) {
-                Hotspot.CENTER -> (parentWidth / 2) + halfWidth
-                Hotspot.TOP_RIGHT, Hotspot.RIGHT, Hotspot.BOTTOM_RIGHT -> parentWidth + halfWidth
-                Hotspot.BOTTOM_LEFT, Hotspot.LEFT, Hotspot.TOP_LEFT -> halfWidth
-                Hotspot.TOP, Hotspot.BOTTOM -> right
-            }
-            val endBottom = when (destination) {
-                Hotspot.CENTER -> (parentHeight / 2) + halfHeight
-                Hotspot.BOTTOM_RIGHT, Hotspot.BOTTOM, Hotspot.BOTTOM_LEFT ->
-                    parentHeight + halfHeight
-                Hotspot.TOP_LEFT, Hotspot.TOP, Hotspot.TOP_RIGHT -> halfHeight
-                Hotspot.LEFT, Hotspot.RIGHT -> bottom
-            }
+            val endLeft =
+                when (destination) {
+                    Hotspot.CENTER -> (parentWidth / 2) - halfWidth
+                    Hotspot.BOTTOM_LEFT,
+                    Hotspot.LEFT,
+                    Hotspot.TOP_LEFT -> -halfWidth
+                    Hotspot.TOP_RIGHT,
+                    Hotspot.RIGHT,
+                    Hotspot.BOTTOM_RIGHT -> parentWidth - halfWidth
+                    Hotspot.TOP,
+                    Hotspot.BOTTOM -> left
+                }
+            val endTop =
+                when (destination) {
+                    Hotspot.CENTER -> (parentHeight / 2) - halfHeight
+                    Hotspot.TOP_LEFT,
+                    Hotspot.TOP,
+                    Hotspot.TOP_RIGHT -> -halfHeight
+                    Hotspot.BOTTOM_RIGHT,
+                    Hotspot.BOTTOM,
+                    Hotspot.BOTTOM_LEFT -> parentHeight - halfHeight
+                    Hotspot.LEFT,
+                    Hotspot.RIGHT -> top
+                }
+            val endRight =
+                when (destination) {
+                    Hotspot.CENTER -> (parentWidth / 2) + halfWidth
+                    Hotspot.TOP_RIGHT,
+                    Hotspot.RIGHT,
+                    Hotspot.BOTTOM_RIGHT -> parentWidth + halfWidth
+                    Hotspot.BOTTOM_LEFT,
+                    Hotspot.LEFT,
+                    Hotspot.TOP_LEFT -> halfWidth
+                    Hotspot.TOP,
+                    Hotspot.BOTTOM -> right
+                }
+            val endBottom =
+                when (destination) {
+                    Hotspot.CENTER -> (parentHeight / 2) + halfHeight
+                    Hotspot.BOTTOM_RIGHT,
+                    Hotspot.BOTTOM,
+                    Hotspot.BOTTOM_LEFT -> parentHeight + halfHeight
+                    Hotspot.TOP_LEFT,
+                    Hotspot.TOP,
+                    Hotspot.TOP_RIGHT -> halfHeight
+                    Hotspot.LEFT,
+                    Hotspot.RIGHT -> bottom
+                }
 
             return mapOf(
                 Bound.LEFT to endLeft,
@@ -833,44 +905,49 @@
             duration: Long,
             ephemeral: Boolean
         ) {
-            val propertyValuesHolders = buildList {
-                bounds.forEach { bound ->
-                    add(
-                        PropertyValuesHolder.ofInt(
-                            PROPERTIES[bound],
-                            startValues.getValue(bound),
-                            endValues.getValue(bound)
-                        )
-                    )
-                }
-            }.toTypedArray()
+            val propertyValuesHolders =
+                buildList {
+                        bounds.forEach { bound ->
+                            add(
+                                PropertyValuesHolder.ofInt(
+                                    PROPERTIES[bound],
+                                    startValues.getValue(bound),
+                                    endValues.getValue(bound)
+                                )
+                            )
+                        }
+                    }
+                    .toTypedArray()
 
             (view.getTag(R.id.tag_animator) as? ObjectAnimator)?.cancel()
 
             val animator = ObjectAnimator.ofPropertyValuesHolder(view, *propertyValuesHolders)
             animator.interpolator = interpolator
             animator.duration = duration
-            animator.addListener(object : AnimatorListenerAdapter() {
-                var cancelled = false
+            animator.addListener(
+                object : AnimatorListenerAdapter() {
+                    var cancelled = false
 
-                override fun onAnimationEnd(animation: Animator) {
-                    view.setTag(R.id.tag_animator, null /* tag */)
-                    bounds.forEach { view.setTag(it.overrideTag, null /* tag */) }
+                    override fun onAnimationEnd(animation: Animator) {
+                        view.setTag(R.id.tag_animator, null /* tag */)
+                        bounds.forEach { view.setTag(it.overrideTag, null /* tag */) }
 
-                    // When an animation is cancelled, a new one might be taking over. We shouldn't
-                    // unregister the listener yet.
-                    if (ephemeral && !cancelled) {
-                        // The duration is the same for the whole hierarchy, so it's safe to remove
-                        // the listener recursively. We do this because some descendant views might
-                        // not change bounds, and therefore not animate and leak the listener.
-                        recursivelyRemoveListener(view)
+                        // When an animation is cancelled, a new one might be taking over. We
+                        // shouldn't unregister the listener yet.
+                        if (ephemeral && !cancelled) {
+                            // The duration is the same for the whole hierarchy, so it's safe to
+                            // remove the listener recursively. We do this because some descendant
+                            // views might not change bounds, and therefore not animate and leak the
+                            // listener.
+                            recursivelyRemoveListener(view)
+                        }
+                    }
+
+                    override fun onAnimationCancel(animation: Animator?) {
+                        cancelled = true
                     }
                 }
-
-                override fun onAnimationCancel(animation: Animator?) {
-                    cancelled = true
-                }
-            })
+            )
 
             bounds.forEach { bound -> setBound(view, bound, startValues.getValue(bound)) }
 
@@ -902,7 +979,15 @@
 
     /** An enum used to determine the origin of addition animations. */
     enum class Hotspot {
-        CENTER, LEFT, TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT
+        CENTER,
+        LEFT,
+        TOP_LEFT,
+        TOP,
+        TOP_RIGHT,
+        RIGHT,
+        BOTTOM_RIGHT,
+        BOTTOM,
+        BOTTOM_LEFT
     }
 
     private enum class Bound(val label: String, val overrideTag: Int) {
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
index 76de7b5..77640f1 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
@@ -11,37 +11,36 @@
     /**
      * Synchronize the next draw between the view roots of [view] and [otherView], then run [then].
      *
-     * Note that in some cases, the synchronization might not be possible (e.g. WM consumed the
-     * next transactions) or disabled (temporarily, on low ram devices). In this case, [then] will
-     * be called without synchronizing.
+     * Note that in some cases, the synchronization might not be possible (e.g. WM consumed the next
+     * transactions) or disabled (temporarily, on low ram devices). In this case, [then] will be
+     * called without synchronizing.
      */
-    fun synchronizeNextDraw(
-        view: View,
-        otherView: View,
-        then: () -> Unit
-    ) {
-        if (!view.isAttachedToWindow || view.viewRootImpl == null ||
-            !otherView.isAttachedToWindow || otherView.viewRootImpl == null ||
-            view.viewRootImpl == otherView.viewRootImpl) {
+    fun synchronizeNextDraw(view: View, otherView: View, then: () -> Unit) {
+        if (
+            !view.isAttachedToWindow ||
+                view.viewRootImpl == null ||
+                !otherView.isAttachedToWindow ||
+                otherView.viewRootImpl == null ||
+                view.viewRootImpl == otherView.viewRootImpl
+        ) {
             // No need to synchronize if either the touch surface or dialog view is not attached
             // to a window.
             then()
             return
         }
 
-        surfaceSyncer = SurfaceSyncer().apply {
-            val syncId = setupSync(Runnable { then() })
-            addToSync(syncId, view)
-            addToSync(syncId, otherView)
-            markSyncReady(syncId)
-        }
+        surfaceSyncer =
+            SurfaceSyncer().apply {
+                val syncId = setupSync(Runnable { then() })
+                addToSync(syncId, view)
+                addToSync(syncId, otherView)
+                markSyncReady(syncId)
+            }
     }
 
-    /**
-     * A Java-friendly API for [synchronizeNextDraw].
-     */
+    /** A Java-friendly API for [synchronizeNextDraw]. */
     @JvmStatic
     fun synchronizeNextDraw(view: View, otherView: View, then: Runnable) {
         synchronizeNextDraw(view, otherView, then::run)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/docs/device-entry/doze.md b/packages/SystemUI/docs/device-entry/doze.md
index 5ff8851..6b6dce5 100644
--- a/packages/SystemUI/docs/device-entry/doze.md
+++ b/packages/SystemUI/docs/device-entry/doze.md
@@ -17,6 +17,9 @@
 ### DOZE
 Device is asleep and listening for enabled pulsing and wake-up gesture triggers. In this state, no UI shows.
 
+### DOZE_SUSPEND_TRIGGERS
+Device is asleep and not listening for any triggers to wake up. This state is used only when CAR_MODE is active. In this state, no UI shows.
+
 ### DOZE_AOD
 Device is asleep, showing UI, and listening for enabled pulsing and wake-up triggers. In this state, screen brightness is handled by [DozeScreenBrightness][5] which uses the brightness sensor specified by `doze_brightness_sensor_type` in the [SystemUI config][6]. To save power, this should be a low-powered sensor that shouldn't trigger as often as the light sensor used for on-screen adaptive brightness.
 
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index 3cf7645..eac765a 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -105,6 +105,11 @@
         void setDozeAmount(float amount);
 
         /**
+         * Set the current keyguard bypass enabled status.
+         */
+        default void setKeyguardBypassEnabled(boolean enabled) {}
+
+        /**
          * Overrides how Intents/PendingIntents gets launched. Mostly to support auth from
          * the lockscreen.
          */
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
index 0f10589..bd628cc 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
@@ -29,7 +29,7 @@
 /**
  * Interface that decides whether a touch on the phone was accidental. i.e. Pocket Dialing.
  *
- * {@see com.android.systemui.classifier.FalsingManagerImpl}
+ * {@see com.android.systemui.classifier.BrightLineFalsingManager}
  */
 @ProvidesInterface(version = FalsingManager.VERSION)
 public interface FalsingManager {
diff --git a/packages/SystemUI/res-keyguard/drawable/qs_auto_rotate_icon_off.xml b/packages/SystemUI/res-keyguard/drawable/qs_auto_rotate_icon_off.xml
new file mode 100644
index 0000000..538f328
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/qs_auto_rotate_icon_off.xml
@@ -0,0 +1,725 @@
+<?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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_2_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="7.062"
+                    android:valueTo="8.578"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="221"
+                    android:propertyName="translateX"
+                    android:startOffset="28"
+                    android:valueFrom="8.578"
+                    android:valueTo="-1.789"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="418"
+                    android:propertyName="translateX"
+                    android:startOffset="248"
+                    android:valueFrom="-1.789"
+                    android:valueTo="-7"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="translateY"
+                    android:startOffset="0"
+                    android:valueFrom="3.312"
+                    android:valueTo="2.016"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="221"
+                    android:propertyName="translateY"
+                    android:startOffset="28"
+                    android:valueFrom="2.016"
+                    android:valueTo="-8.789"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="418"
+                    android:propertyName="translateY"
+                    android:startOffset="248"
+                    android:valueFrom="-8.789"
+                    android:valueTo="-3.5"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="180"
+                    android:valueTo="90"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="166"
+                    android:propertyName="rotation"
+                    android:startOffset="28"
+                    android:valueFrom="90"
+                    android:valueTo="90"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="55"
+                    android:propertyName="rotation"
+                    android:startOffset="193"
+                    android:valueFrom="90"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_N_1_T_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="-135"
+                    android:valueTo="-180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="-7"
+                    android:valueTo="-8.859"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="221"
+                    android:propertyName="translateX"
+                    android:startOffset="28"
+                    android:valueFrom="-8.859"
+                    android:valueTo="1.69"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="418"
+                    android:propertyName="translateX"
+                    android:startOffset="248"
+                    android:valueFrom="1.69"
+                    android:valueTo="7"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="translateY"
+                    android:startOffset="0"
+                    android:valueFrom="-3.594"
+                    android:valueTo="-1.922"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="221"
+                    android:propertyName="translateY"
+                    android:startOffset="28"
+                    android:valueFrom="-1.922"
+                    android:valueTo="8.627"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="418"
+                    android:propertyName="translateY"
+                    android:startOffset="248"
+                    android:valueFrom="8.627"
+                    android:valueTo="3.5"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="360"
+                    android:valueTo="270"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="166"
+                    android:propertyName="rotation"
+                    android:startOffset="28"
+                    android:valueFrom="270"
+                    android:valueTo="270"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="55"
+                    android:propertyName="rotation"
+                    android:startOffset="193"
+                    android:valueFrom="270"
+                    android:valueTo="180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="418"
+                    android:propertyName="rotation"
+                    android:startOffset="248"
+                    android:valueFrom="180"
+                    android:valueTo="180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_N_1_T_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="-135"
+                    android:valueTo="-180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M8.52 3.53 C8.52,3.53 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -7.53,0.95 -7.53,0.95 C-7.53,0.95 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 7.11,2.11 7.11,2.11 C7.11,2.11 7.14,2.14 7.14,2.14 C7.14,2.14 8.48,3.49 8.48,3.49 C8.48,3.49 8.5,3.51 8.5,3.51 C8.5,3.51 8.52,3.53 8.52,3.53c "
+                    android:valueTo="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -6.08,2.36 -6.08,2.36 C-6.08,2.36 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 7.49,1.78 7.49,1.78 C7.49,1.78 8.87,0.41 8.87,0.41 C8.87,0.41 8.95,0.5 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="66"
+                    android:propertyName="pathData"
+                    android:startOffset="28"
+                    android:valueFrom="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -6.08,2.36 -6.08,2.36 C-6.08,2.36 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 7.49,1.78 7.49,1.78 C7.49,1.78 8.87,0.41 8.87,0.41 C8.87,0.41 8.95,0.5 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueTo="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -2.78,5.89 -2.78,5.89 C-2.78,5.89 -1.29,4.47 -1.29,4.47 C-1.29,4.47 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="72"
+                    android:propertyName="pathData"
+                    android:startOffset="94"
+                    android:valueFrom="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -2.78,5.89 -2.78,5.89 C-2.78,5.89 -1.29,4.47 -1.29,4.47 C-1.29,4.47 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueTo="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 0.36,8.83 0.36,8.83 C0.36,8.83 1.8,7.44 1.8,7.44 C1.8,7.44 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="pathData"
+                    android:startOffset="166"
+                    android:valueFrom="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 0.36,8.83 0.36,8.83 C0.36,8.83 1.8,7.44 1.8,7.44 C1.8,7.44 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueTo="M8.82 3.18 C8.26,3.74 3.22,8.8 3.22,8.8 C3.22,8.8 3.21,8.79 3.21,8.79 C3.21,8.79 3.24,8.8 3.24,8.8 C3.24,8.8 1.8,7.44 1.8,7.44 C1.8,7.44 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="55"
+                    android:propertyName="pathData"
+                    android:startOffset="193"
+                    android:valueFrom="M8.82 3.18 C8.26,3.74 3.22,8.8 3.22,8.8 C3.22,8.8 3.21,8.79 3.21,8.79 C3.21,8.79 3.24,8.8 3.24,8.8 C3.24,8.8 1.8,7.44 1.8,7.44 C1.8,7.44 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueTo="M8.82 3.18 C8.26,3.74 5.82,6.14 5.82,6.14 C5.82,6.14 5.81,6.14 5.81,6.14 C5.81,6.14 5.83,6.14 5.83,6.14 C5.83,6.14 4.39,4.78 4.39,4.78 C4.39,4.78 4.37,4.76 4.37,4.76 C4.37,4.76 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="41"
+                    android:propertyName="pathData"
+                    android:startOffset="248"
+                    android:valueFrom="M8.82 3.18 C8.26,3.74 5.82,6.14 5.82,6.14 C5.82,6.14 5.81,6.14 5.81,6.14 C5.81,6.14 5.83,6.14 5.83,6.14 C5.83,6.14 4.39,4.78 4.39,4.78 C4.39,4.78 4.37,4.76 4.37,4.76 C4.37,4.76 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueTo="M8.91 3.09 C8.91,3.09 8.91,3.1 8.91,3.1 C8.91,3.1 8.9,3.09 8.9,3.09 C8.9,3.09 7.49,1.74 7.49,1.74 C7.49,1.74 7.5,1.75 7.5,1.75 C7.5,1.75 7.48,1.73 7.48,1.73 C7.48,1.73 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.79,2.2 8.91,3.09c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="pathData"
+                    android:startOffset="290"
+                    android:valueFrom="M8.91 3.09 C8.91,3.09 8.91,3.1 8.91,3.1 C8.91,3.1 8.9,3.09 8.9,3.09 C8.9,3.09 7.49,1.74 7.49,1.74 C7.49,1.74 7.5,1.75 7.5,1.75 C7.5,1.75 7.48,1.73 7.48,1.73 C7.48,1.73 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.79,2.2 8.91,3.09c "
+                    android:valueTo="M9.05 0.57 C9.05,0.57 9.05,0.58 9.05,0.58 C9.05,0.58 9.04,0.57 9.04,0.57 C9.04,0.57 7.6,1.83 7.6,1.83 C7.6,1.83 7.61,1.85 7.61,1.85 C7.61,1.85 7.59,1.83 7.59,1.83 C7.59,1.83 7.61,1.86 7.61,1.86 C7.61,1.86 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 9.05,0.58 9.05,0.58 C9.05,0.58 9.05,0.57 9.05,0.57c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="pathData"
+                    android:startOffset="317"
+                    android:valueFrom="M9.05 0.57 C9.05,0.57 9.05,0.58 9.05,0.58 C9.05,0.58 9.04,0.57 9.04,0.57 C9.04,0.57 7.6,1.83 7.6,1.83 C7.6,1.83 7.61,1.85 7.61,1.85 C7.61,1.85 7.59,1.83 7.59,1.83 C7.59,1.83 7.61,1.86 7.61,1.86 C7.61,1.86 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 9.05,0.58 9.05,0.58 C9.05,0.58 9.05,0.57 9.05,0.57c "
+                    android:valueTo="M5.94 -2.52 C5.94,-2.52 5.94,-2.51 5.94,-2.51 C5.94,-2.51 5.93,-2.52 5.93,-2.52 C5.93,-2.52 4.53,-1.12 4.53,-1.12 C4.53,-1.12 4.55,-1.11 4.55,-1.11 C4.55,-1.11 4.53,-1.13 4.53,-1.13 C4.53,-1.13 4.55,-1.09 4.55,-1.09 C4.55,-1.09 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 5.94,-2.52 5.94,-2.52 C5.94,-2.52 5.94,-2.52 5.94,-2.52c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-8.52 -3.53 C-8.52,-3.53 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 7.53,-0.95 7.53,-0.95 C7.53,-0.95 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.11,-2.11 -7.11,-2.11 C-7.11,-2.11 -7.14,-2.14 -7.14,-2.14 C-7.14,-2.14 -8.48,-3.49 -8.48,-3.49 C-8.48,-3.49 -8.5,-3.51 -8.5,-3.51 C-8.5,-3.51 -8.52,-3.53 -8.52,-3.53c "
+                    android:valueTo="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 6.08,-2.36 6.08,-2.36 C6.08,-2.36 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -7.49,-1.78 -7.49,-1.78 C-7.49,-1.78 -8.87,-0.41 -8.87,-0.41 C-8.87,-0.41 -8.95,-0.5 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="66"
+                    android:propertyName="pathData"
+                    android:startOffset="28"
+                    android:valueFrom="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 6.08,-2.36 6.08,-2.36 C6.08,-2.36 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -7.49,-1.78 -7.49,-1.78 C-7.49,-1.78 -8.87,-0.41 -8.87,-0.41 C-8.87,-0.41 -8.95,-0.5 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueTo="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 2.78,-5.89 2.78,-5.89 C2.78,-5.89 1.29,-4.47 1.29,-4.47 C1.29,-4.47 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="72"
+                    android:propertyName="pathData"
+                    android:startOffset="94"
+                    android:valueFrom="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 2.78,-5.89 2.78,-5.89 C2.78,-5.89 1.29,-4.47 1.29,-4.47 C1.29,-4.47 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueTo="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 -0.36,-8.83 -0.36,-8.83 C-0.36,-8.83 -1.8,-7.44 -1.8,-7.44 C-1.8,-7.44 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="pathData"
+                    android:startOffset="166"
+                    android:valueFrom="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 -0.36,-8.83 -0.36,-8.83 C-0.36,-8.83 -1.8,-7.44 -1.8,-7.44 C-1.8,-7.44 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueTo="M-8.82 -3.18 C-8.26,-3.74 -3.22,-8.8 -3.22,-8.8 C-3.22,-8.8 -3.21,-8.79 -3.21,-8.79 C-3.21,-8.79 -3.24,-8.8 -3.24,-8.8 C-3.24,-8.8 -1.8,-7.44 -1.8,-7.44 C-1.8,-7.44 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="55"
+                    android:propertyName="pathData"
+                    android:startOffset="193"
+                    android:valueFrom="M-8.82 -3.18 C-8.26,-3.74 -3.22,-8.8 -3.22,-8.8 C-3.22,-8.8 -3.21,-8.79 -3.21,-8.79 C-3.21,-8.79 -3.24,-8.8 -3.24,-8.8 C-3.24,-8.8 -1.8,-7.44 -1.8,-7.44 C-1.8,-7.44 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueTo="M-8.82 -3.18 C-8.26,-3.74 -5.81,-6.14 -5.81,-6.14 C-5.81,-6.14 -5.81,-6.13 -5.81,-6.13 C-5.81,-6.13 -5.83,-6.14 -5.83,-6.14 C-5.83,-6.14 -4.39,-4.78 -4.39,-4.78 C-4.39,-4.78 -4.37,-4.76 -4.37,-4.76 C-4.37,-4.76 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="41"
+                    android:propertyName="pathData"
+                    android:startOffset="248"
+                    android:valueFrom="M-8.82 -3.18 C-8.26,-3.74 -5.81,-6.14 -5.81,-6.14 C-5.81,-6.14 -5.81,-6.13 -5.81,-6.13 C-5.81,-6.13 -5.83,-6.14 -5.83,-6.14 C-5.83,-6.14 -4.39,-4.78 -4.39,-4.78 C-4.39,-4.78 -4.37,-4.76 -4.37,-4.76 C-4.37,-4.76 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueTo="M-8.91 -3.09 C-8.91,-3.09 -8.91,-3.09 -8.91,-3.09 C-8.91,-3.09 -8.9,-3.09 -8.9,-3.09 C-8.9,-3.09 -7.49,-1.74 -7.49,-1.74 C-7.49,-1.74 -7.5,-1.75 -7.5,-1.75 C-7.5,-1.75 -7.48,-1.73 -7.48,-1.73 C-7.48,-1.73 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.79,-2.2 -8.91,-3.09c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="pathData"
+                    android:startOffset="290"
+                    android:valueFrom="M-8.91 -3.09 C-8.91,-3.09 -8.91,-3.09 -8.91,-3.09 C-8.91,-3.09 -8.9,-3.09 -8.9,-3.09 C-8.9,-3.09 -7.49,-1.74 -7.49,-1.74 C-7.49,-1.74 -7.5,-1.75 -7.5,-1.75 C-7.5,-1.75 -7.48,-1.73 -7.48,-1.73 C-7.48,-1.73 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.79,-2.2 -8.91,-3.09c "
+                    android:valueTo="M-9.05 -0.57 C-9.05,-0.57 -9.05,-0.58 -9.05,-0.58 C-9.05,-0.58 -9.04,-0.57 -9.04,-0.57 C-9.04,-0.57 -7.59,-1.83 -7.59,-1.83 C-7.59,-1.83 -7.61,-1.85 -7.61,-1.85 C-7.61,-1.85 -7.59,-1.83 -7.59,-1.83 C-7.59,-1.83 -7.61,-1.86 -7.61,-1.86 C-7.61,-1.86 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -9.05,-0.58 -9.05,-0.58 C-9.05,-0.58 -9.05,-0.57 -9.05,-0.57c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="83"
+                    android:propertyName="pathData"
+                    android:startOffset="317"
+                    android:valueFrom="M-9.05 -0.57 C-9.05,-0.57 -9.05,-0.58 -9.05,-0.58 C-9.05,-0.58 -9.04,-0.57 -9.04,-0.57 C-9.04,-0.57 -7.59,-1.83 -7.59,-1.83 C-7.59,-1.83 -7.61,-1.85 -7.61,-1.85 C-7.61,-1.85 -7.59,-1.83 -7.59,-1.83 C-7.59,-1.83 -7.61,-1.86 -7.61,-1.86 C-7.61,-1.86 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -9.05,-0.58 -9.05,-0.58 C-9.05,-0.58 -9.05,-0.57 -9.05,-0.57c "
+                    android:valueTo="M-5.94 2.52 C-5.94,2.52 -5.94,2.51 -5.94,2.51 C-5.94,2.51 -5.93,2.52 -5.93,2.52 C-5.93,2.52 -4.53,1.12 -4.53,1.12 C-4.53,1.12 -4.55,1.11 -4.55,1.11 C-4.55,1.11 -4.53,1.13 -4.53,1.13 C-4.53,1.13 -4.55,1.09 -4.55,1.09 C-4.55,1.09 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -5.94,2.52 -5.94,2.52 C-5.94,2.52 -5.94,2.52 -5.94,2.52c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="61"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M7.54 -0.94 C7.54,-0.94 7.54,-0.95 7.54,-0.95 C7.55,-0.94 7.54,-0.94 7.55,-0.94 C7.55,-0.94 7.53,-0.94 7.53,-0.94 C7.53,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94 C7.54,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94c "
+                    android:valueTo="M7.54 -0.94 C7.54,-0.94 7.54,-0.95 7.54,-0.95 C7.55,-0.94 7.54,-0.94 7.55,-0.94 C7.55,-0.94 7.53,-0.94 7.53,-0.94 C7.53,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94 C7.54,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="pathData"
+                    android:startOffset="61"
+                    android:valueFrom="M7.54 -0.94 C7.54,-0.94 7.54,-0.95 7.54,-0.95 C7.55,-0.94 7.54,-0.94 7.55,-0.94 C7.55,-0.94 7.53,-0.94 7.53,-0.94 C7.53,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94 C7.54,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94c "
+                    android:valueTo="M6.15 -2.35 C6.15,-2.35 6.15,-2.35 6.15,-2.35 C6.16,-2.34 6.15,-2.35 6.16,-2.35 C6.16,-2.35 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 4.72,-0.93 4.72,-0.93 C4.72,-0.93 4.7,-0.94 4.7,-0.94 C4.7,-0.94 6.15,-2.35 6.15,-2.35c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="143"
+                    android:propertyName="pathData"
+                    android:startOffset="88"
+                    android:valueFrom="M6.15 -2.35 C6.15,-2.35 6.15,-2.35 6.15,-2.35 C6.16,-2.34 6.15,-2.35 6.16,-2.35 C6.16,-2.35 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 4.72,-0.93 4.72,-0.93 C4.72,-0.93 4.7,-0.94 4.7,-0.94 C4.7,-0.94 6.15,-2.35 6.15,-2.35c "
+                    android:valueTo="M-0.65 -9.12 C-0.65,-9.12 -0.66,-9.13 -0.66,-9.13 C-0.65,-9.12 -0.66,-9.12 -0.65,-9.12 C-0.65,-9.12 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -1.8,-7.43 -1.8,-7.43 C-1.8,-7.43 -0.65,-9.12 -0.65,-9.12c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="232"
+                    android:valueFrom="M-0.65 -9.12 C-0.65,-9.12 -0.66,-9.13 -0.66,-9.13 C-0.65,-9.12 -0.66,-9.12 -0.65,-9.12 C-0.65,-9.12 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -1.8,-7.43 -1.8,-7.43 C-1.8,-7.43 -0.65,-9.12 -0.65,-9.12c "
+                    android:valueTo="M-3.21 -8.85 C-3.21,-8.85 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -1.8,-7.43 -1.8,-7.43 C-1.8,-7.43 -3.21,-8.85 -3.21,-8.85c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="418"
+                    android:propertyName="pathData"
+                    android:startOffset="248"
+                    android:valueFrom="M-3.21 -8.85 C-3.21,-8.85 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -1.8,-7.43 -1.8,-7.43 C-1.8,-7.43 -3.21,-8.85 -3.21,-8.85c "
+                    android:valueTo="M-8.52 -3.53 C-8.52,-3.53 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.11,-2.11 -7.11,-2.11 C-7.11,-2.11 -8.52,-3.53 -8.52,-3.53c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_3_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="61"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-7.54 0.94 C-7.54,0.94 -7.54,0.95 -7.54,0.95 C-7.55,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94c "
+                    android:valueTo="M-7.54 0.94 C-7.54,0.94 -7.54,0.95 -7.54,0.95 C-7.55,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="28"
+                    android:propertyName="pathData"
+                    android:startOffset="61"
+                    android:valueFrom="M-7.54 0.94 C-7.54,0.94 -7.54,0.95 -7.54,0.95 C-7.55,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94c "
+                    android:valueTo="M-6.15 2.35 C-6.15,2.35 -6.15,2.35 -6.15,2.35 C-6.16,2.34 -6.15,2.35 -6.15,2.35 C-6.15,2.35 -6.14,2.36 -6.14,2.36 C-6.14,2.36 -4.7,0.94 -4.7,0.94 C-4.7,0.94 -4.72,0.93 -4.72,0.93 C-4.72,0.93 -4.7,0.94 -4.7,0.94 C-4.7,0.94 -6.15,2.35 -6.15,2.35c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="143"
+                    android:propertyName="pathData"
+                    android:startOffset="88"
+                    android:valueFrom="M-6.15 2.35 C-6.15,2.35 -6.15,2.35 -6.15,2.35 C-6.16,2.34 -6.15,2.35 -6.15,2.35 C-6.15,2.35 -6.14,2.36 -6.14,2.36 C-6.14,2.36 -4.7,0.94 -4.7,0.94 C-4.7,0.94 -4.72,0.93 -4.72,0.93 C-4.72,0.93 -4.7,0.94 -4.7,0.94 C-4.7,0.94 -6.15,2.35 -6.15,2.35c "
+                    android:valueTo="M0.65 9.12 C0.65,9.12 0.66,9.13 0.66,9.13 C0.65,9.12 0.66,9.13 0.65,9.12 C0.65,9.12 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 1.8,7.43 1.8,7.43 C1.8,7.43 0.65,9.12 0.65,9.12c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="232"
+                    android:valueFrom="M0.65 9.12 C0.65,9.12 0.66,9.13 0.66,9.13 C0.65,9.12 0.66,9.13 0.65,9.12 C0.65,9.12 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 1.8,7.43 1.8,7.43 C1.8,7.43 0.65,9.12 0.65,9.12c "
+                    android:valueTo="M3.21 8.85 C3.21,8.85 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 1.8,7.43 1.8,7.43 C1.8,7.43 3.21,8.85 3.21,8.85c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="418"
+                    android:propertyName="pathData"
+                    android:startOffset="248"
+                    android:valueFrom="M3.21 8.85 C3.21,8.85 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 1.8,7.43 1.8,7.43 C1.8,7.43 3.21,8.85 3.21,8.85c "
+                    android:valueTo="M8.52 3.53 C8.52,3.53 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 7.11,2.11 7.11,2.11 C7.11,2.11 8.52,3.53 8.52,3.53c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="-135"
+                    android:valueTo="-180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="683"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_2_G_N_1_T_0"
+                    android:rotation="-135"
+                    android:translateX="12.008"
+                    android:translateY="11.992">
+                    <group
+                        android:name="_R_G_L_2_G_T_1"
+                        android:rotation="180"
+                        android:translateX="7.062"
+                        android:translateY="3.312">
+                        <group
+                            android:name="_R_G_L_2_G"
+                            android:translateX="6.984"
+                            android:translateY="3.547">
+                            <path
+                                android:name="_R_G_L_2_G_D_0_P_0"
+                                android:fillAlpha="1"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M-4.6 -1.06 C-4.6,-1.06 -9.55,-1.06 -9.55,-1.06 C-9.55,-1.06 -9.55,-6.01 -9.55,-6.01 C-9.55,-6.01 -7.55,-6 -7.55,-6 C-7.55,-6 -7.51,-3.04 -7.51,-3.04 C-7.51,-3.04 -4.6,-3.05 -4.6,-3.05 C-4.6,-3.05 -4.6,-1.06 -4.6,-1.06c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_1_G_N_1_T_0"
+                    android:rotation="-135"
+                    android:translateX="12.008"
+                    android:translateY="11.992">
+                    <group
+                        android:name="_R_G_L_1_G_T_1"
+                        android:rotation="360"
+                        android:translateX="-7"
+                        android:translateY="-3.594">
+                        <group
+                            android:name="_R_G_L_1_G"
+                            android:translateX="6.984"
+                            android:translateY="3.547">
+                            <path
+                                android:name="_R_G_L_1_G_D_0_P_0"
+                                android:fillAlpha="1"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M-4.6 -1.06 C-4.6,-1.06 -9.55,-1.06 -9.55,-1.06 C-9.55,-1.06 -9.55,-6.01 -9.55,-6.01 C-9.55,-6.01 -7.55,-6 -7.55,-6 C-7.55,-6 -7.51,-3.04 -7.51,-3.04 C-7.51,-3.04 -4.6,-3.05 -4.6,-3.05 C-4.6,-3.05 -4.6,-1.06 -4.6,-1.06c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:rotation="-135"
+                    android:translateX="12.008"
+                    android:translateY="11.992">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M8.52 3.53 C8.52,3.53 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -7.53,0.95 -7.53,0.95 C-7.53,0.95 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 7.11,2.11 7.11,2.11 C7.11,2.11 7.14,2.14 7.14,2.14 C7.14,2.14 8.48,3.49 8.48,3.49 C8.48,3.49 8.5,3.51 8.5,3.51 C8.5,3.51 8.52,3.53 8.52,3.53c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-8.52 -3.53 C-8.52,-3.53 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 7.53,-0.95 7.53,-0.95 C7.53,-0.95 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.11,-2.11 -7.11,-2.11 C-7.11,-2.11 -7.14,-2.14 -7.14,-2.14 C-7.14,-2.14 -8.48,-3.49 -8.48,-3.49 C-8.48,-3.49 -8.5,-3.51 -8.5,-3.51 C-8.5,-3.51 -8.52,-3.53 -8.52,-3.53c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M7.54 -0.94 C7.54,-0.94 7.54,-0.95 7.54,-0.95 C7.55,-0.94 7.54,-0.94 7.55,-0.94 C7.55,-0.94 7.53,-0.94 7.53,-0.94 C7.53,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94 C7.54,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_3_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-7.54 0.94 C-7.54,0.94 -7.54,0.95 -7.54,0.95 C-7.55,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/qs_auto_rotate_icon_on.xml b/packages/SystemUI/res-keyguard/drawable/qs_auto_rotate_icon_on.xml
new file mode 100644
index 0000000..bd67d9f
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/qs_auto_rotate_icon_on.xml
@@ -0,0 +1,781 @@
+<?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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_2_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="367"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="367"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M8.52 3.53 C8.52,3.53 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -7.53,0.95 -7.53,0.95 C-7.53,0.95 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 7.11,2.11 7.11,2.11 C7.11,2.11 7.14,2.14 7.14,2.14 C7.14,2.14 8.48,3.49 8.48,3.49 C8.48,3.49 8.5,3.51 8.5,3.51 C8.5,3.51 8.52,3.53 8.52,3.53c "
+                    android:valueTo="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -6.08,2.36 -6.08,2.36 C-6.08,2.36 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 7.49,1.78 7.49,1.78 C7.49,1.78 8.87,0.41 8.87,0.41 C8.87,0.41 8.95,0.5 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="41"
+                    android:propertyName="pathData"
+                    android:startOffset="17"
+                    android:valueFrom="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -6.08,2.36 -6.08,2.36 C-6.08,2.36 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 7.49,1.78 7.49,1.78 C7.49,1.78 8.87,0.41 8.87,0.41 C8.87,0.41 8.95,0.5 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueTo="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -2.78,5.89 -2.78,5.89 C-2.78,5.89 -1.29,4.47 -1.29,4.47 C-1.29,4.47 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="45"
+                    android:propertyName="pathData"
+                    android:startOffset="59"
+                    android:valueFrom="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -2.78,5.89 -2.78,5.89 C-2.78,5.89 -1.29,4.47 -1.29,4.47 C-1.29,4.47 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueTo="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 0.36,8.83 0.36,8.83 C0.36,8.83 1.8,7.44 1.8,7.44 C1.8,7.44 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="103"
+                    android:valueFrom="M8.82 3.18 C8.26,3.74 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 0.36,8.83 0.36,8.83 C0.36,8.83 1.8,7.44 1.8,7.44 C1.8,7.44 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueTo="M8.82 3.18 C8.26,3.74 3.22,8.8 3.22,8.8 C3.22,8.8 3.21,8.79 3.21,8.79 C3.21,8.79 3.24,8.8 3.24,8.8 C3.24,8.8 1.8,7.44 1.8,7.44 C1.8,7.44 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="34"
+                    android:propertyName="pathData"
+                    android:startOffset="121"
+                    android:valueFrom="M8.82 3.18 C8.26,3.74 3.22,8.8 3.22,8.8 C3.22,8.8 3.21,8.79 3.21,8.79 C3.21,8.79 3.24,8.8 3.24,8.8 C3.24,8.8 1.8,7.44 1.8,7.44 C1.8,7.44 1.78,7.42 1.78,7.42 C1.78,7.42 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueTo="M8.82 3.18 C8.26,3.74 5.82,6.14 5.82,6.14 C5.82,6.14 5.81,6.14 5.81,6.14 C5.81,6.14 5.83,6.14 5.83,6.14 C5.83,6.14 4.39,4.78 4.39,4.78 C4.39,4.78 4.37,4.76 4.37,4.76 C4.37,4.76 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="26"
+                    android:propertyName="pathData"
+                    android:startOffset="155"
+                    android:valueFrom="M8.82 3.18 C8.26,3.74 5.82,6.14 5.82,6.14 C5.82,6.14 5.81,6.14 5.81,6.14 C5.81,6.14 5.83,6.14 5.83,6.14 C5.83,6.14 4.39,4.78 4.39,4.78 C4.39,4.78 4.37,4.76 4.37,4.76 C4.37,4.76 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.7,2.29 8.82,3.18c "
+                    android:valueTo="M8.91 3.09 C8.91,3.09 8.91,3.1 8.91,3.1 C8.91,3.1 8.9,3.09 8.9,3.09 C8.9,3.09 7.49,1.74 7.49,1.74 C7.49,1.74 7.5,1.75 7.5,1.75 C7.5,1.75 7.48,1.73 7.48,1.73 C7.48,1.73 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.79,2.2 8.91,3.09c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="181"
+                    android:valueFrom="M8.91 3.09 C8.91,3.09 8.91,3.1 8.91,3.1 C8.91,3.1 8.9,3.09 8.9,3.09 C8.9,3.09 7.49,1.74 7.49,1.74 C7.49,1.74 7.5,1.75 7.5,1.75 C7.5,1.75 7.48,1.73 7.48,1.73 C7.48,1.73 7.5,1.77 7.5,1.77 C7.5,1.77 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 8.36,-0.12 9.05,0.58 C9.86,1.4 9.79,2.2 8.91,3.09c "
+                    android:valueTo="M9.05 0.57 C9.05,0.57 9.05,0.58 9.05,0.58 C9.05,0.58 9.04,0.57 9.04,0.57 C9.04,0.57 7.6,1.83 7.6,1.83 C7.6,1.83 7.61,1.85 7.61,1.85 C7.61,1.85 7.59,1.83 7.59,1.83 C7.59,1.83 7.61,1.86 7.61,1.86 C7.61,1.86 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 9.05,0.58 9.05,0.58 C9.05,0.58 9.05,0.57 9.05,0.57c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="52"
+                    android:propertyName="pathData"
+                    android:startOffset="198"
+                    android:valueFrom="M9.05 0.57 C9.05,0.57 9.05,0.58 9.05,0.58 C9.05,0.58 9.04,0.57 9.04,0.57 C9.04,0.57 7.6,1.83 7.6,1.83 C7.6,1.83 7.61,1.85 7.61,1.85 C7.61,1.85 7.59,1.83 7.59,1.83 C7.59,1.83 7.61,1.86 7.61,1.86 C7.61,1.86 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 9.05,0.58 9.05,0.58 C9.05,0.58 9.05,0.57 9.05,0.57c "
+                    android:valueTo="M5.94 -2.52 C5.94,-2.52 5.94,-2.51 5.94,-2.51 C5.94,-2.51 5.93,-2.52 5.93,-2.52 C5.93,-2.52 4.53,-1.12 4.53,-1.12 C4.53,-1.12 4.55,-1.11 4.55,-1.11 C4.55,-1.11 4.53,-1.13 4.53,-1.13 C4.53,-1.13 4.55,-1.09 4.55,-1.09 C4.55,-1.09 4.54,-1.11 4.54,-1.11 C4.54,-1.11 5.95,-2.51 5.95,-2.51 C5.95,-2.51 5.94,-2.52 5.94,-2.52 C5.94,-2.52 5.94,-2.52 5.94,-2.52c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="367"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="367"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-8.52 -3.53 C-8.52,-3.53 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 7.53,-0.95 7.53,-0.95 C7.53,-0.95 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.11,-2.11 -7.11,-2.11 C-7.11,-2.11 -7.14,-2.14 -7.14,-2.14 C-7.14,-2.14 -8.48,-3.49 -8.48,-3.49 C-8.48,-3.49 -8.5,-3.51 -8.5,-3.51 C-8.5,-3.51 -8.52,-3.53 -8.52,-3.53c "
+                    android:valueTo="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 6.08,-2.36 6.08,-2.36 C6.08,-2.36 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -7.49,-1.78 -7.49,-1.78 C-7.49,-1.78 -8.87,-0.41 -8.87,-0.41 C-8.87,-0.41 -8.95,-0.5 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="41"
+                    android:propertyName="pathData"
+                    android:startOffset="17"
+                    android:valueFrom="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 6.08,-2.36 6.08,-2.36 C6.08,-2.36 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -7.49,-1.78 -7.49,-1.78 C-7.49,-1.78 -8.87,-0.41 -8.87,-0.41 C-8.87,-0.41 -8.95,-0.5 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueTo="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 2.78,-5.89 2.78,-5.89 C2.78,-5.89 1.29,-4.47 1.29,-4.47 C1.29,-4.47 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="45"
+                    android:propertyName="pathData"
+                    android:startOffset="59"
+                    android:valueFrom="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 2.78,-5.89 2.78,-5.89 C2.78,-5.89 1.29,-4.47 1.29,-4.47 C1.29,-4.47 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueTo="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 -0.36,-8.83 -0.36,-8.83 C-0.36,-8.83 -1.8,-7.44 -1.8,-7.44 C-1.8,-7.44 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="103"
+                    android:valueFrom="M-8.82 -3.18 C-8.26,-3.74 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 -0.36,-8.83 -0.36,-8.83 C-0.36,-8.83 -1.8,-7.44 -1.8,-7.44 C-1.8,-7.44 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueTo="M-8.82 -3.18 C-8.26,-3.74 -3.22,-8.8 -3.22,-8.8 C-3.22,-8.8 -3.21,-8.79 -3.21,-8.79 C-3.21,-8.79 -3.24,-8.8 -3.24,-8.8 C-3.24,-8.8 -1.8,-7.44 -1.8,-7.44 C-1.8,-7.44 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="34"
+                    android:propertyName="pathData"
+                    android:startOffset="121"
+                    android:valueFrom="M-8.82 -3.18 C-8.26,-3.74 -3.22,-8.8 -3.22,-8.8 C-3.22,-8.8 -3.21,-8.79 -3.21,-8.79 C-3.21,-8.79 -3.24,-8.8 -3.24,-8.8 C-3.24,-8.8 -1.8,-7.44 -1.8,-7.44 C-1.8,-7.44 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueTo="M-8.82 -3.18 C-8.26,-3.74 -5.81,-6.14 -5.81,-6.14 C-5.81,-6.14 -5.81,-6.13 -5.81,-6.13 C-5.81,-6.13 -5.83,-6.14 -5.83,-6.14 C-5.83,-6.14 -4.39,-4.78 -4.39,-4.78 C-4.39,-4.78 -4.37,-4.76 -4.37,-4.76 C-4.37,-4.76 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="26"
+                    android:propertyName="pathData"
+                    android:startOffset="155"
+                    android:valueFrom="M-8.82 -3.18 C-8.26,-3.74 -5.81,-6.14 -5.81,-6.14 C-5.81,-6.14 -5.81,-6.13 -5.81,-6.13 C-5.81,-6.13 -5.83,-6.14 -5.83,-6.14 C-5.83,-6.14 -4.39,-4.78 -4.39,-4.78 C-4.39,-4.78 -4.37,-4.76 -4.37,-4.76 C-4.37,-4.76 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.7,-2.29 -8.82,-3.18c "
+                    android:valueTo="M-8.91 -3.09 C-8.91,-3.09 -8.91,-3.09 -8.91,-3.09 C-8.91,-3.09 -8.9,-3.09 -8.9,-3.09 C-8.9,-3.09 -7.49,-1.74 -7.49,-1.74 C-7.49,-1.74 -7.5,-1.75 -7.5,-1.75 C-7.5,-1.75 -7.48,-1.73 -7.48,-1.73 C-7.48,-1.73 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.79,-2.2 -8.91,-3.09c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="181"
+                    android:valueFrom="M-8.91 -3.09 C-8.91,-3.09 -8.91,-3.09 -8.91,-3.09 C-8.91,-3.09 -8.9,-3.09 -8.9,-3.09 C-8.9,-3.09 -7.49,-1.74 -7.49,-1.74 C-7.49,-1.74 -7.5,-1.75 -7.5,-1.75 C-7.5,-1.75 -7.48,-1.73 -7.48,-1.73 C-7.48,-1.73 -7.5,-1.77 -7.5,-1.77 C-7.5,-1.77 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -8.36,0.12 -9.05,-0.58 C-9.86,-1.4 -9.79,-2.2 -8.91,-3.09c "
+                    android:valueTo="M-9.05 -0.57 C-9.05,-0.57 -9.05,-0.58 -9.05,-0.58 C-9.05,-0.58 -9.04,-0.57 -9.04,-0.57 C-9.04,-0.57 -7.59,-1.83 -7.59,-1.83 C-7.59,-1.83 -7.61,-1.85 -7.61,-1.85 C-7.61,-1.85 -7.59,-1.83 -7.59,-1.83 C-7.59,-1.83 -7.61,-1.86 -7.61,-1.86 C-7.61,-1.86 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -9.05,-0.58 -9.05,-0.58 C-9.05,-0.58 -9.05,-0.57 -9.05,-0.57c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="52"
+                    android:propertyName="pathData"
+                    android:startOffset="198"
+                    android:valueFrom="M-9.05 -0.57 C-9.05,-0.57 -9.05,-0.58 -9.05,-0.58 C-9.05,-0.58 -9.04,-0.57 -9.04,-0.57 C-9.04,-0.57 -7.59,-1.83 -7.59,-1.83 C-7.59,-1.83 -7.61,-1.85 -7.61,-1.85 C-7.61,-1.85 -7.59,-1.83 -7.59,-1.83 C-7.59,-1.83 -7.61,-1.86 -7.61,-1.86 C-7.61,-1.86 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -9.05,-0.58 -9.05,-0.58 C-9.05,-0.58 -9.05,-0.57 -9.05,-0.57c "
+                    android:valueTo="M-5.94 2.52 C-5.94,2.52 -5.94,2.51 -5.94,2.51 C-5.94,2.51 -5.93,2.52 -5.93,2.52 C-5.93,2.52 -4.53,1.12 -4.53,1.12 C-4.53,1.12 -4.55,1.11 -4.55,1.11 C-4.55,1.11 -4.53,1.13 -4.53,1.13 C-4.53,1.13 -4.55,1.09 -4.55,1.09 C-4.55,1.09 -4.54,1.11 -4.54,1.11 C-4.54,1.11 -5.95,2.51 -5.95,2.51 C-5.95,2.51 -5.94,2.52 -5.94,2.52 C-5.94,2.52 -5.94,2.52 -5.94,2.52c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="38"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M7.54 -0.94 C7.54,-0.94 7.54,-0.95 7.54,-0.95 C7.55,-0.94 7.54,-0.94 7.55,-0.94 C7.55,-0.94 7.53,-0.94 7.53,-0.94 C7.53,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94 C7.54,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94c "
+                    android:valueTo="M7.54 -0.94 C7.54,-0.94 7.54,-0.95 7.54,-0.95 C7.55,-0.94 7.54,-0.94 7.55,-0.94 C7.55,-0.94 7.53,-0.94 7.53,-0.94 C7.53,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94 C7.54,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="38"
+                    android:valueFrom="M7.54 -0.94 C7.54,-0.94 7.54,-0.95 7.54,-0.95 C7.55,-0.94 7.54,-0.94 7.55,-0.94 C7.55,-0.94 7.53,-0.94 7.53,-0.94 C7.53,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94 C7.54,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94c "
+                    android:valueTo="M6.15 -2.35 C6.15,-2.35 6.15,-2.35 6.15,-2.35 C6.16,-2.34 6.15,-2.35 6.16,-2.35 C6.16,-2.35 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 4.72,-0.93 4.72,-0.93 C4.72,-0.93 4.7,-0.94 4.7,-0.94 C4.7,-0.94 6.15,-2.35 6.15,-2.35c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="90"
+                    android:propertyName="pathData"
+                    android:startOffset="55"
+                    android:valueFrom="M6.15 -2.35 C6.15,-2.35 6.15,-2.35 6.15,-2.35 C6.16,-2.34 6.15,-2.35 6.16,-2.35 C6.16,-2.35 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 4.72,-0.93 4.72,-0.93 C4.72,-0.93 4.7,-0.94 4.7,-0.94 C4.7,-0.94 6.15,-2.35 6.15,-2.35c "
+                    android:valueTo="M-0.65 -9.12 C-0.65,-9.12 -0.66,-9.13 -0.66,-9.13 C-0.65,-9.12 -0.66,-9.12 -0.65,-9.12 C-0.65,-9.12 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -1.8,-7.43 -1.8,-7.43 C-1.8,-7.43 -0.65,-9.12 -0.65,-9.12c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="10"
+                    android:propertyName="pathData"
+                    android:startOffset="145"
+                    android:valueFrom="M-0.65 -9.12 C-0.65,-9.12 -0.66,-9.13 -0.66,-9.13 C-0.65,-9.12 -0.66,-9.12 -0.65,-9.12 C-0.65,-9.12 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -1.8,-7.43 -1.8,-7.43 C-1.8,-7.43 -0.65,-9.12 -0.65,-9.12c "
+                    android:valueTo="M-3.21 -8.85 C-3.21,-8.85 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -1.8,-7.43 -1.8,-7.43 C-1.8,-7.43 -3.21,-8.85 -3.21,-8.85c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="261"
+                    android:propertyName="pathData"
+                    android:startOffset="155"
+                    android:valueFrom="M-3.21 -8.85 C-3.21,-8.85 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -1.8,-7.43 -1.8,-7.43 C-1.8,-7.43 -3.21,-8.85 -3.21,-8.85c "
+                    android:valueTo="M-8.52 -3.53 C-8.52,-3.53 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 7.53,-0.94 7.53,-0.94 C7.53,-0.94 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.11,-2.11 -7.11,-2.11 C-7.11,-2.11 -8.52,-3.53 -8.52,-3.53c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G_D_3_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="38"
+                    android:propertyName="pathData"
+                    android:startOffset="0"
+                    android:valueFrom="M-7.54 0.94 C-7.54,0.94 -7.54,0.95 -7.54,0.95 C-7.55,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94c "
+                    android:valueTo="M-7.54 0.94 C-7.54,0.94 -7.54,0.95 -7.54,0.95 C-7.55,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="pathData"
+                    android:startOffset="38"
+                    android:valueFrom="M-7.54 0.94 C-7.54,0.94 -7.54,0.95 -7.54,0.95 C-7.55,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94c "
+                    android:valueTo="M-6.15 2.35 C-6.15,2.35 -6.15,2.35 -6.15,2.35 C-6.16,2.34 -6.15,2.35 -6.15,2.35 C-6.15,2.35 -6.14,2.36 -6.14,2.36 C-6.14,2.36 -4.7,0.94 -4.7,0.94 C-4.7,0.94 -4.72,0.93 -4.72,0.93 C-4.72,0.93 -4.7,0.94 -4.7,0.94 C-4.7,0.94 -6.15,2.35 -6.15,2.35c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="90"
+                    android:propertyName="pathData"
+                    android:startOffset="55"
+                    android:valueFrom="M-6.15 2.35 C-6.15,2.35 -6.15,2.35 -6.15,2.35 C-6.16,2.34 -6.15,2.35 -6.15,2.35 C-6.15,2.35 -6.14,2.36 -6.14,2.36 C-6.14,2.36 -4.7,0.94 -4.7,0.94 C-4.7,0.94 -4.72,0.93 -4.72,0.93 C-4.72,0.93 -4.7,0.94 -4.7,0.94 C-4.7,0.94 -6.15,2.35 -6.15,2.35c "
+                    android:valueTo="M0.65 9.12 C0.65,9.12 0.66,9.13 0.66,9.13 C0.65,9.12 0.66,9.13 0.65,9.12 C0.65,9.12 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 1.8,7.43 1.8,7.43 C1.8,7.43 0.65,9.12 0.65,9.12c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="10"
+                    android:propertyName="pathData"
+                    android:startOffset="145"
+                    android:valueFrom="M0.65 9.12 C0.65,9.12 0.66,9.13 0.66,9.13 C0.65,9.12 0.66,9.13 0.65,9.12 C0.65,9.12 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 1.8,7.43 1.8,7.43 C1.8,7.43 0.65,9.12 0.65,9.12c "
+                    android:valueTo="M3.21 8.85 C3.21,8.85 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 1.8,7.43 1.8,7.43 C1.8,7.43 3.21,8.85 3.21,8.85c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="261"
+                    android:propertyName="pathData"
+                    android:startOffset="155"
+                    android:valueFrom="M3.21 8.85 C3.21,8.85 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 1.8,7.43 1.8,7.43 C1.8,7.43 3.21,8.85 3.21,8.85c "
+                    android:valueTo="M8.52 3.53 C8.52,3.53 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 7.11,2.11 7.11,2.11 C7.11,2.11 8.52,3.53 8.52,3.53c "
+                    android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="367"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="-135"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="-7"
+                    android:valueTo="-8.859"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="138"
+                    android:propertyName="translateX"
+                    android:startOffset="17"
+                    android:valueFrom="-8.859"
+                    android:valueTo="1.734"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="261"
+                    android:propertyName="translateX"
+                    android:startOffset="155"
+                    android:valueFrom="1.734"
+                    android:valueTo="7"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="translateY"
+                    android:startOffset="0"
+                    android:valueFrom="-3.594"
+                    android:valueTo="-1.922"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="138"
+                    android:propertyName="translateY"
+                    android:startOffset="17"
+                    android:valueFrom="-1.922"
+                    android:valueTo="8.671"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="261"
+                    android:propertyName="translateY"
+                    android:startOffset="155"
+                    android:valueFrom="8.671"
+                    android:valueTo="3.5"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="360"
+                    android:valueTo="270"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="103"
+                    android:propertyName="rotation"
+                    android:startOffset="17"
+                    android:valueFrom="270"
+                    android:valueTo="270"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="34"
+                    android:propertyName="rotation"
+                    android:startOffset="121"
+                    android:valueFrom="270"
+                    android:valueTo="180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="261"
+                    android:propertyName="rotation"
+                    android:startOffset="155"
+                    android:valueFrom="180"
+                    android:valueTo="180"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_N_3_T_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="367"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="-135"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="7.062"
+                    android:valueTo="8.578"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="138"
+                    android:propertyName="translateX"
+                    android:startOffset="17"
+                    android:valueFrom="8.578"
+                    android:valueTo="-1.656"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="261"
+                    android:propertyName="translateX"
+                    android:startOffset="155"
+                    android:valueFrom="-1.656"
+                    android:valueTo="-7"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="translateY"
+                    android:startOffset="0"
+                    android:valueFrom="3.312"
+                    android:valueTo="2.016"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="138"
+                    android:propertyName="translateY"
+                    android:startOffset="17"
+                    android:valueFrom="2.016"
+                    android:valueTo="-8.656"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="261"
+                    android:propertyName="translateY"
+                    android:startOffset="155"
+                    android:valueFrom="-8.656"
+                    android:valueTo="-3.5"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.1,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="17"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="180"
+                    android:valueTo="90"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="103"
+                    android:propertyName="rotation"
+                    android:startOffset="17"
+                    android:valueFrom="90"
+                    android:valueTo="90"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="34"
+                    android:propertyName="rotation"
+                    android:startOffset="121"
+                    android:valueFrom="90"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_N_3_T_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="367"
+                    android:propertyName="rotation"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="-135"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="433"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_2_G"
+                    android:rotation="0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_2_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M8.52 3.53 C8.52,3.53 2.94,9.08 2.94,9.08 C2.3,9.72 1.27,9.74 0.65,9.12 C0.65,9.12 -7.53,0.95 -7.53,0.95 C-7.53,0.95 -4.7,0.94 -4.7,0.94 C-4.7,0.94 1.78,7.42 1.78,7.42 C1.78,7.42 7.11,2.11 7.11,2.11 C7.11,2.11 7.14,2.14 7.14,2.14 C7.14,2.14 8.48,3.49 8.48,3.49 C8.48,3.49 8.5,3.51 8.5,3.51 C8.5,3.51 8.52,3.53 8.52,3.53c " />
+                    <path
+                        android:name="_R_G_L_2_G_D_1_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-8.52 -3.53 C-8.52,-3.53 -2.94,-9.08 -2.94,-9.08 C-2.3,-9.72 -1.27,-9.74 -0.65,-9.12 C-0.65,-9.12 7.53,-0.95 7.53,-0.95 C7.53,-0.95 4.7,-0.94 4.7,-0.94 C4.7,-0.94 -1.78,-7.42 -1.78,-7.42 C-1.78,-7.42 -7.11,-2.11 -7.11,-2.11 C-7.11,-2.11 -7.14,-2.14 -7.14,-2.14 C-7.14,-2.14 -8.48,-3.49 -8.48,-3.49 C-8.48,-3.49 -8.5,-3.51 -8.5,-3.51 C-8.5,-3.51 -8.52,-3.53 -8.52,-3.53c " />
+                    <path
+                        android:name="_R_G_L_2_G_D_2_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M7.54 -0.94 C7.54,-0.94 7.54,-0.95 7.54,-0.95 C7.55,-0.94 7.54,-0.94 7.55,-0.94 C7.55,-0.94 7.53,-0.94 7.53,-0.94 C7.53,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94 C7.54,-0.94 7.52,-0.94 7.52,-0.94 C7.52,-0.94 7.54,-0.94 7.54,-0.94c " />
+                    <path
+                        android:name="_R_G_L_2_G_D_3_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-7.54 0.94 C-7.54,0.94 -7.54,0.95 -7.54,0.95 C-7.55,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.53,0.94 -7.53,0.94 C-7.53,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94 C-7.54,0.94 -7.52,0.94 -7.52,0.94 C-7.52,0.94 -7.54,0.94 -7.54,0.94c " />
+                </group>
+                <group
+                    android:name="_R_G_L_1_G_N_3_T_0"
+                    android:rotation="0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_1_G_T_1"
+                        android:rotation="360"
+                        android:translateX="-7"
+                        android:translateY="-3.594">
+                        <group
+                            android:name="_R_G_L_1_G"
+                            android:translateX="6.984"
+                            android:translateY="3.547">
+                            <path
+                                android:name="_R_G_L_1_G_D_0_P_0"
+                                android:fillAlpha="1"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M-4.6 -1.06 C-4.6,-1.06 -9.55,-1.06 -9.55,-1.06 C-9.55,-1.06 -9.55,-6.01 -9.55,-6.01 C-9.55,-6.01 -7.55,-6 -7.55,-6 C-7.55,-6 -7.51,-3.04 -7.51,-3.04 C-7.51,-3.04 -4.6,-3.05 -4.6,-3.05 C-4.6,-3.05 -4.6,-1.06 -4.6,-1.06c " />
+                        </group>
+                    </group>
+                </group>
+                <group
+                    android:name="_R_G_L_0_G_N_3_T_0"
+                    android:rotation="0"
+                    android:translateX="12"
+                    android:translateY="12">
+                    <group
+                        android:name="_R_G_L_0_G_T_1"
+                        android:rotation="180"
+                        android:translateX="7.062"
+                        android:translateY="3.312">
+                        <group
+                            android:name="_R_G_L_0_G"
+                            android:translateX="6.984"
+                            android:translateY="3.547">
+                            <path
+                                android:name="_R_G_L_0_G_D_0_P_0"
+                                android:fillAlpha="1"
+                                android:fillColor="#ffffff"
+                                android:fillType="nonZero"
+                                android:pathData=" M-4.6 -1.06 C-4.6,-1.06 -9.55,-1.06 -9.55,-1.06 C-9.55,-1.06 -9.55,-6.01 -9.55,-6.01 C-9.55,-6.01 -7.55,-6 -7.55,-6 C-7.55,-6 -7.51,-3.04 -7.51,-3.04 C-7.51,-3.04 -4.6,-3.05 -4.6,-3.05 C-4.6,-3.05 -4.6,-1.06 -4.6,-1.06c " />
+                        </group>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/qs_bluetooth_icon_off.xml b/packages/SystemUI/res-keyguard/drawable/qs_bluetooth_icon_off.xml
new file mode 100644
index 0000000..17a7611
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/qs_bluetooth_icon_off.xml
@@ -0,0 +1,144 @@
+<?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.
+  -->
+
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector
+            android:height="24dp"
+            android:width="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_2_G"
+                    android:translateX="14.125"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_2_G_D_0_P_0"
+                        android:fillColor="#ffffff"
+                        android:fillAlpha="1"
+                        android:fillType="nonZero"
+                        android:pathData=" M-1 6.17 C-1,6.17 0.88,4.29 0.88,4.29 C0.88,4.29 -1,2.41 -1,2.41 C-1,2.41 -1,6.17 -1,6.17c  M0.88 -4.29 C0.88,-4.29 -1,-6.17 -1,-6.17 C-1,-6.17 -1,-2.41 -1,-2.41 C-1,-2.41 0.88,-4.29 0.88,-4.29c  M-2 -10 C-2,-10 3.71,-4.29 3.71,-4.29 C3.71,-4.29 -0.59,0 -0.59,0 C-0.59,0 3.71,4.29 3.71,4.29 C3.71,4.29 -2,10 -2,10 C-2,10 -3,10 -3,10 C-3,10 -3,2.41 -3,2.41 C-3,2.41 -7.59,7 -7.59,7 C-7.59,7 -9.01,5.59 -9.01,5.59 C-9.01,5.59 -3.41,0 -3.41,0 C-3.41,0 -9.01,-5.59 -9.01,-5.59 C-9.01,-5.59 -7.59,-7 -7.59,-7 C-7.59,-7 -3,-2.41 -3,-2.41 C-3,-2.41 -3,-10 -3,-10 C-3,-10 -2,-10 -2,-10c "/>
+                </group>
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:translateX="14.125"
+                    android:translateY="12"
+                    android:pivotX="-9.109"
+                    android:scaleX="1"
+                    android:scaleY="1">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:fillColor="#ffffff"
+                        android:fillAlpha="1"
+                        android:fillType="nonZero"
+                        android:pathData=" M-9.09 -1.5 C-8.26,-1.5 -7.59,-0.83 -7.59,0 C-7.59,0.83 -8.26,1.5 -9.09,1.5 C-9.91,1.5 -10.59,0.83 -10.59,0 C-10.59,-0.83 -9.91,-1.5 -9.09,-1.5c "/>
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="14.125"
+                    android:translateY="12"
+                    android:pivotX="4.875"
+                    android:scaleX="1"
+                    android:scaleY="1">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillColor="#ffffff"
+                        android:fillAlpha="1"
+                        android:fillType="nonZero"
+                        android:pathData=" M4.92 -1.5 C5.75,-1.5 6.42,-0.83 6.42,0 C6.42,0.83 5.75,1.5 4.92,1.5 C4.09,1.5 3.42,0.83 3.42,0 C3.42,-0.83 4.09,-1.5 4.92,-1.5c "/>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="_R_G_L_1_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:propertyName="scaleX"
+                    android:duration="150"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator
+                            android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:propertyName="scaleY"
+                    android:duration="150"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr
+                        name="android:interpolator">
+                        <pathInterpolator
+                            android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:propertyName="scaleX"
+                    android:duration="150"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator
+                            android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:propertyName="scaleY"
+                    android:duration="150"
+                    android:startOffset="0"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator
+                            android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:propertyName="translateX"
+                    android:duration="150"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/qs_bluetooth_icon_on.xml b/packages/SystemUI/res-keyguard/drawable/qs_bluetooth_icon_on.xml
new file mode 100644
index 0000000..2dba48c
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/qs_bluetooth_icon_on.xml
@@ -0,0 +1,138 @@
+<?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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_1_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="scaleX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.35,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="scaleY"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.35,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="scaleX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.35,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="250"
+                    android:propertyName="scaleY"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.35,1 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="267"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_2_G"
+                    android:translateX="14.125"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_2_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-1 6.17 C-1,6.17 0.88,4.29 0.88,4.29 C0.88,4.29 -1,2.41 -1,2.41 C-1,2.41 -1,6.17 -1,6.17c  M0.88 -4.29 C0.88,-4.29 -1,-6.17 -1,-6.17 C-1,-6.17 -1,-2.41 -1,-2.41 C-1,-2.41 0.88,-4.29 0.88,-4.29c  M-2 -10 C-2,-10 3.71,-4.29 3.71,-4.29 C3.71,-4.29 -0.59,0 -0.59,0 C-0.59,0 3.71,4.29 3.71,4.29 C3.71,4.29 -2,10 -2,10 C-2,10 -3,10 -3,10 C-3,10 -3,2.41 -3,2.41 C-3,2.41 -7.59,7 -7.59,7 C-7.59,7 -9.01,5.59 -9.01,5.59 C-9.01,5.59 -3.41,0 -3.41,0 C-3.41,0 -9.01,-5.59 -9.01,-5.59 C-9.01,-5.59 -7.59,-7 -7.59,-7 C-7.59,-7 -3,-2.41 -3,-2.41 C-3,-2.41 -3,-10 -3,-10 C-3,-10 -2,-10 -2,-10c " />
+                </group>
+                <group
+                    android:name="_R_G_L_1_G"
+                    android:pivotX="-9.109"
+                    android:scaleX="0"
+                    android:scaleY="0"
+                    android:translateX="14.125"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_1_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-9.09 -1.5 C-8.26,-1.5 -7.59,-0.83 -7.59,0 C-7.59,0.83 -8.26,1.5 -9.09,1.5 C-9.91,1.5 -10.59,0.83 -10.59,0 C-10.59,-0.83 -9.91,-1.5 -9.09,-1.5c " />
+                </group>
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:pivotX="4.875"
+                    android:scaleX="0"
+                    android:scaleY="0"
+                    android:translateX="14.125"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M4.92 -1.5 C5.75,-1.5 6.42,-0.83 6.42,0 C6.42,0.83 5.75,1.5 4.92,1.5 C4.09,1.5 3.42,0.83 3.42,0 C3.42,-0.83 4.09,-1.5 4.92,-1.5c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/qs_bluetooth_icon_search.xml b/packages/SystemUI/res-keyguard/drawable/qs_bluetooth_icon_search.xml
new file mode 100644
index 0000000..3697769
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/qs_bluetooth_icon_search.xml
@@ -0,0 +1,268 @@
+<?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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="_R_G_L_0_G_D_1_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="167"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="333"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_2_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="167"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="333"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="500"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_3_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="167"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="333"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_4_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="167"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="333"
+                    android:valueFrom="1"
+                    android:valueTo="1"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                    android:duration="167"
+                    android:propertyName="fillAlpha"
+                    android:startOffset="500"
+                    android:valueFrom="1"
+                    android:valueTo="0"
+                    android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="1017"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="24dp"
+            android:height="24dp"
+            android:viewportHeight="24"
+            android:viewportWidth="24">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="14.125"
+                    android:translateY="12">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-1 6.17 C-1,6.17 0.88,4.29 0.88,4.29 C0.88,4.29 -1,2.41 -1,2.41 C-1,2.41 -1,6.17 -1,6.17c  M0.88 -4.29 C0.88,-4.29 -1,-6.17 -1,-6.17 C-1,-6.17 -1,-2.41 -1,-2.41 C-1,-2.41 0.88,-4.29 0.88,-4.29c  M-2 -10 C-2,-10 3.71,-4.29 3.71,-4.29 C3.71,-4.29 -0.59,0 -0.59,0 C-0.59,0 3.71,4.29 3.71,4.29 C3.71,4.29 -2,10 -2,10 C-2,10 -3,10 -3,10 C-3,10 -3,2.41 -3,2.41 C-3,2.41 -7.59,7 -7.59,7 C-7.59,7 -9.01,5.59 -9.01,5.59 C-9.01,5.59 -3.41,0 -3.41,0 C-3.41,0 -9.01,-5.59 -9.01,-5.59 C-9.01,-5.59 -7.59,-7 -7.59,-7 C-7.59,-7 -3,-2.41 -3,-2.41 C-3,-2.41 -3,-10 -3,-10 C-3,-10 -2,-10 -2,-10c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_1_P_0"
+                        android:fillAlpha="0"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M4.56 2.33 C4.56,2.33 2.24,0.01 2.24,0.01 C2.24,0.01 4.57,-2.31 4.57,-2.31 C4.84,-1.59 5,-0.82 5,0 C5,0.82 4.84,1.61 4.56,2.33c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_2_P_0"
+                        android:fillAlpha="0"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M6.27 -4.03 C6.27,-4.03 7.53,-5.29 7.53,-5.29 C8.46,-3.77 9,-1.99 9.01,-0.1 C9.01,1.85 8.44,3.67 7.47,5.21 C7.47,5.21 6.27,4.01 6.27,4.01 C6.89,2.81 7.25,1.44 7.25,-0.01 C7.25,-1.46 6.9,-2.82 6.27,-4.03c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_3_P_0"
+                        android:fillAlpha="0"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-8.6 -2.33 C-8.6,-2.33 -6.28,-0.01 -6.28,-0.01 C-6.28,-0.01 -8.61,2.31 -8.61,2.31 C-8.88,1.59 -9.04,0.82 -9.04,0 C-9.04,-0.82 -8.88,-1.61 -8.6,-2.33c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_4_P_0"
+                        android:fillAlpha="0"
+                        android:fillColor="#ffffff"
+                        android:fillType="nonZero"
+                        android:pathData=" M-10.31 4.03 C-10.31,4.03 -11.57,5.29 -11.57,5.29 C-12.5,3.77 -13.04,1.99 -13.05,0.1 C-13.05,-1.85 -12.48,-3.67 -11.51,-5.21 C-11.51,-5.21 -10.31,-4.01 -10.31,-4.01 C-10.93,-2.81 -11.29,-1.44 -11.29,0.01 C-11.29,1.46 -10.94,2.82 -10.31,4.03c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_5_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#000000"
+                        android:fillType="nonZero"
+                        android:pathData=" M-9.09 0 C-9.09,0 -9.09,0 -9.09,0 C-9.09,0 -9.09,0 -9.09,0 C-9.09,0 -9.09,0 -9.09,0 C-9.09,0 -9.09,0 -9.09,0c " />
+                    <path
+                        android:name="_R_G_L_0_G_D_6_P_0"
+                        android:fillAlpha="1"
+                        android:fillColor="#000000"
+                        android:fillType="nonZero"
+                        android:pathData=" M4.92 0 C4.92,0 4.92,0 4.92,0 C4.92,0 4.92,0 4.92,0 C4.92,0 4.92,0 4.92,0 C4.92,0 4.92,0 4.92,0c " />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index 5184c1c..169ccaa 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Jy het jou wagwoord <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd ingetik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%2$d</xliff:g> sekondes."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Verkeerde SIM-PIN-kode. Jy sal nou jou diensverskaffer moet kontak om jou toestel te ontsluit."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Verkeerde SIM-PIN-kode. Jy het <xliff:g id="NUMBER_1">%d</xliff:g> pogings oor.</item>
-      <item quantity="one">Verkeerde SIM-PIN-kode. Jy het <xliff:g id="NUMBER_0">%d</xliff:g> oorblywende poging voordat jy jou diensverskaffer sal moet kontak om jou toestel te ontsluit.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Verkeerde PIN-kode vir SIM. Jy het # poging oor voordat jy jou diensverskaffer moet kontak om jou toestel te ontsluit.}other{Verkeerde PIN-kode vir SIM. Jy het # pogings oor. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM is onbruikbaar. Kontak jou diensverskaffer."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Verkeerde SIM-PUK-kode. Jy het <xliff:g id="NUMBER_1">%d</xliff:g> pogings oor voordat SIM permanent onbruikbaar word.</item>
-      <item quantity="one">Verkeerde SIM-PUK-kode. Jy het <xliff:g id="NUMBER_0">%d</xliff:g> poging oor voordat SIM permanent onbruikbaar word.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Verkeerde PUK-kode vir SIM. Jy het # poging oor voordat SIM permanent onbruikbaar word.}other{Verkeerde PUK-kode vir SIM. Jy het # pogings oor voordat SIM permanent onbruikbaar word.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM-PIN-bewerking het misluk!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM-PUK-bewerking het misluk!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Wissel invoermetode"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Toestel is handmatig gesluit"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nie herken nie"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Skakel kameratoegang aan om Gesigslot te gebruik"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Voer SIM-PIN in. Jy het <xliff:g id="NUMBER_1">%d</xliff:g> pogings oor.</item>
-      <item quantity="one">Voer SIM-PIN in. Jy het <xliff:g id="NUMBER_0">%d</xliff:g> poging oor voordat jy jou diensverskaffer moet kontak om jou toestel te ontsluit.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Jy het <xliff:g id="_NUMBER_1">%d</xliff:g> pogings oor voordat die SIM permanent onbruikbaar word. Kontak die diensverskaffer vir besonderhede.</item>
-      <item quantity="one">SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Jy het <xliff:g id="_NUMBER_0">%d</xliff:g> poging oor voordat die SIM permanent onbruikbaar word. Kontak die diensverskaffer vir besonderhede.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Voer SIM se PIN in. Jy het # poging oor voordat jy jou diensverskaffer moet kontak om jou toestel te ontsluit.}other{Voer SIM se PIN in. Jy het # pogings oor.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Jy het # poging oor voordat die SIM permanent onbruikbaar word. Kontak die diensverskaffer vir besonderhede.}other{SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Jy het # pogings oor voordat die SIM permanent onbruikbaar word. Kontak die diensverskaffer vir besonderhede.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Verstek"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Borrel"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analoog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index 11a2be5..b528269 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"የይለፍ ቃልዎን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ተይበዋል።\n\nበ<xliff:g id="NUMBER_1">%2$d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ስለውታል።\n\nበ<xliff:g id="NUMBER_1">%2$d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ልክ ያልሆነ የሲም ፒን ኮድ። አሁን መሣሪያዎን ለማስከፈት አገልግሎት አቅራቢዎን ማነጋገር አለብዎት።"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">ልክ ያልሆነ የሲም ፒን ኮድ፣ <xliff:g id="NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል።</item>
-      <item quantity="other">ልክ ያልሆነ የሲም ፒን ኮድ፣ <xliff:g id="NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል።</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{የተሳሳተ የሲም ፒን ኮድ፣ መሣሪያዎን ለማስከፈት የአገልግሎት አቅራቢዎን ማነጋገር ግዴታ ከመሆኑ በፊት # ሙከራ ይቀርዎታል።}one{የተሳሳተ የሲም ፒን ኮድ፣ # ሙከራዎች ይቀሩዎታል። }other{የተሳሳተ የሲም ፒን ኮድ፣ # ሙከራዎች ይቀሩዎታል። }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"ሲሙ ጥቅም ላይ መዋል እይችልም። የአገልግሎት አቅራቢዎን ያነጋግሩ።"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">ልክ ያልሆነ የሲም ፒዩኬ ኮድ፣ ሲሙ እስከመጨረሻው የማይሰራ ከመሆኑ በፊት <xliff:g id="NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል።</item>
-      <item quantity="other">ልክ ያልሆነ የሲም ፒዩኬ ኮድ፣ ሲሙ እስከመጨረሻው የማይሰራ ከመሆኑ በፊት <xliff:g id="NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል።</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{የተሳሳተ የሲም PUK ኮድ፣ ሲም በቋሚነት መጠቀም የማይቻል ከመሆኑ በፊት # ሙከራ ይቀርዎታል።}one{የተሳሳተ የሲም PUK ኮድ፣ ሲም በቋሚነት መጠቀም የማይቻል ከመሆኑ በፊት # ሙከራ ይቀርዎታል።}other{የተሳሳተ የሲም PUK ኮድ፣ ሲም በቋሚነት መጠቀም የማይቻል ከመሆኑ በፊት # ሙከራዎች ይቀሩዎታል።}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"የሲም ፒን ክወና አልተሳካም!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"የሲም PUK ክወና አልተሳካም!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"የግቤት ስልት ቀይር"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"መሣሪያ በተጠቃሚው ራሱ ተቆልፏል"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"አልታወቀም"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"በመልክ መክፈትን ለመጠቀም በቅንብሮች ውስጥ የካሜራ መዳረሻን ያብሩ"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">የሲም ፒን ያስገቡ። <xliff:g id="NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል።</item>
-      <item quantity="other">የሲም ፒን ያስገቡ። <xliff:g id="NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል።</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ሲም እስከመጨረሻው መጠቀም የማይቻል ከመሆኑ በፊት <xliff:g id="_NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል። ዝርዝሮችን ለማግኘት የአገልግሎት አቅራቢን ያነጋግሩ።</item>
-      <item quantity="other">ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ሲም እስከመጨረሻው መጠቀም የማይቻል ከመሆኑ በፊት <xliff:g id="_NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል። ዝርዝሮችን ለማግኘት የአገልግሎት አቅራቢን ያነጋግሩ።</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{የሲም ፒን ያስገቡ። መሣሪያዎን ለማስከፈት የአገልግሎት አቅራቢዎን ማነጋገር ግዴታ ከመሆኑ በፊት # ሙከራ ይቀርዎታል።}one{የሲም ፒን ያስገቡ። # ቀሪ ሙከራዎች አሉዎት።}other{የሲም ፒን ያስገቡ። # ቀሪ ሙከራዎች አሉዎት።}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ሲም በቋሚነት መጠቀም የማይቻል ከመሆኑ በፊት # ሙከራ ይቀርዎታል። ዝርዝሮችን ለማግኘት የአገልግሎት አቅራቢን ያነጋግሩ።}one{ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ሲም በቋሚነት መጠቀም የማይቻል ከመሆኑ በፊት # ሙከራዎች ይቀሩዎታል። ዝርዝሮችን ለማግኘት የአገልግሎት አቅራቢን ያነጋግሩ።}other{ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ሲም በቋሚነት መጠቀም የማይቻል ከመሆኑ በፊት # ሙከራዎች ይቀሩዎታል። ዝርዝሮችን ለማግኘት የአገልግሎት አቅራቢን ያነጋግሩ።}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ነባሪ"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"አረፋ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"አናሎግ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 5e3bc32..534dbaa 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -68,23 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"لقد كتبت كلمة المرور بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"لقد رسمت نقش فتح القفل بطريقة غير صحيحة <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانية."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"‏رمز \"رقم التعريف الشخصي\" لشريحة SIM غير صحيح، ويلزمك الاتصال الآن بمشغّل شبكة الجوّال لإلغاء قفل الجهاز."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="zero">‏رمز رقم التعريف الشخصي لشريحة SIM غير صحيح، ولم تتبق لديك أي محاولات (<xliff:g id="NUMBER_1">%d</xliff:g>).</item>
-      <item quantity="two">‏رمز رقم التعريف الشخصي لشريحة SIM غير صحيح، ويتبقى لديك محاولتان (<xliff:g id="NUMBER_1">%d</xliff:g>).</item>
-      <item quantity="few">‏رمز رقم التعريف الشخصي لشريحة SIM غير صحيح، ويتبقى لديك <xliff:g id="NUMBER_1">%d</xliff:g> محاولات.</item>
-      <item quantity="many">‏رمز رقم التعريف الشخصي لشريحة SIM غير صحيح، ويتبقى لديك <xliff:g id="NUMBER_1">%d</xliff:g> محاولة.</item>
-      <item quantity="other">‏رمز رقم التعريف الشخصي لشريحة SIM غير صحيح، ويتبقى لديك <xliff:g id="NUMBER_1">%d</xliff:g> محاولة.</item>
-      <item quantity="one">‏رمز \"رقم التعريف الشخصي\" لشريحة SIM غير صحيح، ويتبقى لديك محاولة واحدة (<xliff:g id="NUMBER_0">%d</xliff:g>) يتعين عليك بعدها الاتصال بمشغّل شبكة الجوّال لإلغاء قفل الجهاز.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{‏رقم التعريف الشخصي لشريحة SIM غير صحيح. تتبقّى لديك محاولة واحدة يجب بعدها الاتصال بمشغّل شبكة الجوّال لفتح قفل الجهاز.}zero{‏رمز رقم التعريف الشخصي لشريحة SIM غير صحيح. تتبقّى لديك # محاولة. }two{‏رمز رقم التعريف الشخصي لشريحة SIM غير صحيح. تتبقّى لديك محاولتان. }few{‏رمز رقم التعريف الشخصي لشريحة SIM غير صحيح. تتبقّى لديك # محاولات. }many{‏رمز رقم التعريف الشخصي لشريحة SIM غير صحيح. تتبقّى لديك # محاولة. }other{‏رمز رقم التعريف الشخصي لشريحة SIM غير صحيح. تتبقّى لديك # محاولة. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"‏شريحة SIM غير صالحة للاستخدام. يُرجى الاتصال بمشغّل شبكة الجوّال."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="zero">‏رمز PUK لشريحة SIM غير صحيح، ولم تتبق لديك أي محاولات (<xliff:g id="NUMBER_1">%d</xliff:g>) تصبح بعدها شريحة SIM غير صالحة للاستخدام بشكل دائم.</item>
-      <item quantity="two">‏رمز PUK لشريحة SIM غير صحيح، ويتبقى لديك محاولتان (<xliff:g id="NUMBER_1">%d</xliff:g>) تصبح بعدها شريحة SIM غير صالحة للاستخدام بشكل دائم.</item>
-      <item quantity="few">‏رمز PUK لشريحة SIM غير صحيح، ويتبقى لديك <xliff:g id="NUMBER_1">%d</xliff:g> محاولات تصبح بعدها شريحة SIM غير صالحة للاستخدام بشكل دائم.</item>
-      <item quantity="many">‏رمز PUK لشريحة SIM غير صحيح، ويتبقى لديك <xliff:g id="NUMBER_1">%d</xliff:g> محاولة تصبح بعدها شريحة SIM غير صالحة للاستخدام بشكل دائم.</item>
-      <item quantity="other">‏رمز PUK لشريحة SIM غير صحيح، ويتبقى لديك <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات تصبح بعدها شريحة SIM غير صالحة للاستخدام بشكل دائم.</item>
-      <item quantity="one">‏رمز PUK لشريحة SIM غير صالح، ويتبقى لديك محاولة واحدة (<xliff:g id="NUMBER_0">%d</xliff:g>)، تصبح بعدها شريحة SIM غير صالحة للاستخدام بشكل دائم.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{‏رمز PUK لشريحة SIM غير صحيح. تتبقّى لديك محاولة واحدة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا.}zero{‏رمز PUK لشريحة SIM غير صحيح. تتبقّى لديك # محاولة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا.}two{‏رمز PUK لشريحة SIM غير صحيح. تتبقّى لديك محاولتان قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا.}few{‏رمز PUK لشريحة SIM غير صحيح. تتبقّى لديك # محاولات قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا.}many{‏رمز PUK لشريحة SIM غير صحيح. تتبقّى لديك # محاولة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا.}other{‏رمز PUK لشريحة SIM غير صحيح. تتبقّى لديك # محاولة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"‏تعذّر إتمام عملية \"رقم التعريف الشخصي\" لشريحة SIM"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"‏تعذّر إتمام عملية PUK لشريحة SIM"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"تبديل أسلوب الإدخال"</string>
@@ -99,22 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"تم حظر الجهاز يدويًا"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"لم يتم التعرّف عليه."</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"يجب منح الكاميرا إذن الوصول في \"الإعدادات\"."</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="zero">‏أدخل رقم التعريف الشخصي لشريحة SIM. تتبقى لديك <xliff:g id="NUMBER_1">%d</xliff:g> محاولة.</item>
-      <item quantity="two">‏أدخل رقم التعريف الشخصي لشريحة SIM. تتبقى لديك محاولتان (<xliff:g id="NUMBER_1">%d</xliff:g>).</item>
-      <item quantity="few">‏أدخل رقم التعريف الشخصي لشريحة SIM. تتبقى لديك <xliff:g id="NUMBER_1">%d</xliff:g> محاولات.</item>
-      <item quantity="many">‏أدخل رقم التعريف الشخصي لشريحة SIM. تتبقى لديك <xliff:g id="NUMBER_1">%d</xliff:g> محاولة.</item>
-      <item quantity="other">‏أدخل رقم التعريف الشخصي لشريحة SIM. تتبقى لديك <xliff:g id="NUMBER_1">%d</xliff:g> محاولة.</item>
-      <item quantity="one">‏أدخل رقم التعريف الشخصي لشريحة SIM. تتبقى لديك محاولة واحدة (<xliff:g id="NUMBER_0">%d</xliff:g>) يجب أن تتصل بعدها بمشغّل شبكة الجوّال لفتح الجهاز.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="zero">‏تم إيقاف شريحة SIM الآن. أدخل رمز PUK للمتابعة، وتتبقى لديك <xliff:g id="_NUMBER_1">%d</xliff:g> محاولة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. ويمكنك الاتصال بمشغل شبكة الجوّال لمعرفة التفاصيل.</item>
-      <item quantity="two">‏تم إيقاف شريحة SIM الآن. أدخل رمز PUK للمتابعة، وتتبقى لديك محاولتان (<xliff:g id="_NUMBER_1">%d</xliff:g>) قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. ويمكنك الاتصال بمشغل شبكة الجوّال لمعرفة التفاصيل.</item>
-      <item quantity="few">‏تم إيقاف شريحة SIM الآن. أدخل رمز PUK للمتابعة، وتتبقى لديك <xliff:g id="_NUMBER_1">%d</xliff:g> محاولات قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. ويمكنك الاتصال بمشغل شبكة الجوّال لمعرفة التفاصيل.</item>
-      <item quantity="many">‏تم إيقاف شريحة SIM الآن. أدخل رمز PUK للمتابعة، وتتبقى لديك <xliff:g id="_NUMBER_1">%d</xliff:g> محاولة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. ويمكنك الاتصال بمشغل شبكة الجوّال لمعرفة التفاصيل.</item>
-      <item quantity="other">‏تم إيقاف شريحة SIM الآن. أدخل رمز PUK للمتابعة، وتتبقى لديك <xliff:g id="_NUMBER_1">%d</xliff:g> محاولة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. ويمكنك الاتصال بمشغل شبكة الجوّال لمعرفة التفاصيل.</item>
-      <item quantity="one">‏تم إيقاف شريحة SIM الآن. أدخل رمز PUK للمتابعة، وتتبقى لديك محاولة واحدة (<xliff:g id="_NUMBER_0">%d</xliff:g>) قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. ويمكنك الاتصال بمشغل شبكة الجوّال لمعرفة التفاصيل.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{‏أدخِل رقم التعريف الشخصي لشريحة SIM. تتبقّى لديك محاولة واحدة ويجب بعدها التواصل مع مشغّل شبكة الجوّال لفتح قفل الجهاز.}zero{‏أدخِل رقم التعريف الشخصي لشريحة SIM. تتبقّى لديك # محاولة.}two{‏أدخِل رقم التعريف الشخصي لشريحة SIM. تتبقّى لديك محاولتان.}few{‏أدخِل رقم التعريف الشخصي لشريحة SIM. تتبقّى لديك # محاولات.}many{‏أدخِل رقم التعريف الشخصي لشريحة SIM. تتبقّى لديك # محاولةً.}other{‏أدخِل رقم التعريف الشخصي لشريحة SIM. تتبقّى لديك # محاولة.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{‏تم إيقاف شريحة SIM الآن. يجب إدخال رمز PUK للمتابعة. وتتبقّى لديك محاولة واحدة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. يمكنك التواصل مع مشغِّل شبكة الجوّال لمعرفة التفاصيل.}zero{‏تم إيقاف شريحة SIM الآن. يجب إدخال رمز PUK للمتابعة. وتتبقّى لديك # محاولة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. يمكنك التواصل مع مشغِّل شبكة الجوّال لمعرفة التفاصيل.}two{‏تم إيقاف شريحة SIM الآن. يجب إدخال رمز PUK للمتابعة. وتتبقّى لديك محاولتان قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. يمكنك التواصل مع مشغِّل شبكة الجوّال لمعرفة التفاصيل.}few{‏تم إيقاف شريحة SIM الآن. يجب إدخال رمز PUK للمتابعة. وتتبقّى لديك # محاولات قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. يمكنك التواصل مع مشغِّل شبكة الجوّال لمعرفة التفاصيل.}many{‏تم إيقاف شريحة SIM الآن. يجب إدخال رمز PUK للمتابعة. وتتبقّى لديك # محاولةً قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. يمكنك التواصل مع مشغِّل شبكة الجوّال لمعرفة التفاصيل.}other{‏تم إيقاف شريحة SIM الآن. يجب إدخال رمز PUK للمتابعة. وتتبقّى لديك # محاولة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. يمكنك التواصل مع مشغِّل شبكة الجوّال لمعرفة التفاصيل.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"تلقائي"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"فقاعة"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ساعة تقليدية"</string>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index d60c564..537b5b8 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"আপুনি আপোনাৰ পাছৱৰ্ড <xliff:g id="NUMBER_0">%1$d</xliff:g>বাৰ ভুলকৈ লিখিছে। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ছেকেণ্ডৰ পাছত আকৌ চেষ্টা কৰক।"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"আপুনি আপোনাৰ আনলক আৰ্হি <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g>ছেকেণ্ডৰ পিছত আকৌ চেষ্টা কৰক।"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ছিমৰ ভুল পিন ক\'ড, আপোনাৰ ডিভাইচটো আনলক কৰিবলৈ আপুনি এতিয়া আপোনাৰ বাহকৰ সৈতে যোগাযোগ কৰিবই লাগিব।"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">ছিমৰ ভুল পিন ক’ড, আপুনি আৰু <xliff:g id="NUMBER_1">%d</xliff:g> বাৰ প্ৰয়াস কৰিব পাৰিব।</item>
-      <item quantity="other">ছিমৰ ভুল পিন ক’ড, আপুনি আৰু <xliff:g id="NUMBER_1">%d</xliff:g> বাৰ প্ৰয়াস কৰিব পাৰিব।</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{ছিমৰ পিন ক’ড ভুল হৈছে, আপোনাৰ ডিভাইচ আনলক কৰিবলৈ আপোনাৰ বাহকৰ লগত যোগাযোগ কৰিবই লগা হোৱাৰ পূৰ্বে আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে।}one{ছিমৰ পিন ক’ড ভুল হৈছে, আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে। }other{ছিমৰ পিন ক’ড ভুল হৈছে, আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে। }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"ছিম ব্যৱহাৰযোগ্য নহয়। আপোনাৰ বাহকৰ সৈতে যোগাযোগ কৰক।"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">ছিমৰ ভুল PUK ক\'ড, আপুনি আৰু <xliff:g id="NUMBER_1">%d</xliff:g> বাৰ ভুল ক’ড দিলে আপোনাৰ ছিম চিৰকালৰ বাবে ব্যৱহাৰৰ অনুপযোগী হ’ব।</item>
-      <item quantity="other">ছিমৰ ভুল PUK ক\'ড, আপুনি আৰু <xliff:g id="NUMBER_1">%d</xliff:g> বাৰ ভুল ক’ড দিলে আপোনাৰ ছিম চিৰকালৰ বাবে ব্যৱহাৰৰ অনুপযোগী হ’ব।</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{ছিমৰ PUK ক’ড ভুল হৈছে, ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে।}one{ছিমৰ PUK ক’ড ভুল হৈছে, ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে।}other{ছিমৰ PUK ক’ড ভুল হৈছে, ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে।}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"ছিম পিনৰ জৰিয়তে আনলক কৰিব পৰা নগ\'ল!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"ছিম PUKৰ জৰিয়তে আনলক কৰিব পৰা নগ\'ল!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ইনপুট পদ্ধতি সলনি কৰক"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"ডিভাইচটো মেনুৱেলভাৱে লক কৰা হৈছিল"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"চিনাক্ত কৰিব পৰা নাই"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"ফেচ আনলক ব্যৱহাৰ কৰিবলৈ ছেটিঙত কেমেৰাৰ এক্সেছ অন কৰক"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">ছিমৰ পিন দিয়ক। আপুনি আৰু <xliff:g id="NUMBER_1">%d</xliff:g>বাৰ প্ৰয়াস কৰিব পাৰে।</item>
-      <item quantity="other">ছিমৰ পিন দিয়ক। আপুনি আৰু <xliff:g id="NUMBER_1">%d</xliff:g>বাৰ প্ৰয়াস কৰিব পাৰে।</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">ছিমখন অক্ষম হ’ল। অব্যাহত ৰাখিবলৈ PUK দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ হাতত <xliff:g id="_NUMBER_1">%d</xliff:g>টা প্ৰয়াস বাকী আছে। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।</item>
-      <item quantity="other">ছিমখন অক্ষম হ’ল। অব্যাহত ৰাখিবলৈ PUK দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ হাতত <xliff:g id="_NUMBER_1">%d</xliff:g>টা প্ৰয়াস বাকী আছে। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{ছিমৰ পিন দিয়ক। আপোনাৰ ডিভাইচ আনলক কৰিবলৈ আপোনাৰ বাহকৰ লগত যোগাযোগ কৰিবই লগা হোৱাৰ পূৰ্বে আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে।}one{ছিমৰ পিন দিয়ক। আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে।}other{ছিমৰ পিন দিয়ক। আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে।}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{ছিমখন এতিয়া অক্ষম কৰা হৈছে। অব্যাহত ৰাখিবলৈ PUK ক’ড দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে। সবিশেষৰ বাবে বাহকৰ সৈতে যোগাযোগ কৰক।}one{ছিমখন এতিয়া অক্ষম কৰা হৈছে। অব্যাহত ৰাখিবলৈ PUK ক’ড দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে। সবিশেষৰ বাবে বাহকৰ সৈতে যোগাযোগ কৰক।}other{ছিমখন এতিয়া অক্ষম কৰা হৈছে। অব্যাহত ৰাখিবলৈ PUK ক’ড দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ ওচৰত # টা প্ৰয়াস বাকী আছে। সবিশেষৰ বাবে বাহকৰ সৈতে যোগাযোগ কৰক।}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ডিফ’ল্ট"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"বাবল"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"এনাল’গ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index fe35bbc..3fd2f04 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Parolu <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Kilid modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Yanlış SIM PIN kodu  cihazın açılması üçün operatorla indi əlaqə saxlamalısınız."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Yanlış SIM PIN kodu, <xliff:g id="NUMBER_1">%d</xliff:g> cəhdiniz qalır.</item>
-      <item quantity="one">Yanlış SIM PIN kodu, <xliff:g id="NUMBER_0">%d</xliff:g> cəhddən sonra cihazı kiliddən çıxarmaq üçün operatorla əlaqə saxlamalısınız.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Yanlış SIM PIN kodu, # cəhdiniz qalıb, sonra cihazı kiliddən çıxarmaq üçün operatorla əlaqə saxlamalı olacaqsınız.}other{Yanlış SIM PIN kodu, # cəhdiniz qalıb. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM yararsızdır. Operatorla əlaqə saxlayın."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Yanlış SIM PUK kodu,<xliff:g id="NUMBER_1">%d</xliff:g> cəhddən sonra SIM kart həmişəlik yararsız olacaq.</item>
-      <item quantity="one">Yanlış SIM PUK kodu, <xliff:g id="NUMBER_0">%d</xliff:g> cəhddən sonra SIM kart həmişəlik yararsız olacaq.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Yanlış SIM PUK kodu, # cəhdiniz qalıb, sonra SIM kart həmişəlik yararsız olacaq.}other{Yanlış SIM PUK kodu, # cəhdiniz qalıb, sonra SIM kart həmişəlik yararsız olacaq.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN əməliyyatı alınmadı!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK əməliyyatı alınmadı!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Daxiletmə metoduna keçin"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Cihaz əl ilə kilidləndi"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Tanınmır"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Üz ilə Kiliddən Açmanı istifadə etmək üçün Ayarlarda kameraya girişi aktiv edin"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM PIN-ni daxil edin. <xliff:g id="NUMBER_1">%d</xliff:g> cəhdiniz qalır.</item>
-      <item quantity="one">SIM PIN-ni daxil edin. Cihazınızı kiliddən çıxarmaq üçün operatorunuzla əlaqə saxlamadan öncə <xliff:g id="NUMBER_0">%d</xliff:g> cəhdiniz qalır.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM indi deaktivdir. Davam etmək üçün PUK kodunu daxil edin. SIM birdəfəlik yararsız olmadan öncə <xliff:g id="_NUMBER_1">%d</xliff:g> cəhdiniz qalır. Ətraflı məlumat üçün operatorla əlaqə saxlayın.</item>
-      <item quantity="one">SIM indi deaktivdir. Davam etmək üçün PUK kodunu daxil edin. SIM birdəfəlik yararsız olmadan öncə <xliff:g id="_NUMBER_0">%d</xliff:g> cəhdiniz qalır. Ətraflı məlumat üçün operatorla əlaqə saxlayın.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM PIN kodunu daxil edin. # cəhdiniz qalıb, sonra cihazınızı kiliddən çıxarmaq üçün operatorunuzla əlaqə saxlamalı olacaqsınız.}other{SIM PIN kodunu daxil edin. # cəhdiniz qalıb.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM indi deaktivdir. Davam etmək üçün PUK kodunu daxil edin. # cəhdiniz qalıb, sonra SIM birdəfəlik yararsız olacaq. Ətraflı məlumat üçün operatorla əlaqə saxlayın.}other{SIM indi deaktivdir. Davam etmək üçün PUK kodunu daxil edin. # cəhdiniz qalıb, sonra SIM birdəfəlik yararsız olacaq. Ətraflı məlumat üçün operatorla əlaqə saxlayın.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Defolt"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Qabarcıq"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analoq"</string>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index 5e83a15..b0059d8 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -68,17 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Uneli ste pogrešnu lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Nacrtali ste netačan šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nProbajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Netačan PIN kôd za SIM. Sada morate da kontaktirate mobilnog operatera da biste otključali uređaj."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Netačan PIN kôd za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj.</item>
-      <item quantity="few">Netačan PIN kôd za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-      <item quantity="other">Netačan PIN kôd za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Netačan PIN za SIM kôd. Imate još # pokušaj, a onda morate da se obratite mobilnom operateru da biste otključali uređaj.}one{Netačan PIN za SIM kôd. Imate još # pokušaj. }few{Netačan PIN za SIM kôd. Imate još # pokušaja. }other{Netačan PIN za SIM kôd. Imate još # pokušaja. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM kartica je neupotrebljiva. Kontaktirajte mobilnog operatera."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Netačan PUK kôd za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj pre nego što SIM kartica postane trajno neupotrebljiva.</item>
-      <item quantity="few">Netačan PUK kôd za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja pre nego što SIM kartica postane trajno neupotrebljiva.</item>
-      <item quantity="other">Netačan PUK kôd za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja pre nego što SIM kartica postane trajno neupotrebljiva.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Netačan SIM PUK kôd. Imate još # pokušaj pre nego što SIM kartica postane trajno neupotrebljiva.}one{Netačan PUK kôd za SIM. Imate još # pokušaj pre nego što SIM kartica postane trajno neupotrebljiva.}few{Netačan PUK kôd za SIM. Imate još # pokušaja pre nego što SIM kartica postane trajno neupotrebljiva.}other{Netačan PUK kôd za SIM. Imate još # pokušaja pre nego što SIM kartica postane trajno neupotrebljiva.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Radnja sa PIN kodom za SIM nije uspela!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Radnja sa PUK kodom za SIM nije uspela!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promeni metod unosa"</string>
@@ -93,16 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Uređaj je ručno zaključan"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nije prepoznat"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Otključavanje licem traži pristup kameri u Podešavanjima"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Unesite PIN za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj.</item>
-      <item quantity="few">Unesite PIN za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-      <item quantity="other">Unesite PIN za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaj pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.</item>
-      <item quantity="few">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.</item>
-      <item quantity="other">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Unesite PIN za SIM. Još # pokušaj i moraćete da se obratite mobilnom operateru da biste otključali uređaj.}one{Unesite PIN za SIM. Imate još # pokušaj.}few{Unesite PIN za SIM. Imate još # pokušaja.}other{Unesite PIN za SIM. Imate još # pokušaja.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaj pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}one{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaj pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}few{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}other{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Podrazumevani"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Mehurići"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogni"</string>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index 0e6681c..ebcca07 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -68,19 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Вы няправільна ўвялі пароль столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%2$d</xliff:g> с."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Вы няправільна ўвялі ўзор разблакіроўкі столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%2$d</xliff:g> с."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Няправільны PIN-код SIM-карты, цяпер вы павінны звязацца з аператарам для разблакіроўкі прылады."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Няправільны PIN-код SIM-карты, у вас засталася <xliff:g id="NUMBER_1">%d</xliff:g> спроба.</item>
-      <item quantity="few">Няправільны PIN-код SIM-карты, у вас засталіся <xliff:g id="NUMBER_1">%d</xliff:g> спробы.</item>
-      <item quantity="many">Няправільны PIN-код SIM-карты, у вас засталіся <xliff:g id="NUMBER_1">%d</xliff:g> спроб.</item>
-      <item quantity="other">Няправільны PIN-код SIM-карты, у вас засталіся <xliff:g id="NUMBER_1">%d</xliff:g> спробы.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Няправільны PIN-код SIM-карты. У вас засталася # спроба, інакш вам прыйдзецца звязацца з аператарам для разблакіроўкі прылады.}one{Няправільны PIN-код SIM-карты, у вас засталіся # спроба. }few{Няправільны PIN-код SIM-карты, у вас засталіся # спробы. }many{Няправільны PIN-код SIM-карты, у вас засталіся # спроб. }other{Няправільны PIN-код SIM-карты, у вас засталіся # спробы. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-карта не прыдатная для выкарыстання. Звяжыцеся з аператарам."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Няправільны PUK-код SIM-карты, у вас засталася <xliff:g id="NUMBER_1">%d</xliff:g> спроба перад тым, як SIM-карта перастане працаваць назаўжды.</item>
-      <item quantity="few">Няправільны PUK-код SIM-карты, у вас засталіся <xliff:g id="NUMBER_1">%d</xliff:g> спробы перад тым, як SIM-карта перастане працаваць назаўжды.</item>
-      <item quantity="many">Няправільны PUK-код SIM-карты, у вас засталіся <xliff:g id="NUMBER_1">%d</xliff:g> спроб перад тым, як SIM-карта перастане працаваць назаўжды.</item>
-      <item quantity="other">Няправільны PUK-код SIM-карты, у вас засталіся <xliff:g id="NUMBER_1">%d</xliff:g> спробы перад тым, як SIM-карта перастане працаваць назаўжды.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Няправільны PUK-код SIM-карты, у вас засталася # спроба перад тым, як SIM-карта перастане працаваць назаўжды.}one{Няправільны PUK-код SIM-карты, у вас засталося # спроба перад тым, як SIM-карта перастане працаваць назаўжды.}few{Няправільны PUK-код SIM-карты, у вас засталося # спробы перад тым, як SIM-карта перастане працаваць назаўжды.}many{Няправільны PUK-код SIM-карты, у вас засталося # спроб перад тым, як SIM-карта перастане працаваць назаўжды.}other{Няправільны PUK-код SIM-карты, у вас засталося # спробы перад тым, як SIM-карта перастане працаваць назаўжды.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Разблакіраваць SIM-карту PIN-кодам не атрымалася!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Разблакіраваць SIM-карту PUK-кодам не атрымалася!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Пераключэнне рэжыму ўводу"</string>
@@ -95,18 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Прылада была заблакіравана ўручную"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Не распазнана"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Для распазнавання твару ўключыце доступ да камеры"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Увядзіце PIN-код SIM-карты. У вас засталася <xliff:g id="NUMBER_1">%d</xliff:g> спроба.</item>
-      <item quantity="few">Увядзіце PIN-код SIM-карты. У вас засталося <xliff:g id="NUMBER_1">%d</xliff:g> спробы.</item>
-      <item quantity="many">Увядзіце PIN-код SIM-карты. У вас засталося <xliff:g id="NUMBER_1">%d</xliff:g> спроб.</item>
-      <item quantity="other">Увядзіце PIN-код SIM-карты. У вас засталося <xliff:g id="NUMBER_1">%d</xliff:g> спробы.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ <xliff:g id="_NUMBER_1">%d</xliff:g> спроба, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.</item>
-      <item quantity="few">SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ <xliff:g id="_NUMBER_1">%d</xliff:g> спробы, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.</item>
-      <item quantity="many">SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ <xliff:g id="_NUMBER_1">%d</xliff:g> спроб, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.</item>
-      <item quantity="other">SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ <xliff:g id="_NUMBER_1">%d</xliff:g> спробы, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Увядзіце PIN-код SIM-карты. У вас засталася # спроба. Пасля гэтага вам давядзецца звярнуцца да свайго аператара, каб разблакіраваць прыладу.}one{Увядзіце PIN-код SIM-карты. У вас засталося # спроба.}few{Увядзіце PIN-код SIM-карты. У вас засталося # спробы.}many{Увядзіце PIN-код SIM-карты. У вас засталося # спроб.}other{Увядзіце PIN-код SIM-карты. У вас засталося # спробы.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ # спроба, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.}one{SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ # спроба, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.}few{SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ # спробы, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.}many{SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ # спроб, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.}other{SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ # спробы, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Стандартны"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Бурбалкі"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Са стрэлкамі"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index a4e08f3..a08409e 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Неправилен ПИН код за SIM картата – сега трябва да се свържете с оператора си, за да отключите устройството."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Неправилен ПИН код за SIM картата – остават ви <xliff:g id="NUMBER_1">%d</xliff:g> опита.</item>
-      <item quantity="one">Неправилен ПИН код за SIM картата – остава ви <xliff:g id="NUMBER_0">%d</xliff:g> опит, преди да трябва да се свържете с оператора си, за да отключите устройството.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Неправилен ПИН код за SIM картата. Остава ви # опит, преди да трябва да се свържете с оператора си, за да отключите устройството.}other{Неправилен ПИН код за SIM картата. Остават ви # опита. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM картата е неизползваема. Свържете се с оператора си."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Неправилен PUK код за SIM картата – остават ви <xliff:g id="NUMBER_1">%d</xliff:g> опита, преди тя да стане неизползваема завинаги.</item>
-      <item quantity="one">Неправилен PUK код за SIM картата – остава ви <xliff:g id="NUMBER_0">%d</xliff:g> опит, преди тя да стане неизползваема завинаги.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Неправилен PUK код за SIM картата. Остава ви # опит, преди тя да стане неизползваема завинаги.}other{Неправилен PUK код за SIM картата. Остават ви # опита, преди тя да стане неизползваема завинаги.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Операцията с ПИН кода за SIM картата не бе успешна!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Операцията с PUK кода за SIM картата не бе успешна!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Превключване на метода на въвеждане"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Устройството бе заключено ръчно"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Не е разпознато"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"За да ползвате „Отключване с лице“, вкл. достъпа до камерата от настройките"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Въведете ПИН кода за SIM картата – остават ви <xliff:g id="NUMBER_1">%d</xliff:g> опита.</item>
-      <item quantity="one">Въведете ПИН кода за SIM картата – остава ви <xliff:g id="NUMBER_0">%d</xliff:g> опит, преди да се наложи да се свържете с оператора си, за да отключите устройството.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Остават ви <xliff:g id="_NUMBER_1">%d</xliff:g> опита, преди SIM картата да стане неизползваема завинаги. Свържете се с оператора за подробности.</item>
-      <item quantity="one">SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Остава ви <xliff:g id="_NUMBER_0">%d</xliff:g> опит, преди SIM картата да стане неизползваема завинаги. Свържете се с оператора за подробности.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Въведете ПИН кода за SIM картата. Остава ви # опит, преди да трябва да се свържете с оператора си, за да отключите устройството.}other{Въведете ПИН кода за SIM картата. Остават ви # опита.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Остава ви # опит, преди SIM картата да стане неизползваема завинаги. Свържете се с оператора за подробности.}other{SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Остават ви # опита, преди SIM картата да стане неизползваема завинаги. Свържете се с оператора за подробности.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Стандартен"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Балонен"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Аналогов"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index bbc025fe..cb9e900 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আপনার পাসওয়ার্ড লিখেছেন।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুলভাবে আপনার আনলকের প্যাটার্ন এঁকেছেন।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ভুল সিম পিন কোড দিয়েছেন, আপনার ডিভাইসটি আনলক করতে এখন আপনাকে অবশ্যই আপনার পরিষেবা প্রদানকারীর সাথে যোগাযোগ করতে হবে।"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">সিমের পিন কোডটি ভুল, আপনি আর <xliff:g id="NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারেন।</item>
-      <item quantity="other">সিমের পিন কোডটি ভুল, আপনি আর <xliff:g id="NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারেন।</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{সিম কার্ডের ভুল পিন কোড দিয়েছেন, আপনি আরও # বার চেষ্টা করতে পারবেন, তারপরে ডিভাইস আনলক করতে পরিষেবা প্রদানকারীর সাথে যোগাযোগ করতে হবে।}one{সিম কার্ডের ভুল পিন কোড দিয়েছেন, আপনি আরও # বার চেষ্টা করতে পারবেন। }other{সিম কার্ডের ভুল পিন কোড দিয়েছেন, আপনি আরও # বার চেষ্টা করতে পারবেন। }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"সিমটি ব্যবহার করা যাবে না। আপনার পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">সিমের PUK কোডটি ভুল, আপনি আর <xliff:g id="NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারেন, তারপর আপনার সিমটি স্থায়ীভাবে অব্যবহারযোগ্য হবে।</item>
-      <item quantity="other">সিমের PUK কোডটি ভুল, আপনি আর <xliff:g id="NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারেন, তারপর আপনার সিমটি স্থায়ীভাবে অব্যবহারযোগ্য হবে।</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{সিম কার্ডের ভুল PUK কোড দিয়েছেন, আপনি আরও # বার চেষ্টা করতে পারবেন, তারপরে এই সিম কার্ডটি স্থায়ীভাবে কাজ করা বন্ধ করে দেবে।}one{সিম কার্ডের ভুল PUK কোড দিয়েছেন, আপনি আরও # বার চেষ্টা করতে পারবেন, তারপরে এই সিম কার্ডটি স্থায়ীভাবে কাজ করা বন্ধ করে দেবে।}other{সিম কার্ডের ভুল PUK কোড দিয়েছেন, আপনি আরও # বার চেষ্টা করতে পারবেন, তারপরে এই সিম কার্ডটি স্থায়ীভাবে কাজ করা বন্ধ করে দেবে।}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"সিম পিন দিয়ে আনলক করা যায়নি!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"সিম PUK দিয়ে আনলক করা যায়নি!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ইনপুট পদ্ধতি পরিবর্তন করুন"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"ডিভাইসটিকে ম্যানুয়ালি লক করা হয়েছে"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"শনাক্ত করা যায়নি"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"\'ফেস আনলক\' ফিচার ব্যবহার করতে, \'সেটিংস\' থেকে ক্যামেরার অ্যাক্সেস চালু করুন"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">সিমের পিন লিখুন। আপনি আর <xliff:g id="NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন।</item>
-      <item quantity="other">সিমের পিন লিখুন। আপনি আর <xliff:g id="NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন।</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">সিম অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আর <xliff:g id="_NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন, তারপরে এই সিমটি আর একেবারেই ব্যবহার করা যাবে না। বিশদে জানতে পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।</item>
-      <item quantity="other">সিম অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আর <xliff:g id="_NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন, তারপরে এই সিমটি আর একেবারেই ব্যবহার করা যাবে না। বিশদে জানতে পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{সিম কার্ডের পিন লিখুন। আপনি আরও # বার চেষ্টা করতে পারবেন, তারপরে ডিভাইস আনলক করতে পরিষেবা প্রদানকারীর সাথে যোগাযোগ করতে হবে।}one{সিম কার্ডের পিন লিখুন। আপনি আরও # বার চেষ্টা করতে পারবেন।}other{সিম কার্ডের পিন লিখুন। আপনি আরও # বার চেষ্টা করতে পারবেন।}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{সিম কার্ডটি এখন বন্ধ করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আরও # বার চেষ্টা করতে পারবেন, তারপরে এই সিম কার্ডটি স্থায়ীভাবে কাজ করা বন্ধ করে দেবে। বিশদ বিবরণের জন্য পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।}one{সিম কার্ডটি এখন বন্ধ করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আরও # বার চেষ্টা করতে পারবেন, তারপরে এই সিম কার্ডটি স্থায়ীভাবে কাজ করা বন্ধ করে দেবে। বিশদ বিবরণের জন্য পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।}other{সিম কার্ডটি এখন বন্ধ করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আরও # বার চেষ্টা করতে পারবেন, তারপরে এই সিম কার্ডটি স্থায়ীভাবে কাজ করা বন্ধ করে দেবে। বিশদ বিবরণের জন্য পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ডিফল্ট"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"বাবল"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"অ্যানালগ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index e0bec84..280d354 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -68,17 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Pogrešno ste unijeli lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Pogrešno ste nacrtali svoj uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"PIN za SIM karticu je netačan. Za otključavanje uređaja sada se morate obratiti svom operateru."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">PIN za SIM karticu je netačan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj.</item>
-      <item quantity="few">PIN za SIM karticu je netačan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-      <item quantity="other">PIN za SIM karticu je netačan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{PIN kôd za SIM je netačan. Imate još # pokušaj prije nego što budete morali kontaktirati mobilnog operatera da vam otključa uređaj.}one{PIN kôd za SIM je netačan. Imate još # pokušaj. }few{PIN kôd za SIM je netačan. Imate još # pokušaja. }other{PIN kôd za SIM je netačan. Imate još # pokušaja. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM kartica je neupotrebljiva. Obratite se svom operateru."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">PUK kôd za SIM karticu je netačan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj prije nego što SIM kartica postane trajno neupotrebljiva.</item>
-      <item quantity="few">PUK kôd za SIM karticu je netačan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva.</item>
-      <item quantity="other">PUK kôd za SIM karticu je netačan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{PUK kôd za SIM karticu je netačan. Imate još # pokušaj prije nego što SIM postane trajno neupotrebljiv.}one{PUK kôd za SIM karticu je netačan. Imate još # pokušaj prije nego što SIM postane trajno neupotrebljiv.}few{PUK kôd za SIM karticu je netačan. Imate još # pokušaja prije nego što SIM postane trajno neupotrebljiv.}other{PUK kôd za SIM karticu je netačan. Imate još # pokušaja prije nego što SIM postane trajno neupotrebljiv.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Korištenje PIN-a za SIM karticu nije uspjelo!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Korištenje PUK-a za SIM nije uspjelo!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promjena načina unosa"</string>
@@ -93,16 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Uređaj je ručno zaključan"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nije prepoznato"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Za otključavanje licem uključite pristup kameri"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Unesite PIN za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj.</item>
-      <item quantity="few">Unesite PIN za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-      <item quantity="other">Unesite PIN za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM kartica je onemogućena. Unesite PUK kôd da nastavite. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaj prije nego što SIM kartica postane trajno neupotrebljiva. Za više informacija kontaktirajte mobilnog operatera.</item>
-      <item quantity="few">SIM kartica je onemogućena. Unesite PUK kôd da nastavite. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Za više informacija kontaktirajte mobilnog operatera.</item>
-      <item quantity="other">SIM kartica je onemogućena. Unesite PUK kôd da nastavite. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Za više informacija kontaktirajte mobilnog operatera.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Unesite PIN za SIM. Imate još # pokušaj prije nego što budete morali kontaktirati mobilnog operatera da vam otključa uređaj.}one{Unesite PIN za SIM. Imate još # pokušaj.}few{Unesite PIN za SIM. Imate još # pokušaja.}other{Unesite PIN za SIM. Imate još # pokušaja.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM je sada onemogućen. Unesite PUK kôd da nastavite. Imate još # pokušaj prije nego što SIM postane trajno neupotrebljiv. Za više informacija kontaktirajte mobilnog operatera.}one{SIM je sada onemogućen. Unesite PUK kôd da nastavite. Imate još # pokušaja prije nego što SIM postane trajno neupotrebljiv. Za više informacija kontaktirajte mobilnog operatera.}few{SIM je sada onemogućen. Unesite PUK kôd da nastavite. Imate još # pokušaja prije nego što SIM postane trajno neupotrebljiv. Za više informacija kontaktirajte mobilnog operatera.}other{SIM je sada onemogućen. Unesite PUK kôd da nastavite. Imate još # pokušaja prije nego što SIM postane trajno neupotrebljiv. Za više informacija kontaktirajte mobilnog operatera.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Zadano"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Mjehurići"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogni"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 1e30e78..b1f5a3f 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Has escrit la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"El codi PIN de la SIM no és correcte. Contacta amb l\'operador de telefonia mòbil per desbloquejar el dispositiu."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">El codi PIN de la SIM no és correcte. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents.</item>
-      <item quantity="one">El codi PIN de la SIM no és correcte. Et queda <xliff:g id="NUMBER_0">%d</xliff:g> intent; si no l\'encertes, contacta amb l\'operador de telefonia mòbil per desbloquejar el dispositiu.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{El codi PIN de la SIM no és correcte. Et queda # intent; si no l\'encertes, contacta amb l\'operador per desbloquejar el dispositiu.}other{El codi PIN de la SIM no és correcte. Et queden # intents. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"La SIM no es pot fer servir. Contacta amb l\'operador de telefonia mòbil."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">El codi PUK de la SIM no és correcte. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents; si els esgotes tots, la SIM no es podrà tornar a fer servir.</item>
-      <item quantity="one">El codi PUK de la SIM no és correcte. Et queda <xliff:g id="NUMBER_0">%d</xliff:g> intent; si no l\'encertes, la SIM no es podrà tornar a fer servir.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{El codi PUK de la SIM no és correcte. Et queda # intent; si no l\'encertes, la SIM no es podrà tornar a fer servir.}other{El codi PUK de la SIM no és correcte. Et queden # intents; si no l\'encertes, la SIM no es podrà tornar a fer servir.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Ha fallat l\'operació del PIN de la SIM"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"No s\'ha pogut desbloquejar la SIM amb el codi PUK."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Canvia el mètode d\'introducció"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"El dispositiu s\'ha bloquejat manualment"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"No s\'ha reconegut"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Desbloqueig facial necessita accés a la càmera"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Introdueix el PIN de la SIM. Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents.</item>
-      <item quantity="one">Introdueix el PIN de la SIM. Et queda <xliff:g id="NUMBER_0">%d</xliff:g> intent; si no l\'encertes, contacta amb l\'operador de telefonia mòbil per desbloquejar el dispositiu.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queden <xliff:g id="_NUMBER_1">%d</xliff:g> intents; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador de telefonia mòbil per obtenir-ne més informació.</item>
-      <item quantity="one">La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queda <xliff:g id="_NUMBER_0">%d</xliff:g> intent; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador de telefonia mòbil per obtenir-ne més informació.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Introdueix el PIN de la SIM. Et queda # intent; si no l\'encertes, contacta amb l\'operador per desbloquejar el dispositiu.}other{Introdueix el PIN de la SIM. Et queden # intents.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queda # intent; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador per obtenir informació.}other{La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queden # intents; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador per obtenir informació.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Predeterminada"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bombolla"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analògica"</string>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index 3c37bba..1b52635 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -68,19 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali heslo. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste zadali nesprávné bezpečnostní gesto. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Zadali jste nesprávný kód PIN SIM karty. Nyní musíte za účelem odemknutí zařízení kontaktovat svého operátora."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="few">Zadali jste nesprávný kód PIN SIM karty. Máte ještě <xliff:g id="NUMBER_1">%d</xliff:g> pokusy.</item>
-      <item quantity="many">Zadali jste nesprávný kód PIN SIM karty. Máte ještě <xliff:g id="NUMBER_1">%d</xliff:g> pokusu.</item>
-      <item quantity="other">Zadali jste nesprávný kód PIN SIM karty. Máte ještě <xliff:g id="NUMBER_1">%d</xliff:g> pokusů.</item>
-      <item quantity="one">Zadali jste nesprávný PIN SIM karty. Zbývá <xliff:g id="NUMBER_0">%d</xliff:g> pokus, poté bude muset zařízení odemknout operátor.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Zadali jste nesprávný PIN SIM karty. Zbývá vám # pokus, poté zařízení bude muset odemknout operátor.}few{Zadali jste nesprávný PIN SIM karty. Máte ještě # pokusy. }many{Zadali jste nesprávný PIN SIM karty. Máte ještě # pokusu. }other{Zadali jste nesprávný PIN SIM karty. Máte ještě # pokusů. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM kartu nelze použít. Kontaktujte operátora."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="few">Nesprávný kód PUK SIM karty. Máte ještě <xliff:g id="NUMBER_1">%d</xliff:g> pokusy, poté bude SIM karta natrvalo zablokována.</item>
-      <item quantity="many">Nesprávný kód PUK SIM karty. Máte ještě <xliff:g id="NUMBER_1">%d</xliff:g> pokusu, poté bude SIM karta natrvalo zablokována.</item>
-      <item quantity="other">Nesprávný kód PUK SIM karty. Máte ještě <xliff:g id="NUMBER_1">%d</xliff:g> pokusů, poté bude SIM karta natrvalo zablokována.</item>
-      <item quantity="one">Nesprávný kód PUK SIM karty. Máte ještě <xliff:g id="NUMBER_0">%d</xliff:g> pokus, poté bude SIM karta natrvalo zablokována.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Nesprávný PUK SIM karty. Máte ještě # pokus, poté bude SIM karta natrvalo zablokována.}few{Nesprávný PUK SIM karty. Máte ještě # pokusy, poté bude SIM karta natrvalo zablokována.}many{Nesprávný PUK SIM karty. Máte ještě # pokusu, poté bude SIM karta natrvalo zablokována.}other{Nesprávný PUK SIM karty. Máte ještě # pokusů, poté bude SIM karta natrvalo zablokována.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Operace pomocí kódu PIN SIM karty se nezdařila."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Operace pomocí kódu PUK SIM karty se nezdařila."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Přepnout metodu zadávání"</string>
@@ -95,18 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Zařízení bylo ručně uzamčeno"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nerozpoznáno"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"V Nastavení zapněte přístup k fotoaparátu"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="few">Zadejte PIN SIM karty. Zbývají <xliff:g id="NUMBER_1">%d</xliff:g> pokusy.</item>
-      <item quantity="many">Zadejte PIN SIM karty. Zbývá <xliff:g id="NUMBER_1">%d</xliff:g> pokusu.</item>
-      <item quantity="other">Zadejte PIN SIM karty. Zbývá <xliff:g id="NUMBER_1">%d</xliff:g> pokusů.</item>
-      <item quantity="one">Zadejte PIN SIM karty. Zbývá <xliff:g id="NUMBER_0">%d</xliff:g> pokus, poté bude muset zařízení odemknout operátor.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="few">SIM karta je teď zablokována. Chcete-li pokračovat, zadejte kód PUK. Máte ještě <xliff:g id="_NUMBER_1">%d</xliff:g> pokusy, poté bude SIM karta natrvalo zablokována. Podrobnosti vám poskytne operátor.</item>
-      <item quantity="many">SIM karta je teď zablokována. Chcete-li pokračovat, zadejte kód PUK. Máte ještě <xliff:g id="_NUMBER_1">%d</xliff:g> pokusu, poté bude SIM karta natrvalo zablokována. Podrobnosti vám poskytne operátor.</item>
-      <item quantity="other">SIM karta je teď zablokována. Chcete-li pokračovat, zadejte kód PUK. Máte ještě <xliff:g id="_NUMBER_1">%d</xliff:g> pokusů, poté bude SIM karta natrvalo zablokována. Podrobnosti vám poskytne operátor.</item>
-      <item quantity="one">SIM karta je teď zablokována. Chcete-li pokračovat, zadejte kód PUK. Máte ještě <xliff:g id="_NUMBER_0">%d</xliff:g> pokus, poté bude SIM karta natrvalo zablokována. Podrobnosti vám poskytne operátor.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Zadejte PIN SIM karty. Zbývá # pokus, poté bude muset zařízení odemknout operátor.}few{Zadejte PIN SIM karty. Zbývají # pokusy.}many{Zadejte PIN SIM karty. Zbývá # pokusu.}other{Zadejte PIN SIM karty. Zbývá # pokusů.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM karta je nyní zablokována. Chcete-li pokračovat, zadejte PUK. Máte ještě # pokus, poté bude SIM karta natrvalo zablokována. Podrobnosti poskytne operátor.}few{SIM karta je nyní zablokována. Chcete-li pokračovat, zadejte PUK. Máte ještě # pokusy, poté bude SIM karta natrvalo zablokována. Podrobnosti poskytne operátor.}many{SIM karta je nyní zablokována. Chcete-li pokračovat, zadejte PUK. Máte ještě # pokusu, poté bude SIM karta natrvalo zablokována. Podrobnosti poskytne operátor.}other{SIM karta je nyní zablokována. Chcete-li pokračovat, zadejte PUK. Máte ještě # pokusů, poté bude SIM karta natrvalo zablokována. Podrobnosti poskytne operátor.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Výchozí"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bublina"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogové"</string>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index 0774c52..cb8ad8f 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Forkert pinkode til SIM-kort. Du er nu nødt til at kontakte dit mobilselskab for at låse din enhed op."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Forkert pinkode til SIM-kort. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøg tilbage.</item>
-      <item quantity="other">Forkert pinkode til SIM-kort. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøg tilbage.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Du har angivet en forkert pinkode til SIM-kortet. Du har # forsøg tilbage, før du skal kontakte dit mobilselskab for at få låst din enhed op.}one{Du har angivet en forkert pinkode til SIM-kortet. Du har # forsøg tilbage. }other{Du har angivet en forkert pinkode til SIM-kortet. Du har # forsøg tilbage. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-kortet er ubrugeligt. Kontakt dit mobilselskab."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Forkert PUK-kode til SIM-kort. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt.</item>
-      <item quantity="other">Forkert PUK-kode til SIM-kort. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Du har angivet en forkert PUK-kode til SIM-kortet. Du har # forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt.}one{Du har angivet en forkert PUK-kode til SIM-kortet. Du har # forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt.}other{Du har angivet en forkert PUK-kode til SIM-kortet. Du har # forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Pinkoden til SIM-kortet blev afvist"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"PUK-koden til SIM-kortet blev afvist"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Skift indtastningsmetode"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Enheden blev låst manuelt"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Ikke genkendt"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Aktivér kameraadgang i Indstillinger for at bruge ansigtslås"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Angiv pinkoden til SIM-kortet. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøg tilbage.</item>
-      <item quantity="other">Angiv pinkoden til SIM-kortet. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøg tilbage.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har <xliff:g id="_NUMBER_1">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.</item>
-      <item quantity="other">SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har <xliff:g id="_NUMBER_1">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Angiv pinkoden til SIM-kortet. Du har # forsøg tilbage, før du skal kontakte dit mobilselskab for at låse din enhed op.}one{Angiv pinkoden til SIM-kortet. Du har # forsøg tilbage.}other{Angiv pinkoden til SIM-kortet. Du har # forsøg tilbage.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har # forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.}one{SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har # forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.}other{SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har # forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Standard"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Boble"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index c46c08f..579c514 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Du hast dein Passwort <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch eingegeben.\n\nBitte versuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. \n\nBitte versuche es in <xliff:g id="NUMBER_1">%2$d</xliff:g> Sekunden noch einmal."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Falscher PIN-Code der SIM-Karte. Bitte wende dich an deinen Mobilfunkanbieter, damit er dein Gerät entsperrt."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Falscher PIN-Code der SIM-Karte. Du hast noch <xliff:g id="NUMBER_1">%d</xliff:g> Versuche.</item>
-      <item quantity="one">Falscher PIN-Code der SIM-Karte. Du hast noch <xliff:g id="NUMBER_0">%d</xliff:g> Versuch, bevor du das Gerät von deinem Mobilfunkanbieter entsperren lassen musst.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Falscher PIN-Code für die SIM-Karte. Du hast noch # Versuch, bevor das Gerät nur noch vom Mobilfunkanbieter entsperrt werden kann.}other{Falscher PIN-Code für die SIM-Karte. Du hast noch # Versuche. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"Die SIM-Karte kann nicht verwendet werden. Bitte wende dich an deinen Mobilfunkanbieter."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Falscher PUK-Code der SIM-Karte. Du hast noch <xliff:g id="NUMBER_1">%d</xliff:g> Versuche, bevor deine SIM-Karte endgültig gesperrt wird.</item>
-      <item quantity="one">Falscher PUK-Code der SIM-Karte. Du hast noch <xliff:g id="NUMBER_0">%d</xliff:g> Versuch, bevor deine SIM-Karte endgültig gesperrt wird.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Falscher PUK-Code für die SIM-Karte. Du hast noch # Versuch, bevor die SIM-Karte endgültig gesperrt wird.}other{Falscher PUK-Code für die SIM-Karte. Du hast noch # Versuche, bevor die SIM-Karte endgültig gesperrt wird.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Fehler beim Entsperren der SIM-Karte mit der PIN."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Fehler beim Entsperren der SIM-Karte mithilfe des PUK-Codes."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Eingabemethode wechseln"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Gerät manuell gesperrt"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nicht erkannt"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Die Gesichtsentsperrung benötigt Kamerazugriff"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Gib die PIN für die SIM-Karte ein. Du hast noch <xliff:g id="NUMBER_1">%d</xliff:g> Versuche.</item>
-      <item quantity="one">Gib die PIN für die SIM-Karte ein. Du hast noch <xliff:g id="NUMBER_0">%d</xliff:g> Versuch, bevor das Gerät nur noch vom Mobilfunkanbieter entsperrt werden kann.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Du hast noch <xliff:g id="_NUMBER_1">%d</xliff:g> Versuche, bevor die SIM-Karte endgültig gesperrt wird. Weitere Informationen erhältst du von deinem Mobilfunkanbieter.</item>
-      <item quantity="one">Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Du hast noch <xliff:g id="_NUMBER_0">%d</xliff:g> Versuch, bevor die SIM-Karte endgültig gesperrt wird. Weitere Informationen erhältst du von deinem Mobilfunkanbieter.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Gib die PIN für die SIM-Karte ein. Du hast noch # Versuch, bevor das Gerät nur noch vom Mobilfunkanbieter entsperrt werden kann.}other{Gib die PIN für die SIM-Karte ein. Du hast noch # Versuche.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Du hast noch # Versuch, bevor die SIM-Karte endgültig gesperrt wird. Wende dich für weitere Informationen an deinen Mobilfunkanbieter.}other{Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Du hast noch # Versuche, bevor die SIM-Karte endgültig gesperrt wird. Wende dich für weitere Informationen an deinen Mobilfunkanbieter.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Standard"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 73afafa7..8dd5d20 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%2$d</xliff:g> δευτερόλεπτα."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος<xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%2$d</xliff:g> δευτερόλεπτα."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Λανθασμένος κωδικός PIN κάρτας SIM. Θα πρέπει να επικοινωνήσετε με την εταιρεία κινητής τηλεφωνίας σας για να ξεκλειδώσετε τη συσκευή σας."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Λανθασμένος κωδικός PIN κάρτας SIM. Απομένουν άλλες <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες.</item>
-      <item quantity="one">Λανθασμένος κωδικός PIN κάρτας SIM. Απομένει άλλη <xliff:g id="NUMBER_0">%d</xliff:g> προσπάθεια. Στη συνέχεια, θα πρέπει να επικοινωνήσετε με την εταιρεία κινητής τηλεφωνίας σας για να ξεκλειδώσετε τη συσκευή σας.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Εσφαλμένος κωδικός PIN κάρτας SIM. Απομένει άλλη # προσπάθεια. Στη συνέχεια, θα πρέπει να επικοινωνήσετε με τον πάροχο κινητής τηλεφωνίας σας για να ξεκλειδώσετε τη συσκευή σας.}other{Εσφαλμένος κωδικός PIN κάρτας SIM. Απομένουν # προσπάθειες. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"Η κάρτα SIM δεν μπορεί να χρησιμοποιηθεί. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας σας."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Λανθασμένος κωδικός PUK κάρτας SIM. Απομένουν άλλες <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM.</item>
-      <item quantity="one">Λανθασμένος κωδικός PUK κάρτας SIM. Απομένει άλλη <xliff:g id="NUMBER_0">%d</xliff:g> προσπάθεια προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Λανθασμένος κωδικός PUK κάρτας SIM. Απομένει άλλη # προσπάθεια προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM.}other{Εσφαλμένος κωδικός PUK κάρτας SIM. Απομένουν # προσπάθειες προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Αποτυχία λειτουργίας κωδικού PIN κάρτας SIM!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Αποτυχία λειτουργίας κωδικού PUK κάρτας SIM!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Εναλλαγή μεθόδου εισαγωγής"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Η συσκευή κλειδώθηκε με μη αυτόματο τρόπο"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Δεν αναγνωρίστηκε"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Ενεργοπ. πρόσβ. κάμ. στις Ρυθμ. για Ξεκλείδ. με το πρόσωπο."</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Εισαγάγετε τον αριθμό PIN της κάρτας SIM. Απομένουν άλλες <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες.</item>
-      <item quantity="one">Εισαγάγετε τον αριθμό PIN της κάρτας SIM. Απομένει άλλη <xliff:g id="NUMBER_0">%d</xliff:g> προσπάθεια. Στη συνέχεια, θα πρέπει να επικοινωνήσετε με τον πάροχο κινητής τηλεφωνίας, για να ξεκλειδώσετε τη συσκευή.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">Η κάρτα SIM απενεργοποιήθηκε. Καταχωρίστε τον κωδικό PUK, για να συνεχίσετε. Απομένουν <xliff:g id="_NUMBER_1">%d</xliff:g> ακόμη προσπάθειες προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας για λεπτομέρειες.</item>
-      <item quantity="one">Η κάρτα SIM απενεργοποιήθηκε. Καταχωρίστε τον κωδικό PUK, για να συνεχίσετε. Απομένει <xliff:g id="_NUMBER_0">%d</xliff:g> ακόμη προσπάθεια προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας για λεπτομέρειες.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Εισαγάγετε τον κωδικό PIN της κάρτας SIM. Απομένει άλλη # προσπάθεια. Στη συνέχεια, θα πρέπει να επικοινωνήσετε με τον πάροχο κινητής τηλεφωνίας, για να ξεκλειδώσετε τη συσκευή.}other{Εισαγάγετε τον κωδικό PIN της κάρτας SIM. Απομένουν # προσπάθειες.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Η κάρτα SIM απενεργοποιήθηκε. Εισαγάγετε τον κωδικό PUK, για να συνεχίσετε. Απομένει # ακόμη προσπάθεια προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας για λεπτομέρειες.}other{Η κάρτα SIM απενεργοποιήθηκε. Εισαγάγετε τον κωδικό PUK, για να συνεχίσετε. Απομένουν # ακόμη προσπάθειες προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας για λεπτομέρειες.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Προεπιλογή"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Συννεφάκι"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Αναλογικό"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index 0d08c42..865ebab 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Incorrect SIM PIN code; you must now contact your operator to unlock your device."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Incorrect SIM PIN code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
-      <item quantity="one">Incorrect SIM PIN code. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before you must contact your provider to unlock your device.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Incorrect SIM PIN code; you have # remaining attempt before you must contact your operator to unlock your device.}other{Incorrect SIM PIN code; you have # remaining attempts. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM is unusable. Contact your operator."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Incorrect SIM PUK code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item>
-      <item quantity="one">Incorrect SIM PUK code. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Incorrect SIM PUK code; you have # remaining attempt before SIM becomes permanently unusable.}other{Incorrect SIM PUK code, you have # remaining attempts before SIM becomes permanently unusable.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN operation failed!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK operation failed!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Device was locked manually"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Not recognised"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"To use Face Unlock, turn on camera access in Settings"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Enter SIM PIN. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
-      <item quantity="one">Enter SIM PIN. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before you must contact your operator to unlock your device.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item>
-      <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Enter SIM PIN. You have # remaining attempt before you must contact your operator to unlock your device.}other{Enter SIM PIN. You have # remaining attempts.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM is now disabled. Enter PUK code to continue. You have # remaining attempt before SIM becomes permanently unusable. Contact operator for details.}other{SIM is now disabled. Enter PUK code to continue. You have # remaining attempts before SIM becomes permanently unusable. Contact operator for details.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Default"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogue"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
index 3356ec9..9b4df35 100644
--- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Incorrect SIM PIN code you must now contact your carrier to unlock your device."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Incorrect SIM PIN code, you have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
-      <item quantity="one">Incorrect SIM PIN code, you have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before you must contact your carrier to unlock your device.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Incorrect SIM PIN code, you have # remaining attempt before you must contact your carrier to unlock your device.}other{Incorrect SIM PIN code, you have # remaining attempts. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM is unusable. Contact your carrier."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Incorrect SIM PUK code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item>
-      <item quantity="one">Incorrect SIM PUK code. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Incorrect SIM PUK code; you have # remaining attempt before SIM becomes permanently unusable.}other{Incorrect SIM PUK code, you have # remaining attempts before SIM becomes permanently unusable.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN operation failed!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK operation failed!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Device was locked manually"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Not recognised"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"To use Face Unlock, turn on camera access in Settings"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Enter SIM PIN. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
-      <item quantity="one">Enter SIM PIN. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before you must contact your carrier to unlock your device.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact carrier for details.</item>
-      <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact carrier for details.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Enter SIM PIN. You have # remaining attempt before you must contact your carrier to unlock your device.}other{Enter SIM PIN. You have # remaining attempts.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM is now disabled. Enter PUK code to continue. You have # remaining attempt before SIM becomes permanently unusable. Contact carrier for details.}other{SIM is now disabled. Enter PUK code to continue. You have # remaining attempts before SIM becomes permanently unusable. Contact carrier for details.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Default"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogue"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index 0d08c42..865ebab 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Incorrect SIM PIN code; you must now contact your operator to unlock your device."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Incorrect SIM PIN code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
-      <item quantity="one">Incorrect SIM PIN code. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before you must contact your provider to unlock your device.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Incorrect SIM PIN code; you have # remaining attempt before you must contact your operator to unlock your device.}other{Incorrect SIM PIN code; you have # remaining attempts. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM is unusable. Contact your operator."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Incorrect SIM PUK code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item>
-      <item quantity="one">Incorrect SIM PUK code. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Incorrect SIM PUK code; you have # remaining attempt before SIM becomes permanently unusable.}other{Incorrect SIM PUK code, you have # remaining attempts before SIM becomes permanently unusable.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN operation failed!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK operation failed!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Device was locked manually"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Not recognised"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"To use Face Unlock, turn on camera access in Settings"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Enter SIM PIN. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
-      <item quantity="one">Enter SIM PIN. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before you must contact your operator to unlock your device.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item>
-      <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Enter SIM PIN. You have # remaining attempt before you must contact your operator to unlock your device.}other{Enter SIM PIN. You have # remaining attempts.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM is now disabled. Enter PUK code to continue. You have # remaining attempt before SIM becomes permanently unusable. Contact operator for details.}other{SIM is now disabled. Enter PUK code to continue. You have # remaining attempts before SIM becomes permanently unusable. Contact operator for details.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Default"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogue"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index 0d08c42..865ebab 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%2$d</xliff:g> seconds."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Incorrect SIM PIN code; you must now contact your operator to unlock your device."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Incorrect SIM PIN code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
-      <item quantity="one">Incorrect SIM PIN code. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before you must contact your provider to unlock your device.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Incorrect SIM PIN code; you have # remaining attempt before you must contact your operator to unlock your device.}other{Incorrect SIM PIN code; you have # remaining attempts. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM is unusable. Contact your operator."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Incorrect SIM PUK code. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item>
-      <item quantity="one">Incorrect SIM PUK code. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Incorrect SIM PUK code; you have # remaining attempt before SIM becomes permanently unusable.}other{Incorrect SIM PUK code, you have # remaining attempts before SIM becomes permanently unusable.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN operation failed!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK operation failed!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Switch input method"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Device was locked manually"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Not recognised"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"To use Face Unlock, turn on camera access in Settings"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Enter SIM PIN. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
-      <item quantity="one">Enter SIM PIN. You have <xliff:g id="NUMBER_0">%d</xliff:g> remaining attempt before you must contact your operator to unlock your device.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item>
-      <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Enter SIM PIN. You have # remaining attempt before you must contact your operator to unlock your device.}other{Enter SIM PIN. You have # remaining attempts.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM is now disabled. Enter PUK code to continue. You have # remaining attempt before SIM becomes permanently unusable. Contact operator for details.}other{SIM is now disabled. Enter PUK code to continue. You have # remaining attempts before SIM becomes permanently unusable. Contact operator for details.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Default"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogue"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
index 3c31942..afb3d65 100644
--- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‏‏‎‎You have incorrectly typed your password ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ times. ‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Try again in ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%2$d</xliff:g>‎‏‎‎‏‏‏‎ seconds.‎‏‎‎‏‎"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‎‎‎‎You have incorrectly drawn your unlock pattern ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ times. ‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Try again in ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%2$d</xliff:g>‎‏‎‎‏‏‏‎ seconds.‎‏‎‎‏‎"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎Incorrect SIM PIN code you must now contact your carrier to unlock your device.‎‏‎‎‏‎"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎Incorrect SIM PIN code, you have ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%d</xliff:g>‎‏‎‎‏‏‏‎ remaining attempts.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎Incorrect SIM PIN code, you have ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%d</xliff:g>‎‏‎‎‏‏‏‎ remaining attempt before you must contact your carrier to unlock your device.‎‏‎‎‏‎</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎Incorrect SIM PIN code, you have # remaining attempt before you must contact your carrier to unlock your device.‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎Incorrect SIM PIN code, you have # remaining attempts. ‎‏‎‎‏‎}}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎SIM is unusable. Contact your carrier.‎‏‎‎‏‎"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‎‏‏‎‎Incorrect SIM PUK code, you have ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%d</xliff:g>‎‏‎‎‏‏‏‎ remaining attempts before SIM becomes permanently unusable.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‎‏‏‎‎Incorrect SIM PUK code, you have ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%d</xliff:g>‎‏‎‎‏‏‏‎ remaining attempt before SIM becomes permanently unusable.‎‏‎‎‏‎</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎Incorrect SIM PUK code, you have # remaining attempt before SIM becomes permanently unusable.‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎Incorrect SIM PUK code, you have # remaining attempts before SIM becomes permanently unusable.‎‏‎‎‏‎}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎SIM PIN operation failed!‎‏‎‎‏‎"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎SIM PUK operation failed!‎‏‎‎‏‎"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎Switch input method‎‏‎‎‏‎"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‎‎‎Device was locked manually‎‏‎‎‏‎"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‎Not recognized‎‏‎‎‏‎"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎To use Face Unlock, turn on camera access in Settings‎‏‎‎‏‎"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‎Enter SIM PIN. You have ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%d</xliff:g>‎‏‎‎‏‏‏‎ remaining attempts.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‎Enter SIM PIN. You have ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%d</xliff:g>‎‏‎‎‏‏‏‎ remaining attempt before you must contact your carrier to unlock your device.‎‏‎‎‏‎</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‎SIM is now disabled. Enter PUK code to continue. You have ‎‏‎‎‏‏‎<xliff:g id="_NUMBER_1">%d</xliff:g>‎‏‎‎‏‏‏‎ remaining attempts before SIM becomes permanently unusable. Contact carrier for details.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‎SIM is now disabled. Enter PUK code to continue. You have ‎‏‎‎‏‏‎<xliff:g id="_NUMBER_0">%d</xliff:g>‎‏‎‎‏‏‏‎ remaining attempt before SIM becomes permanently unusable. Contact carrier for details.‎‏‎‎‏‎</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‎Enter SIM PIN. You have # remaining attempt before you must contact your carrier to unlock your device.‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‎Enter SIM PIN. You have # remaining attempts.‎‏‎‎‏‎}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‎SIM is now disabled. Enter PUK code to continue. You have # remaining attempt before SIM becomes permanently unusable. Contact carrier for details.‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‎SIM is now disabled. Enter PUK code to continue. You have # remaining attempts before SIM becomes permanently unusable. Contact carrier for details.‎‏‎‎‏‎}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎Default‎‏‎‎‏‎"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎Bubble‎‏‎‎‏‎"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎Analog‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index 708e633..ea3b8a7 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Escribiste tu contraseña <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Dibujaste tu patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"El código PIN de la tarjeta SIM es incorrecto. Debes comunicarte con tu proveedor para desbloquear el dispositivo."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">El código PIN de la tarjeta SIM es incorrecto. Te quedan <xliff:g id="NUMBER_1">%d</xliff:g> intentos más.</item>
-      <item quantity="one">El código PIN de la tarjeta SIM es incorrecto. Te queda <xliff:g id="NUMBER_0">%d</xliff:g> intento antes de que debas comunicarte con tu proveedor para desbloquear el dispositivo.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{El código PIN de la tarjeta SIM es incorrecto. Tienes # intento restante antes de que debas comunicarte con tu operador para desbloquear el dispositivo.}other{El código PIN de la tarjeta SIM es incorrecto. Tienes # intentos restantes. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"La tarjeta SIM no se puede usar. Comunícate con tu proveedor."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">El código PUK de la tarjeta SIM es incorrecto. Tienes <xliff:g id="NUMBER_1">%d</xliff:g> intentos más antes de que la tarjeta SIM quede inutilizable de manera permanente.</item>
-      <item quantity="one">El código PUK de la tarjeta SIM es incorrecto. Tienes <xliff:g id="NUMBER_0">%d</xliff:g> intento antes de que la tarjeta SIM quede inutilizable de manera permanente.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{El código PUK de la tarjeta SIM es incorrecto. Tienes # intento restante antes de que la tarjeta SIM quede inutilizable permanentemente.}other{El código PUK de la tarjeta SIM es incorrecto. Tienes # intentos restantes antes de que la tarjeta SIM quede inutilizable permanentemente.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Se produjo un error al desbloquear la tarjeta SIM con el PIN."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Se produjo un error al desbloquear la tarjeta SIM con el PUK."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambiar método de entrada"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"El dispositivo se bloqueó de forma manual"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"No se reconoció"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Activa acceso a cámara en Config. y usa Desb. facial"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Ingresa el PIN de la SIM. Quedan <xliff:g id="NUMBER_1">%d</xliff:g> intentos más.</item>
-      <item quantity="one">Ingresa el PIN de la SIM. Queda <xliff:g id="NUMBER_0">%d</xliff:g> intento antes de que debas comunicarte con tu proveedor para desbloquear el dispositivo.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">Se inhabilitó la SIM. Para continuar, ingresa el código PUK. Te quedan <xliff:g id="_NUMBER_1">%d</xliff:g> intentos más antes de que la SIM quede inutilizable permanentemente. Comunícate con tu proveedor para obtener más detalles.</item>
-      <item quantity="one">Se inhabilitó la SIM. Para continuar, ingresa el código PUK. Te queda <xliff:g id="_NUMBER_0">%d</xliff:g> intento más antes de que la SIM quede inutilizable permanentemente. Comunícate con tu proveedor para obtener más detalles.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Ingresa el PIN de la tarjeta SIM. Tienes # intento restante antes de que debas comunicarte con tu operador para desbloquear el dispositivo.}other{Ingresa el PIN de la tarjeta SIM. Tienes # intentos restantes.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Se inhabilitó la tarjeta SIM. Para continuar, ingresa el código PUK. Tienes # intento restante antes de que la SIM quede inutilizable permanentemente. Comunícate con tu operador para conocer más detalles.}other{Se inhabilitó la tarjeta SIM. Para continuar, ingresa el código PUK. Tienes # intentos restantes antes de que la SIM quede inutilizable permanentemente. Comunícate con tu operador para conocer más detalles.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Predeterminado"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Burbuja"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analógico"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index b498c0e..0c267aa 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al introducir la contraseña. \n\nVuelve a intentarlo dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Has fallado <xliff:g id="NUMBER_0">%1$d</xliff:g> veces al dibujar el patrón de desbloqueo. \n\nVuelve a intentarlo dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"El código PIN de la tarjeta SIM es incorrecto. Debes ponerte en contacto con tu operador para desbloquear el dispositivo."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">El código PIN de la tarjeta SIM es incorrecto. Quedan <xliff:g id="NUMBER_1">%d</xliff:g> intentos.</item>
-      <item quantity="one">El código PIN de la tarjeta SIM es incorrecto. Queda <xliff:g id="NUMBER_0">%d</xliff:g> intento para tener que ponerte en contacto con tu operador para desbloquear el dispositivo.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Código PIN de la SIM incorrecto. Te queda # intento antes de tener que ponerte en contacto con tu operador para desbloquear el dispositivo.}other{Código PIN de la SIM incorrecto. Te quedan # intentos. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"La tarjeta SIM no se puede utilizar. Ponte en contacto con tu operador."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">El código PUK de la tarjeta SIM es incorrecto. Quedan <xliff:g id="NUMBER_1">%d</xliff:g> intentos paraa que la tarjeta SIM no se pueda utilizar de forma permanente.</item>
-      <item quantity="one">El código PUK de la tarjeta SIM es incorrecto. Queda <xliff:g id="NUMBER_0">%d</xliff:g> intento para que la tarjeta SIM no se pueda utilizar de forma permanente.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Código PUK de la SIM incorrecto. Te queda # intento antes de que la SIM quede inservible permanentemente.}other{Código PUK de la SIM incorrecto. Te quedan # intentos antes de que la SIM quede inservible permanentemente.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"No se ha podido desbloquear la tarjeta SIM con el código PIN."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"No se ha podido desbloquear la tarjeta SIM con el código PUK."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambiar método de introducción"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"El dispositivo se ha bloqueado manualmente"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"No se reconoce"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Desbloqueo facial: activa el acceso a la cámara"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Introduce el PIN de la tarjeta SIM. Te quedan <xliff:g id="NUMBER_1">%d</xliff:g> intentos.</item>
-      <item quantity="one">Introduce el PIN de la tarjeta SIM. Te queda <xliff:g id="NUMBER_0">%d</xliff:g> intento para tener que ponerte en contacto con tu operador para desbloquear el dispositivo.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">La tarjeta SIM está inhabilitada. Introduce el código PUK para continuar. Te quedan <xliff:g id="_NUMBER_1">%d</xliff:g> intentos para que la tarjeta SIM quede inservible de forma permanente. Ponte en contacto con tu operador para obtener más información.</item>
-      <item quantity="one">La tarjeta SIM está inhabilitada. Introduce el código PUK para continuar. Te queda <xliff:g id="_NUMBER_0">%d</xliff:g> intento para que la tarjeta SIM quede inservible de forma permanente. Ponte en contacto con tu operador para obtener más información.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Introduce el PIN de la SIM. Te queda # intento antes de tener que ponerte en contacto con tu operador para desbloquear el dispositivo.}other{Introduce el PIN de la SIM. Te quedan # intentos.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{La SIM se ha inhabilitado. Introduce el código PUK para continuar. Te queda # intento antes de que la SIM quede inservible permanentemente. Ponte en contacto con tu operador para obtener más información.}other{La SIM se ha inhabilitado. Introduce el código PUK para continuar. Te quedan # intentos antes de que la SIM quede inservible permanentemente. Ponte en contacto con tu operador para obtener más información.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Predeterminado"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Burbuja"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analógico"</string>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index 74ce06c..f4c99c4 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Olete parooli <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast uuesti."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Olete oma avamismustrit <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti joonistanud. \n\nProovige <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundi pärast uuesti."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM-kaardi vale PIN-kood. Seadme avamiseks peate nüüd ühendust võtma oma operaatoriga."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM-kaardi vale PIN-kood. Teil on jäänud veel <xliff:g id="NUMBER_1">%d</xliff:g> katset.</item>
-      <item quantity="one">SIM-kaardi vale PIN-kood. Teil on jäänud veel <xliff:g id="NUMBER_0">%d</xliff:g> katse enne, kui peate seadme avamiseks operaatoriga ühendust võtma.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM-i vale PIN-kood. Teil on veel # katse, enne kui peate seadme avamiseks operaatoriga ühendust võtma.}other{SIM-i vale PIN-kood. Teil on veel # katset. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-kaart on kasutamiskõlbmatu. Võtke ühendust operaatoriga."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM-kaardi vale PUK-kood. Teil on jäänud veel <xliff:g id="NUMBER_1">%d</xliff:g> katset enne, kui SIM-kaart jäädavalt lukustatakse.</item>
-      <item quantity="one">SIM-kaardi vale PUK-kood. Teil on jäänud veel <xliff:g id="NUMBER_0">%d</xliff:g> katse enne, kui SIM-kaart jäädavalt lukustatakse.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM-i vale PUK-kood. Teil on veel # katse, enne kui SIM püsivalt lukustatakse.}other{SIM-i vale PUK-kood. Teil on veel # katset, enne kui SIM püsivalt lukustatakse.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM-kaardi PIN-koodi toiming ebaõnnestus."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM-kaardi PUK-koodi toiming ebaõnnestus."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Vaheta sisestusmeetodit"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Seade lukustati käsitsi"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Ei tuvastatud"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Näoga avamise kasutamiseks andke seadetes juurdepääs kaamerale"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Sisestage SIM-kaardi PIN-kood. Jäänud on <xliff:g id="NUMBER_1">%d</xliff:g> katset.</item>
-      <item quantity="one">Sisestage SIM-kaardi PIN-kood. Jäänud on <xliff:g id="NUMBER_0">%d</xliff:g> katse enne, kui peate seadme avamiseks ühendust võtma operaatoriga.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM-kaart on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Teil on jäänud veel <xliff:g id="_NUMBER_1">%d</xliff:g> katset enne, kui SIM-kaart püsivalt lukustatakse. Lisateavet küsige operaatorilt.</item>
-      <item quantity="one">SIM-kaart on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Teil on jäänud veel <xliff:g id="_NUMBER_0">%d</xliff:g> katse enne, kui SIM-kaart püsivalt lukustatakse. Lisateavet küsige operaatorilt.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Sisestage SIM-i PIN-kood. Teil on veel # katse, enne kui peate seadme avamiseks operaatoriga ühendust võtma.}other{Sisestage SIM-i PIN-kood. Teil on veel # katset.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Teil on veel # katse enne, kui SIM püsivalt lukustatakse. Lisateavet küsige operaatorilt.}other{SIM on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Teil on veel # katset enne, kui SIM püsivalt lukustatakse. Lisateavet küsige operaatorilt.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Vaikenumbrilaud"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Mull"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analoog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 19fc68a..bf94915 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz idatzi duzu pasahitza, baina huts egin duzu denetan. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"<xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz marraztu duzu desblokeatzeko eredua, baina huts egin duzu denetan. \n\nSaiatu berriro <xliff:g id="NUMBER_1">%2$d</xliff:g> segundo barru."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIMaren PIN kodea ez da zuzena. Gailua desblokeatzeko, operadorearekin jarri beharko duzu harremanetan."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Ez da zuzena SIM txartelaren PIN kodea. <xliff:g id="NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu gailua desblokeatzeko.</item>
-      <item quantity="one">Ez da zuzena SIM txartelaren PIN kodea. <xliff:g id="NUMBER_0">%d</xliff:g> saiakera geratzen zaizu gailua desblokeatzeko.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Oker idatzi duzu SIMaren PIN kodea. # saiakera geratzen zaizu gailua desblokeatzeko operadorearekin harremanetan jarri behar izan aurretik.}other{Oker idatzi duzu SIMaren PIN kodea. # saiakera geratzen zaizkizu gailua desblokeatzeko operadorearekin harremanetan jarri behar izan aurretik. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM txartela erabilgaitza da. Jarri operadorearekin harremanetan."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Ez da zuzena SIM txartelaren PUK kodea. <xliff:g id="NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu SIM txartela betiko erabilgaitz geratu aurretik.</item>
-      <item quantity="one">Ez da zuzena SIM txartelaren PUK kodea. <xliff:g id="NUMBER_0">%d</xliff:g> saiakera geratzen zaizu SIM txartela betiko erabilgaitz geratu aurretik.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Oker idatzi duzu SIMaren PUK kodea. # saiakera geratzen zaizu SIMa betiko ez-erabilgarri geratu aurretik.}other{Oker idatzi duzu SIMaren PUK kodea. # saiakera geratzen zaizkizu SIMa betiko ez-erabilgarri geratu aurretik.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Huts egin du SIM txartelaren PIN kodearen eragiketak!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Huts egin du SIM txartelaren PUK kodearen eragiketak!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Aldatu idazketa-metodoa"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Eskuz blokeatu da gailua"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Ez da ezagutu"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Aurpegi bidezko desblokeoak kamera atzitzeko baimena behar du"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Idatzi SIMaren PINa. <xliff:g id="NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu.</item>
-      <item quantity="one">Idatzi SIMaren PINa. <xliff:g id="NUMBER_0">%d</xliff:g> saiakera geratzen zaizu; oker idatziz gero, operadoreari eskatu beharko diozu gailua desblokeatzeko.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">Desgaitu egin da SIM txartela. Aurrera egiteko, idatzi PUK kodea. <xliff:g id="_NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu SIM txartela betiko erabilgaitz geratu aurretik. Xehetasunak lortzeko, jarri operadorearekin harremanetan.</item>
-      <item quantity="one">Desgaitu egin da SIM txartela. Aurrera egiteko, idatzi PUK kodea. <xliff:g id="_NUMBER_0">%d</xliff:g> saiakera geratzen zaizu SIM txartela betiko erabilgaitz geratu aurretik. Xehetasunak lortzeko, jarri operadorearekin harremanetan.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Idatzi SIMaren PINa. # saiakera geratzen zaizu gailua desblokeatzeko operadorearekin harremanetan jarri behar izan aurretik.}other{Idatzi SIMaren PINa. # saiakera gelditzen zaizkizu.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Orain, SIMa desgaituta dago. Aurrera egiteko, idatzi PUK kodea. # saiakera geratzen zaizu SIMa betiko ez-erabilgarri geratu aurretik. Xehetasunak lortzeko, jarri operadorearekin harremanetan.}other{Orain, SIMa desgaituta dago. Aurrera egiteko, idatzi PUK kodea. # saiakera geratzen zaizkizu SIMa betiko ez-erabilgarri geratu aurretik. Xehetasunak lortzeko, jarri operadorearekin harremanetan.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Lehenetsia"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Puxikak"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogikoa"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index 6b90e89..ca22227 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"گذرواژه خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‌اید. \n\nلطفاً پس‌از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"کد پین سیم‌کارت اشتباه است، اکنون برای باز کردن قفل دستگاهتان باید با شرکت مخابراتی تماس بگیرید."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">کد پین سیم‌کارت اشتباه است، <xliff:g id="NUMBER_1">%d</xliff:g> بار دیگر می‌توانید تلاش کنید.</item>
-      <item quantity="other">کد پین سیم‌کارت اشتباه است، <xliff:g id="NUMBER_1">%d</xliff:g> بار دیگر می‌توانید تلاش کنید.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{کد پین سیم‌کارت اشتباه است. # فرصت دیگر باقی مانده است و پس‌از آن برای باز کردن قفل دستگاه باید با شرکت مخابراتی‌تان تماس بگیرید.}one{کد پین سیم‌کارت اشتباه است، # فرصت دیگر دارید. }other{کد پین سیم‌کارت اشتباه است، # فرصت دیگر دارید. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"سیم‌کارت غیرقابل استفاده است. با شرکت مخابراتی‌تان تماس بگیرید."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">‏کد PUK سیم‌کارت اشتباه است، <xliff:g id="NUMBER_1">%d</xliff:g> بار دیگر می‌توانید تلاش کنید و پس از آن سیم‌کارت برای همیشه غیرقابل استفاده می‌شود.</item>
-      <item quantity="other">‏کد PUK سیم‌کارت اشتباه است، <xliff:g id="NUMBER_1">%d</xliff:g> بار دیگر می‌توانید تلاش کنید و پس از آن سیم‌کارت برای همیشه غیرقابل استفاده می‌شود.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{‏کد PUK سیم‌کارت اشتباه است، # فرصت دیگر باقی مانده است و پس‌از آن سیم‌کارت برای همیشه غیرقابل‌استفاده می‌شود.}one{‏کد PUK سیم‌کارت اشتباه است، # فرصت دیگر باقی مانده است و پس‌از آن سیم‌کارت برای همیشه غیرقابل‌استفاده می‌شود.}other{‏کد PUK سیم‌کارت اشتباه است، # فرصت دیگر باقی مانده است و پس‌از آن سیم‌کارت برای همیشه غیرقابل‌استفاده می‌شود.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"عملیات پین سیم‌کارت ناموفق بود!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"‏عملیات PUK سیم‌کارت ناموفق بود!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"تغییر روش ورودی"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"دستگاه به‌صورت دستی قفل شده است"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"شناسایی نشد"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"برای استفاده از قفل‌گشایی با چهره، دسترسی دوربین را در تنظیمات روشن کنید"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">پین سیم‌کارت را وارد کنید. <xliff:g id="NUMBER_1">%d</xliff:g> تلاش دیگری باقی مانده است.</item>
-      <item quantity="other">پین سیم‌کارت را وارد کنید. <xliff:g id="NUMBER_1">%d</xliff:g> تلاش دیگری باقی مانده است.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">‏سیم‌کارت اکنون غیرفعال است. برای ادامه دادن کد PUK را وارد کنید. <xliff:g id="_NUMBER_1">%d</xliff:g> تلاش دیگر باقی مانده است و پس از آن سیم‌کارت برای همیشه غیرقابل‌استفاده می‌شود. برای اطلاع از جزئیات با شرکت مخابراتی تماس بگیرید.</item>
-      <item quantity="other">‏سیم‌کارت اکنون غیرفعال است. برای ادامه دادن کد PUK را وارد کنید. <xliff:g id="_NUMBER_1">%d</xliff:g> تلاش دیگر باقی مانده است و پس از آن سیم‌کارت برای همیشه غیرقابل‌استفاده می‌شود. برای اطلاع از جزئیات با شرکت مخابراتی تماس بگیرید.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{پین سیم‌کارت را وارد کنید. # فرصت دیگر باقی مانده است و پس‌از آن برای باز کردن قفل دستگاه باید با شرکت مخابراتی‌تان تماس بگیرید.}one{پین سیم‌کارت را وارد کنید. # فرصت دیگر باقی مانده است.}other{پین سیم‌کارت را وارد کنید. # فرصت دیگر باقی مانده است.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{‏سیم‌کارت اکنون غیرفعال است. برای ادامه دادن، کد PUK را وارد کنید. # فرصت دیگر باقی مانده است و پس‌از آن سیم‌کارت برای همیشه غیرقابل‌استفاده می‌شود. برای اطلاع از جزئیات، با شرکت مخابراتی تماس بگیرید.}one{‏سیم‌کارت اکنون غیرفعال است. برای ادامه دادن، کد PUK را وارد کنید. # فرصت دیگر باقی مانده است و پس‌از آن سیم‌کارت برای همیشه غیرقابل‌استفاده می‌شود. برای اطلاع از جزئیات، با شرکت مخابراتی تماس بگیرید.}other{‏سیم‌کارت اکنون غیرفعال است. برای ادامه دادن، کد PUK را وارد کنید. # فرصت دیگر باقی مانده است و پس‌از آن سیم‌کارت برای همیشه غیرقابل‌استفاده می‌شود. برای اطلاع از جزئیات، با شرکت مخابراتی تماس بگیرید.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"پیش‌فرض"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"حباب"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"آنالوگ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index f8aa5de..da74b9a1 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunnin kuluttua."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Virheellinen SIM-kortin PIN-koodi. Sinun on nyt otettava yhteys operaattoriin laitteen lukituksen avaamiseksi."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Virheellinen SIM-kortin PIN-koodi. Sinulla on <xliff:g id="NUMBER_1">%d</xliff:g> yritystä jäljellä.</item>
-      <item quantity="one">Virheellinen SIM-kortin PIN-koodi. Sinulla on <xliff:g id="NUMBER_0">%d</xliff:g> yritys jäljellä, ennen kuin sinun on otettava yhteys operaattoriin laitteen lukituksen avaamiseksi.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Virheellinen SIM-kortin PIN-koodi. Sinulla on # yritys jäljellä, ennen kuin sinun on otettava yhteys operaattoriin laitteen lukituksen avaamiseksi.}other{Virheellinen SIM-kortin PIN-koodi. Sinulla on # yritystä jäljellä. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-korttia ei voi käyttää. Ota yhteys operaattoriin."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Virheellinen SIM-kortin PUK-koodi. Sinulla on <xliff:g id="NUMBER_1">%d</xliff:g> yritystä jäljellä, ennen kuin SIM-kortista tulee pysyvästi käyttökelvoton.</item>
-      <item quantity="one">Virheellinen SIM-kortin PUK-koodi. Sinulla on <xliff:g id="NUMBER_0">%d</xliff:g> yritys jäljellä, ennen kuin SIM-kortista tulee pysyvästi käyttökelvoton.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Virheellinen SIM-kortin PUK-koodi. Sinulla on # yritys jäljellä, ennen kuin SIM-kortti poistuu käytöstä pysyvästi.}other{Virheellinen SIM-kortin PUK-koodi. Sinulla on # yritystä jäljellä, ennen kuin SIM-kortti poistuu käytöstä pysyvästi.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM-kortin PIN-toiminto epäonnistui."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM-kortin PUK-toiminto epäonnistui."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Vaihda syöttötapaa."</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Laite lukittiin manuaalisesti"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Ei tunnistettu"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Kasvojentunnistusavaus: Asetukset &gt; pääsy kameraan"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Anna SIM-kortin PIN-koodi. Sinulla on <xliff:g id="NUMBER_1">%d</xliff:g> yritystä jäljellä.</item>
-      <item quantity="one">Anna SIM-kortin PIN-koodi. <xliff:g id="NUMBER_0">%d</xliff:g> yrityksen jälkeen laite lukittuu, ja vain operaattori voi avata sen.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM-kortti on nyt lukittu. Anna PUK-koodi, niin voit jatkaa. Sinulla on <xliff:g id="_NUMBER_1">%d</xliff:g> yritystä jäljellä, ennen kuin SIM-kortti poistuu pysyvästi käytöstä. Pyydä lisätietoja operaattoriltasi.</item>
-      <item quantity="one">SIM-kortti on nyt lukittu. Anna PUK-koodi, niin voit jatkaa. Sinulla on <xliff:g id="_NUMBER_0">%d</xliff:g> yritys jäljellä, ennen kuin SIM-kortti poistuu pysyvästi käytöstä. Pyydä lisätietoja operaattoriltasi.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Lisää SIM-kortin PIN-koodi. Sinulla on # yritys jäljellä, ennen kuin sinun on otettava yhteys operaattoriin laitteen lukituksen avaamiseksi.}other{Lisää SIM-kortin PIN-koodi. # yritystä jäljellä.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-kortti on nyt lukittu. Lisää PUK-koodi, niin voit jatkaa. Sinulla on # yritys jäljellä, ennen kuin SIM-kortti poistuu käytöstä pysyvästi. Pyydä lisätietoa operaattoriltasi.}other{SIM-kortti on nyt lukittu. Lisää PUK-koodi, niin voit jatkaa. Sinulla on # yritystä jäljellä, ennen kuin SIM-kortti poistuu käytöstä pysyvästi. Pyydä lisätietoa operaattoriltasi.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Oletus"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Kupla"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analoginen"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index 0e98007..b8125032 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Vous avez entré un mot de passe incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"NIP de carte SIM incorrect. Vous devez maintenant communiquer avec votre fournisseur de services pour déverrouiller votre appareil."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Le NIP de la carte SIM incorrect. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative.</item>
-      <item quantity="other">Le NIP de la carte SIM incorrect. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{NIP de la carte SIM incorrect. Il vous reste # tentative. Après cela, vous devrez communiquer avec votre fournisseur de services pour déverrouiller votre appareil.}one{NIP de la carte SIM incorrect. Il vous reste # tentative. }other{NIP de la carte SIM incorrect. Il vous reste # tentatives. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"La carte SIM est inutilisable. Communiquez avec votre fournisseur de services."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Le code PUK de la carte SIM est incorrect. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM devienne définitivement inutilisable.</item>
-      <item quantity="other">Le code PUK de la carte SIM est incorrect. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM devienne définitivement inutilisable.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Code PUK de la carte SIM incorrect. Il vous reste # tentative avant que votre carte SIM devienne définitivement inutilisable.}one{Code PUK de la carte SIM incorrect. Il vous reste # tentative avant que votre carte SIM devienne définitivement inutilisable.}other{Code PUK de la carte SIM incorrect. Il vous reste # tentatives avant que votre carte SIM devienne définitivement inutilisable.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Le déverrouillage par NIP de la carte SIM a échoué."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Le déverrouillage de la carte SIM par code PUK a échoué."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Changer de méthode d\'entrée"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"L\'appareil a été verrouillé manuellement"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Doigt non reconnu"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Déverr. rec. faciale : activez accès app. photo dans Param."</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Entrez le NIP de votre carte SIM. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative.</item>
-      <item quantity="other">Entrez le NIP de votre carte SIM. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM devienne définitivement inutilisable. Pour obtenir plus de détails, communiquez avec votre fournisseur de services.</item>
-      <item quantity="other">La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM devienne définitivement inutilisable. Pour obtenir plus de détails, communiquez avec votre fournisseur de services.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Entrez le NIP de la carte SIM. Il vous reste # tentative. Après cela, vous devrez communiquer avec votre fournisseur de services pour déverrouiller votre appareil.}one{Entrez le NIP de la carte SIM. Il vous reste # tentative.}other{Entrez le NIP de la carte SIM. Il vous reste # tentatives.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Il vous reste # tentative avant que votre carte SIM devienne définitivement inutilisable. Communiquez avec votre fournisseur de services pour en savoir plus.}one{La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Il vous reste # tentative avant que votre carte SIM devienne définitivement inutilisable. Communiquez avec votre fournisseur de services pour en savoir plus.}other{La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Il vous reste # tentatives avant que votre carte SIM devienne définitivement inutilisable. Communiquez avec votre fournisseur de services pour en savoir plus.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Par défaut"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bulle"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogique"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index cf79eab..0b21a40 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nRéessayez dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises.\n\nRéessayez dans <xliff:g id="NUMBER_1">%2$d</xliff:g> secondes."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Code PIN de la carte SIM incorrect. Vous devez désormais contacter votre opérateur pour déverrouiller votre appareil."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Code PIN de la carte SIM incorrect. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative.</item>
-      <item quantity="other">Code PIN de la carte SIM incorrect. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Code PIN SIM incorrect. Il vous reste # tentative avant de devoir contacter votre opérateur pour déverrouiller l\'appareil.}one{Code PIN SIM incorrect. Il vous reste # tentative. }other{Code PIN SIM incorrect. Il vous reste # tentatives. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"La carte SIM est inutilisable. Contactez votre opérateur."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Clé PUK de la carte SIM incorrecte. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM ne devienne définitivement inutilisable.</item>
-      <item quantity="other">Clé PUK de la carte SIM incorrecte. Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM ne devienne définitivement inutilisable.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Clé PUK de la SIM incorrecte. Il vous reste # tentative avant que la SIM ne devienne définitivement inutilisable.}one{Clé PUK de la SIM incorrecte. Il vous reste # tentative avant que la carte SIM ne devienne définitivement inutilisable.}other{Clé PUK de la SIM incorrecte. Il vous reste # tentatives avant que la carte SIM ne devienne définitivement inutilisable.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Échec du déverrouillage à l\'aide du code PIN de la carte SIM."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Échec du déverrouillage à l\'aide de la clé PUK de la carte SIM."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Changer le mode de saisie"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Appareil verrouillé manuellement"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Non reconnu"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Pour le déverrouillage par reconnaissance faciale, activez l\'accès à l\'app. photo dans Paramètres"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Saisissez le code de la carte SIM. <xliff:g id="NUMBER_1">%d</xliff:g> tentative restante.</item>
-      <item quantity="other">Saisissez le code de la carte SIM. <xliff:g id="NUMBER_1">%d</xliff:g> tentatives restantes.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">La carte SIM est maintenant désactivée. Saisissez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM ne devienne définitivement inutilisable. Pour de plus amples informations, veuillez contacter votre opérateur.</item>
-      <item quantity="other">La carte SIM est maintenant désactivée. Saisissez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM ne devienne définitivement inutilisable. Pour de plus amples informations, veuillez contacter votre opérateur.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Saisissez le code PIN SIM. Il vous reste # tentative avant de devoir contacter votre opérateur pour déverrouiller l\'appareil.}one{Saisissez le code PIN SIM. Il vous reste # tentative.}other{Saisissez le code PIN SIM. Il vous reste # tentatives.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{La SIM est maintenant désactivée. Saisissez la clé PUK pour continuer. Il vous reste # tentative avant que la SIM ne devienne définitivement inutilisable. Pour plus d\'infos, contactez votre opérateur.}one{La SIM est maintenant désactivée. Saisissez la clé PUK pour continuer. Il vous reste # tentative avant que la SIM ne devienne définitivement inutilisable. Pour plus d\'infos, contactez votre opérateur.}other{La SIM est maintenant désactivée. Saisissez la clé PUK pour continuer. Il vous reste # tentatives avant que la SIM ne devienne définitivement inutilisable. Pour plus d\'infos, contactez votre opérateur.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Par défaut"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bulle"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogique"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index 819e632..18b0fd5 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Introduciches o contrasinal incorrectamente <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Debuxaches incorrectamente o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"O código PIN da SIM non é correcto. Agora debes contactar co operador para desbloquear o dispositivo."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">O código PIN da SIM é incorrecto. Quédanche <xliff:g id="NUMBER_1">%d</xliff:g> intentos.</item>
-      <item quantity="one">O código PIN da SIM é incorrecto. Quédache <xliff:g id="NUMBER_0">%d</xliff:g> intento antes de que teñas que contactar co operador para desbloquear o dispositivo.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{O código PIN da SIM é incorrecto. Quédache # intento antes de que teñas que contactar co operador para desbloquear o dispositivo.}other{O código PIN da SIM é incorrecto. Quédanche # intentos. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"A SIM está inutilizable. Contacta co operador."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">O código PUK da SIM é incorrecto. Quédanche <xliff:g id="NUMBER_1">%d</xliff:g> intentos antes de que a SIM quede inutilizable para sempre.</item>
-      <item quantity="one">O código PUK da SIM non é correcto. Quédache <xliff:g id="NUMBER_0">%d</xliff:g> intento antes de que a SIM quede inutilizable para sempre.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{O código PUK da SIM é incorrecto. Quédache # intento antes de que a SIM quede inutilizable para sempre.}other{O código PUK da SIM é incorrecto. Quédanche # intentos antes de que a SIM quede inutilizable para sempre.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Produciuse un erro no funcionamento do PIN da SIM"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Produciuse un erro ao tentar desbloquear a tarxeta SIM co código PUK."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambia o método de introdución"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"O dispositivo bloqueouse manualmente"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Non se recoñeceu"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Desbloqueo facial: acceso á cámara en Configuración"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Introduce o código PIN da SIM. Quédanche <xliff:g id="NUMBER_1">%d</xliff:g> intentos.</item>
-      <item quantity="one">Introduce o código PIN da SIM. Quédache <xliff:g id="NUMBER_0">%d</xliff:g> intento antes de que teñas que contactar co operador para desbloquear o dispositivo.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">A SIM está desactivada. Introduce o código PUK para continuar. Quédanche <xliff:g id="_NUMBER_1">%d</xliff:g> intentos antes de que a SIM quede inutilizable para sempre. Contacta co operador para obter información.</item>
-      <item quantity="one">A SIM está desactivada. Introduce o código PUK para continuar. Quédache <xliff:g id="_NUMBER_0">%d</xliff:g> intento antes de que a SIM quede inutilizable para sempre. Contacta co operador para obter información.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Mete o PIN da SIM. Quédache # intento antes de que teñas que contactar co operador para desbloquear o dispositivo.}other{Mete o PIN da SIM. Quédanche # intentos.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{A SIM está desactivada. Mete o código PUK para continuar. Quédache # intento antes de que a SIM quede inutilizable para sempre. Contacta co operador para obter información.}other{A SIM está desactivada. Mete o código PUK para continuar. Quédanche # intentos antes de que a SIM quede inutilizable para sempre. Contacta co operador para obter información.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Predeterminado"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Burbulla"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analóxico"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index 6142aa1..4dd994c 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"તમારો પાસવર્ડ તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે લખ્યો છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકંડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"તમારી અનલૉક પૅટર્ન તમે <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ખોટો સિમ પિન કોડ, તમારે હવે તમારું ઉપકરણ અનલૉક કરવા માટે તમારા કૅરીઅરનો સંપર્ક કરવો આવશ્યક છે."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">ખોટો સિમ પિન કોડ, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
-      <item quantity="other">ખોટો સિમ પિન કોડ, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{સિમ કાર્ડનો ખોટો પિન કોડ, તમને તમારું ડિવાઇસ અનલૉક કરવા માટે તમારા મોબાઇલ ઑપરેટરનો સંપર્ક કરવાની જરૂર પડે, તે પહેલાં તમારી પાસે # પ્રયાસ બાકી છે.}one{સિમ કાર્ડનો ખોટો પિન કોડ, તમારી પાસે # પ્રયાસ બાકી છે. }other{સિમ કાર્ડનો ખોટો પિન કોડ, તમારી પાસે # પ્રયાસ બાકી છે. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"સિમ અનુપયોગી છે. તમારા કૅરિઅરનો સંપર્ક કરો."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">ખોટો સિમ PUK કોડ, સિમ કાયમી રૂપે અનુપયોગી બની જાય તે પહેલા તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
-      <item quantity="other">ખોટો સિમ PUK કોડ, સિમ કાયમી રૂપે અનુપયોગી બની જાય તે પહેલા તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{સિમ કાર્ડનો ખોટો PUK કોડ, સિમ કાર્ડ કાયમ માટે બિનઉપયોગી બની જાય, એ પહેલાં તમારી પાસે # પ્રયાસ બાકી છે.}one{સિમ કાર્ડનો ખોટો PUK કોડ, સિમ કાર્ડ કાયમ માટે બિનઉપયોગી બની જાય, એ પહેલાં તમારી પાસે # પ્રયાસ બાકી છે.}other{સિમ કાર્ડનો ખોટો PUK કોડ, સિમ કાર્ડ કાયમ માટે બિનઉપયોગી બની જાય, એ પહેલાં તમારી પાસે # પ્રયાસ બાકી છે.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"સિમ પિન ઑપરેશન નિષ્ફળ થયું!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"સિમ PUK ઓપરેશન નિષ્ફળ થયું!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ઇનપુટ પદ્ધતિ સ્વિચ કરો"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"ઉપકરણ મેન્યુઅલી લૉક કર્યું હતું"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"ઓળખાયેલ નથી"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"ફેસ અનલૉક વાપરવા સેટિંગમાં કૅમેરા ઍક્સેસ ચાલુ કરો"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">સિમનો પિન દાખલ કરો, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે.</item>
-      <item quantity="other">સિમનો પિન દાખલ કરો, તમારી પાસે <xliff:g id="NUMBER_1">%d</xliff:g> પ્રયાસો બાકી છે.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">સિમ હવે બંધ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાયમીરૂપે બિનઉપયોગી બની જાય એ પહેલાં તમારી પાસે <xliff:g id="_NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે. વિગતો માટે કૅરિઅરનો સંપર્ક કરો.</item>
-      <item quantity="other">સિમ હવે બંધ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાયમીરૂપે બિનઉપયોગી બની જાય એ પહેલાં તમારી પાસે <xliff:g id="_NUMBER_1">%d</xliff:g> પ્રયાસો બાકી છે. વિગતો માટે કૅરિઅરનો સંપર્ક કરો.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{સિમ કાર્ડનો પિન દાખલ કરો. તમને તમારું ડિવાઇસ અનલૉક કરવા માટે તમારા મોબાઇલ ઑપરેટરનો સંપર્ક કરવાની જરૂર પડે, તે પહેલાં તમારી પાસે # પ્રયાસ બાકી છે.}one{સિમ કાર્ડનો પિન દાખલ કરો. તમારી પાસે # પ્રયાસ બાકી છે.}other{સિમ કાર્ડનો પિન દાખલ કરો. તમારી પાસે # પ્રયાસ બાકી છે.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{સિમ કાર્ડ બંધ કરેલું છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાર્ડ કાયમ માટે બિનઉપયોગી બની જાય, એ પહેલાં તમારી પાસે # પ્રયાસ બાકી છે. વિગતો માટે મોબાઇલ ઑપરેટરનો સંપર્ક કરો.}one{સિમ કાર્ડ બંધ કરેલું છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાર્ડ કાયમ માટે બિનઉપયોગી બની જાય, એ પહેલાં તમારી પાસે # પ્રયાસ બાકી છે. વિગતો માટે મોબાઇલ ઑપરેટરનો સંપર્ક કરો.}other{સિમ કાર્ડ બંધ કરેલું છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાર્ડ કાયમ માટે બિનઉપયોગી બની જાય, એ પહેલાં તમારી પાસે # પ્રયાસ બાકી છે. વિગતો માટે મોબાઇલ ઑપરેટરનો સંપર્ક કરો.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ડિફૉલ્ટ"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"બબલ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"એનાલોગ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index 742493a..44a9c0e 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"आप अपना पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"आपने अपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से ड्रॉ किया है. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"गलत SIM पिन कोड, अपने डिवाइस को अनलॉक करने के लिए अब आपको अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करना होगा."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">गलत सिम पिन कोड, आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
-      <item quantity="other">गलत सिम पिन कोड, आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{आपने सिम का गलत पिन कोड डाला है. आपके पास # मौका बचा है. अगर फिर भी डिवाइस अनलॉक नहीं होता है, तो आपको मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करना होगा.}one{आपने सिम का गलत पिन कोड डाला है. आपके पास # मौका बचा है. }other{आपने सिम का गलत पिन कोड डाला है. आपके पास # मौके बचे हैं. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM बेकार हो गया है. अपनी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">SIM PUK कोड गलत है, SIM के हमेशा के लिए बेकार हो जाने से पहले आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
-      <item quantity="other">SIM PUK कोड गलत है, SIM के हमेशा के लिए बेकार हो जाने से पहले आप <xliff:g id="NUMBER_1">%d</xliff:g> बार और कोशिश कर सकते हैं.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{आपने सिम का गलत PUK कोड डाला है. आपके पास # मौका बचा है. इसके बाद, सिम हमेशा के लिए बंद हो जाएगा.}one{आपने सिम का गलत PUK कोड डाला है. आपके पास # मौका बचा है. इसके बाद, सिम हमेशा के लिए बंद हो जाएगा.}other{आपने सिम का गलत PUK कोड डाला है. आपके पास # मौके बचे हैं. इसके बाद, सिम हमेशा के लिए बंद हो जाएगा.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM पिन की कार्यवाही विफल रही!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK की कार्यवाही विफल रही!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"इनपुट का तरीका बदलें"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"डिवाइस को मैन्युअल रूप से लॉक किया गया था"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"पहचान नहीं हो पाई"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"\'फ़ेस अनलॉक\' इस्तेमाल करने के लिए, सेटिंग में जाकर कैमरे का ऐक्सेस चालू करें"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">सिम का पिन डालें. आपके पास <xliff:g id="NUMBER_1">%d</xliff:g> मौके बचे हैं.</item>
-      <item quantity="other">सिम का पिन डालें. आपके पास <xliff:g id="NUMBER_1">%d</xliff:g> मौके बचे हैं.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">सिम बंद कर दिया गया है. जारी रखने के लिए PUK कोड डालें. आपके पास <xliff:g id="_NUMBER_1">%d</xliff:g> मौके बचे हैं, उसके बाद, सिम हमेशा के लिए काम करना बंद कर देगा. जानकारी के लिए, मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें.</item>
-      <item quantity="other">सिम बंद कर दिया गया है. जारी रखने के लिए PUK कोड डालें. आपके पास <xliff:g id="_NUMBER_1">%d</xliff:g> मौके बचे हैं, उसके बाद, सिम हमेशा के लिए काम करना बंद कर देगा. जानकारी के लिए, मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{सिम का पिन डालें. आपके पास # मौका बचा है. अगर फिर भी डिवाइस अनलॉक नहीं होता है, तो आपको मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करना होगा.}one{सिम का पिन डालें. आपके पास # मौका बचा है.}other{सिम का पिन डालें. आपके पास # मौके बचे हैं.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{सिम बंद कर दिया गया है. जारी रखने के लिए PUK कोड डालें. आपके पास # मौका बचा है. इसके बाद, सिम हमेशा के लिए बंद हो जाएगा. ज़्यादा जानकारी के लिए, मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें.}one{सिम बंद कर दिया गया है. जारी रखने के लिए PUK कोड डालें. आपके पास # मौका बचा है. इसके बाद, सिम हमेशा के लिए बंद हो जाएगा. ज़्यादा जानकारी के लिए, मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें.}other{सिम बंद कर दिया गया है. जारी रखने के लिए PUK कोड डालें. आपके पास # मौके बचे हैं. इसके बाद, सिम हमेशा के लिए बंद हो जाएगा. ज़्यादा जानकारी के लिए, मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"डिफ़ॉल्ट"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"बबल"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"एनालॉग"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index 292bfd1..299d811 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -68,17 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Netočno ste unijeli zaporku <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Netočan PIN kôd SIM kartice; sada morate kontaktirati svog mobilnog operatera da bi otključao vaš uređaj."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">PIN kôd SIM-a nije točan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj.</item>
-      <item quantity="few">PIN kôd SIM-a nije točan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-      <item quantity="other">PIN kôd SIM-a nije točan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{PIN kôd SIM-a nije točan. Imate još # pokušaj, a zatim ćete morati kontaktirati mobilnog operatera da bi otključao uređaj.}one{PIN kôd SIM-a nije točan. Imate još # pokušaj. }few{PIN kôd SIM-a nije točan. Imate još # pokušaja. }other{PIN kôd SIM-a nije točan. Imate još # pokušaja. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM kartica nije upotrebljiva. Kontaktirajte svog mobilnog operatera."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">PUK kôd SIM-a nije točan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj, a ako ne uspijete, SIM će postati trajno neupotrebljiv.</item>
-      <item quantity="few">PUK kôd SIM-a nije točan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja, a ako ne uspijete, SIM će postati trajno neupotrebljiv.</item>
-      <item quantity="other">PUK kôd SIM-a nije točan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja, a ako ne uspijete, SIM će postati trajno neupotrebljiv.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{PUK kôd SIM-a nije točan. Imate još # pokušaj prije nego što SIM kartica postane trajno neupotrebljiva.}one{PUK kôd SIM-a nije točan. Imate još # pokušaj prije nego što SIM kartica postane trajno neupotrebljiva.}few{PUK kôd SIM-a nije točan. Imate još # pokušaja prije nego što SIM kartica postane trajno neupotrebljiva.}other{PUK kôd SIM-a nije točan. Imate još # pokušaja prije nego što SIM kartica postane trajno neupotrebljiva.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Operacija PIN-a SIM kartice nije uspjela!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Operacija PUK-a SIM kartice nije uspjela!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Promjena načina unosa"</string>
@@ -93,16 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Uređaj je ručno zaključan"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nije prepoznato"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Za otključavanje licem uključite pristup kameri"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Unesite PIN za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj.</item>
-      <item quantity="few">Unesite PIN za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-      <item quantity="other">Unesite PIN za SIM. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaj prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.</item>
-      <item quantity="few">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.</item>
-      <item quantity="other">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Unesite PIN za SIM. Imate još # pokušaj, a zatim ćete morati kontaktirati mobilnog operatera da bi otključao uređaj.}one{Unesite PIN za SIM. Imate još # pokušaj.}few{Unesite PIN za SIM. Imate još # pokušaja.}other{Unesite PIN za SIM. Imate još # pokušaja.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaj prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.}one{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaj prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.}few{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.}other{SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još # pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Zadano"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Mjehurić"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogni"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index b647f16..6201e95 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül adta meg a jelszót.\n\nPróbálja újra <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal rosszul rajzolta le a feloldási mintát.\n\nPróbálja újra <xliff:g id="NUMBER_1">%2$d</xliff:g> másodperc múlva."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Helytelen PIN-kód a SIM-kártyához. Az eszköz feloldása érdekében, kérjük, vegye fel a kapcsolatot szolgáltatójával."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Helytelen PIN-kód a SIM-kártyához. Még <xliff:g id="NUMBER_1">%d</xliff:g> próbálkozása maradt.</item>
-      <item quantity="one">Helytelen PIN-kód a SIM-kártyához. Még <xliff:g id="NUMBER_0">%d</xliff:g> próbálkozása maradt, az eszköz feloldásához azt követően fel kell vennie a kapcsolatot szolgáltatójával.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Helytelen PIN-kód a SIM-kártyához; még # próbálkozása van, mielőtt fel kell vennie a kapcsolatot szolgáltatójával az eszköz feloldásához.}other{Helytelen PIN-kód a SIM-kártyához; még # próbálkozása van. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"A SIM-kártya használhatatlan. Vegye fel a kapcsolatot szolgáltatójával."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Helytelen PUK-kód a SIM-kártyához. Még <xliff:g id="NUMBER_1">%d</xliff:g> próbálkozása maradt, mielőtt a SIM-kártya végleg használhatatlanná válik.</item>
-      <item quantity="one">Helytelen PUK-kód a SIM-kártyához. Még <xliff:g id="NUMBER_0">%d</xliff:g> próbálkozása maradt, mielőtt a SIM-kártya végleg használhatatlanná válik.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Helytelen PUK-kód a SIM-kártyához. Még # próbálkozása maradt, mielőtt a SIM-kártya végleg használhatatlanná válik.}other{Helytelen PUK-kód a SIM-kártyához; még # próbálkozása van, mielőtt a SIM-kártya végleg használhatatlan lesz.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"A SIM-kártya PIN-művelete sikertelen!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"A SIM-kártya PUK-művelete sikertelen!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Beviteli módszer váltása"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Az eszközt manuálisan lezárták"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nem ismerhető fel"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Arcalapú feloldáshoz Hozzáférés a kamerához szükséges"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Adja meg a SIM-kártya PIN-kódját. <xliff:g id="NUMBER_1">%d</xliff:g> próbálkozása maradt.</item>
-      <item quantity="one">Adja meg a SIM-kártya PIN-kódját. <xliff:g id="NUMBER_0">%d</xliff:g> próbálkozása maradt. Ha elfogynak a próbálkozási lehetőségek, az eszköz feloldásához fel kell vennie a kapcsolatot szolgáltatójával.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. Még <xliff:g id="_NUMBER_1">%d</xliff:g> próbálkozása van, mielőtt végleg használhatatlanná válik a SIM-kártya. További információért forduljon a szolgáltatóhoz.</item>
-      <item quantity="one">A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. Még <xliff:g id="_NUMBER_0">%d</xliff:g> próbálkozása van, mielőtt végleg használhatatlanná válik a SIM-kártya. További információért forduljon a szolgáltatóhoz.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Adja meg a SIM-kártya PIN-kódját. # próbálkozása maradt. Ha elfogynak a próbálkozási lehetőségek, az eszköz feloldásához fel kell vennie a kapcsolatot szolgáltatójával.}other{Adja meg a SIM-kártya PIN-kódját. # próbálkozási lehetősége maradt.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. Még # próbálkozása van, mielőtt végleg használhatatlanná válik a SIM-kártya. További információért forduljon a szolgáltatóhoz.}other{A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. Még # próbálkozása van, mielőtt végleg használhatatlanná válik a SIM-kártya. További információért forduljon a szolgáltatóhoz.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Alapértelmezett"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Buborék"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analóg"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index 2af6e7b..5d65da0 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Դուք սխալ եք մուտքագրել ձեր գաղտնաբառը <xliff:g id="NUMBER_0">%1$d</xliff:g> անգամ: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%2$d</xliff:g> վայրկյանից:"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Դուք սխալ եք մուտքագրել ձեր ապակողպման նախշը <xliff:g id="NUMBER_0">%1$d</xliff:g> անգամ: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%2$d</xliff:g> վայրկյանից։"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM PIN կոդը սխալ է։ Այժմ պետք է դիմեք ձեր օպերատորին՝ սարքն արգելահանելու համար:"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">SIM PIN կոդը սխալ է: Մնաց <xliff:g id="NUMBER_1">%d</xliff:g> փորձ, որից հետո պետք է դիմեք ձեր օպերատորին՝ սարքն արգելահանելու համար:</item>
-      <item quantity="other">SIM PIN կոդը սխալ է: Մնաց <xliff:g id="NUMBER_1">%d</xliff:g> փորձ:</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM քարտի PIN կոդը սխալ է։ Մնաց # փորձ, որից հետո պետք է դիմեք ձեր օպերատորին՝ սարքն ապակողպելու համար։}one{SIM քարտի PIN կոդը սխալ է։ Մնաց # փորձ։ }other{SIM քարտի PIN կոդը սխալ է։ Մնաց # փորձ։ }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-ը հնարավոր չէ օգտագործել: Դիմեք ձեր օպերատորին:"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">SIM PUK կոդը սխալ է: Մնաց <xliff:g id="NUMBER_1">%d</xliff:g> փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել:</item>
-      <item quantity="other">SIM PUK կոդը սխալ է: Մնաց <xliff:g id="NUMBER_1">%d</xliff:g> փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել:</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM քարտի PUK կոդը սխալ է։ Մնաց # փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել։}one{SIM քարտի PUK կոդը սխալ է։ Մնաց # փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել։}other{SIM քարտի PUK կոդը սխալ է։ Մնաց # փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել։}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN կոդի գործողությունը ձախողվեց:"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK կոդի գործողությունը ձախողվեց:"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Փոխել ներածման եղանակը"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Սարքը կողպվել է ձեռքով"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Չհաջողվեց ճանաչել"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Դեմքով ապակողպման համար թույլատրեք տեսախցիկի օգտագործումը"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Մուտքագրեք SIM քարտի PIN կոդը: Մնացել է <xliff:g id="NUMBER_1">%d</xliff:g> փորձ:</item>
-      <item quantity="other">Մուտքագրեք SIM քարտի PIN կոդը: Մնացել է <xliff:g id="NUMBER_1">%d</xliff:g> փորձ:</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM քարտն անջատված է: Շարունակելու համար մուտքագրեք PUK կոդը: Մնացել է <xliff:g id="_NUMBER_1">%d</xliff:g> փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել: Մանրամասների համար դիմեք օպերատորին:</item>
-      <item quantity="other">SIM քարտն անջատված է: Շարունակելու համար մուտքագրեք PUK կոդը: Մնացել է <xliff:g id="_NUMBER_1">%d</xliff:g> փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել: Մանրամասների համար դիմեք օպերատորին:</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Մուտքագրեք SIM քարտի PIN կոդը։ Մնացել է # փորձ, որից հետո պետք է դիմեք ձեր օպերատորին՝ սարքն ապակողպելու համար։}one{Մուտքագրեք SIM քարտի PIN կոդը։ Մնացել է # փորձ։}other{Մուտքագրեք SIM քարտի PIN կոդը։ Մնացել է # փորձ։}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM քարտն այժմ անջատված է։ Շարունակելու համար մուտքագրեք PUK կոդը։ Մնացել է # փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել։ Մանրամասների համար դիմեք օպերատորին։}one{SIM քարտն այժմ անջատված է։ Շարունակելու համար մուտքագրեք PUK կոդը։ Մնացել է # փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել։ Մանրամասների համար դիմեք օպերատորին։}other{SIM քարտն այժմ անջատված է։ Շարունակելու համար մուտքագրեք PUK կոդը։ Մնացել է # փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել։ Մանրամասների համար դիմեք օպերատորին։}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Կանխադրված"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Պղպջակ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Անալոգային"</string>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index 1bd0db2..c42f5eb 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> detik."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Kode PIN SIM salah. Hubungi operator untuk membuka kunci perangkat."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Kode PIN SIM salah, sisa, sisa <xliff:g id="NUMBER_1">%d</xliff:g> percobaan.</item>
-      <item quantity="one">Kode PIN SIM salah, sisa <xliff:g id="NUMBER_0">%d</xliff:g> percobaan sebelum Anda harus menghubungi operator untuk membuka kunci perangkat.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Kode PIN SIM salah. Tersisa # percobaan lagi sebelum Anda harus menghubungi operator untuk membuka kunci perangkat.}other{Kode PIN SIM salah, tersisa # percobaan lagi. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM tidak dapat digunakan. Hubungi operator Anda."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Kode PUK SIM salah, sisa <xliff:g id="NUMBER_1">%d</xliff:g> percobaan sebelum SIM tidak dapat digunakan selamanya.</item>
-      <item quantity="one">Kode PUK SIM salah, sisa <xliff:g id="NUMBER_0">%d</xliff:g> percobaan sebelum SIM tidak dapat digunakan selamanya.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Kode PUK SIM salah, tersisa # percobaan lagi sebelum SIM tidak dapat digunakan secara permanen.}other{Kode PUK SIM salah, tersisa # percobaan lagi sebelum SIM tidak dapat digunakan secara permanen.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Operasi PIN SIM gagal!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Operasi PUK SIM gagal!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Beralih metode input"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Perangkat dikunci secara manual"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Tidak dikenali"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Untuk pakai Face Unlock, beri akses kamera di Setelan"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Masukkan PIN SIM. Tersisa <xliff:g id="NUMBER_1">%d</xliff:g> percobaan.</item>
-      <item quantity="one">Masukkan PIN SIM. Tersisa <xliff:g id="NUMBER_0">%d</xliff:g> percobaan sebelum Anda harus menghubungi operator untuk membuka kunci perangkat.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM kini dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Tersisa <xliff:g id="_NUMBER_1">%d</xliff:g> percobaan sebelum SIM tidak dapat digunakan secara permanen. Hubungi operator untuk mengetahui detailnya.</item>
-      <item quantity="one">SIM kini dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Tersisa <xliff:g id="_NUMBER_0">%d</xliff:g> percobaan sebelum SIM tidak dapat digunakan secara permanen. Hubungi operator untuk mengetahui detailnya.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Masukkan PIN SIM. Tersisa # percobaan lagi sebelum Anda harus menghubungi operator untuk membuka kunci perangkat.}other{Masukkan PIN SIM. Tersisa # percobaan lagi.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM kini dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Tersisa # percobaan lagi sebelum SIM tidak dapat digunakan secara permanen. Hubungi operator untuk mengetahui detailnya.}other{SIM kini dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Tersisa # percobaan lagi sebelum SIM tidak dapat digunakan secara permanen. Hubungi operator untuk mengetahui detailnya.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Default"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Balon"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index fc3af84..ea1a8ee 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Þú hefur slegið inn rangt aðgangsorð <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. \n\nReyndu aftur eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> sekúndur."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Rangt PIN-númer SIM-korts. Nú þarftu að hafa samband við símafyrirtækið til að opna fyrir tækið."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Rangt PIN-númer SIM-korts. Þú átt <xliff:g id="NUMBER_1">%d</xliff:g> tilraun eftir.</item>
-      <item quantity="other">Rangt PIN-númer SIM-korts. Þú átt <xliff:g id="NUMBER_1">%d</xliff:g> tilraunir eftir.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Rangt PIN-númer SIM-korts. Þú átt # tilraun eftir áður en þú þarft að hafa samband við símafyrirtækið þitt til að taka tækið úr lás.}one{Rangt PIN-númer SIM-korts. Þú átt # tilraun eftir. }other{Rangt PIN-númer SIM-korts. Þú átt # tilraunir eftir. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-kortið er ónothæft. Hafðu samband við símafyrirtækið þitt."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Rangt PUK-númer SIM-korts. Þú átt <xliff:g id="NUMBER_1">%d</xliff:g> tilraun eftir áður en SIM-kortið verður ónothæft til frambúðar.</item>
-      <item quantity="other">Rangt PUK-númer SIM-korts. Þú átt <xliff:g id="NUMBER_1">%d</xliff:g> tilraunir eftir áður en SIM-kortið verður ónothæft til frambúðar.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Rangt PUK-númer SIM-korts. Þú átt # tilraun eftir áður en SIM-kortið verður ónothæft til frambúðar.}one{Rangt PUK-númer SIM-korts. Þú átt # tilraun eftir áður en SIM-kortið verður ónothæft til frambúðar.}other{Rangt PUK-númer SIM-korts. Þú átt # tilraunir eftir áður en SIM-kortið verður ónothæft til frambúðar.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"PIN-aðgerð SIM-korts mistókst!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"PUK-aðgerð SIM-korts mistókst!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Skipta um innsláttaraðferð"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Tækinu var læst handvirkt"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Þekktist ekki"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Kveiktu á myndavélaaðgangi í stillingum til að nota andlitskenni"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Sláðu inn PIN-númer SIM-korts. Þú átt <xliff:g id="NUMBER_1">%d</xliff:g> tilraun eftir.</item>
-      <item quantity="other">Sláðu inn PIN-númer SIM-korts. Þú átt <xliff:g id="NUMBER_1">%d</xliff:g> tilraunir eftir.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM-kortið er nú óvirkt. Sláðu inn PUK-númer til að halda áfram. Það er <xliff:g id="_NUMBER_1">%d</xliff:g> tilraun eftir þar til SIM-kortið verður ónothæft til frambúðar. Hafðu samband við símafyrirtækið til að fá upplýsingar.</item>
-      <item quantity="other">SIM-kortið er nú óvirkt. Sláðu inn PUK-númer til að halda áfram. Það eru <xliff:g id="_NUMBER_1">%d</xliff:g> tilraunir eftir þar til SIM-kortið verður ónothæft til frambúðar. Hafðu samband við símafyrirtækið til að fá upplýsingar.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Sláðu inn PIN-númer SIM-korts. Þú átt # tilraun eftir áður en þú þarft að hafa samband við símafyrirtækið þitt til að taka tækið úr lás.}one{Sláðu inn PIN-númer SIM-kortsins. Þú átt # tilraun eftir.}other{Sláðu inn PIN-númer SIM-kortsins. Þú átt # tilraunir eftir.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-kortið er nú óvirkt. Sláðu inn PUK-númer til að halda áfram. Þú átt # tilraun eftir þar til SIM-kortið verður ónothæft til frambúðar. Hafðu samband við símafyrirtækið til að fá upplýsingar.}one{SIM-kortið er nú óvirkt. Sláðu inn PUK-númer til að halda áfram. Þú átt # tilraun eftir þar til SIM-kortið verður ónothæft til frambúðar. Hafðu samband við símafyrirtækið til að fá upplýsingar.}other{SIM-kortið er nú óvirkt. Sláðu inn PUK-númer til að halda áfram. Þú átt # tilraunir eftir þar til SIM-kortið verður ónothæft til frambúðar. Hafðu samband við símafyrirtækið til að fá upplýsingar.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Sjálfgefið"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Blaðra"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Með vísum"</string>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index 81138f1..f1583b1 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Hai digitato la tua password <xliff:g id="NUMBER_0">%1$d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. \n\nRiprova tra <xliff:g id="NUMBER_1">%2$d</xliff:g> secondi."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Codice PIN della SIM errato. Devi contattare l\'operatore per sbloccare il dispositivo."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Codice PIN della SIM errato. Hai ancora <xliff:g id="NUMBER_1">%d</xliff:g> tentativi a disposizione.</item>
-      <item quantity="one">Codice PIN della SIM errato. Hai ancora <xliff:g id="NUMBER_0">%d</xliff:g> tentativo a disposizione, dopodiché dovrai contattare l\'operatore per sbloccare il dispositivo.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Codice PIN della SIM errato. Hai ancora # tentativo a disposizione, dopodiché dovrai contattare l\'operatore per sbloccare il dispositivo.}other{Codice PIN della SIM errato. Hai ancora # tentativi a disposizione. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM inutilizzabile. Contatta il tuo operatore."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Codice PUK della SIM errato. Hai ancora <xliff:g id="NUMBER_1">%d</xliff:g> tentativi a disposizione prima che la SIM diventi definitivamente inutilizzabile.</item>
-      <item quantity="one">Codice PUK della SIM errato. Hai ancora <xliff:g id="NUMBER_0">%d</xliff:g> tentativo a disposizione prima che la SIM diventi definitivamente inutilizzabile.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Codice PUK della SIM errato. Hai ancora # tentativo a disposizione prima che la SIM diventi definitivamente inutilizzabile.}other{Codice PUK della SIM errato. Hai ancora # tentativi a disposizione prima che la SIM diventi definitivamente inutilizzabile.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Operazione con PIN della SIM non riuscita."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Operazione con PUK della SIM non riuscita."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Cambia metodo di immissione"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Il dispositivo è stato bloccato manualmente"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Non riconosciuto"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Sblocco con volto richiede l\'accesso alla fotocamera"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Inserisci il codice PIN della SIM. Hai ancora <xliff:g id="NUMBER_1">%d</xliff:g> tentativi a disposizione.</item>
-      <item quantity="one">Inserisci il codice PIN della SIM. Hai ancora <xliff:g id="NUMBER_0">%d</xliff:g> tentativo a disposizione, dopodiché dovrai contattare l\'operatore per sbloccare il dispositivo.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">La scheda SIM è ora disattivata. Inserisci il codice PUK per continuare. Hai ancora <xliff:g id="_NUMBER_1">%d</xliff:g> tentativi a disposizione prima che la SIM diventi definitivamente inutilizzabile. Per informazioni dettagliate, contatta l\'operatore.</item>
-      <item quantity="one">La scheda SIM è ora disattivata. Inserisci il codice PUK per continuare. Hai ancora <xliff:g id="_NUMBER_0">%d</xliff:g> tentativo a disposizione prima che la SIM diventi definitivamente inutilizzabile. Per informazioni dettagliate, contatta l\'operatore.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Inserisci il codice PIN della SIM. Hai ancora # tentativo a disposizione, dopodiché dovrai contattare l\'operatore per sbloccare il dispositivo.}other{Inserisci il PIN della SIM. Hai a disposizione ancora # tentativi.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{La scheda SIM è ora disattivata. Inserisci il codice PUK per continuare. Hai ancora # tentativo a disposizione prima che la SIM diventi definitivamente inutilizzabile. Per informazioni dettagliate, contatta l\'operatore.}other{La scheda SIM è ora disattivata. Inserisci il codice PUK per continuare. Hai ancora # tentativi a disposizione prima che la SIM diventi definitivamente inutilizzabile. Per informazioni dettagliate, contatta l\'operatore.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Predefinito"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bolla"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogico"</string>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index 90b4828..470dd72 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -68,19 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nאפשר לנסות שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. \n\nאפשר לנסות שוב בעוד <xliff:g id="NUMBER_1">%2$d</xliff:g> שניות."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"‏קוד האימות של כרטיס ה-SIM שגוי. יש ליצור קשר עם הספק כדי לבטל את נעילת המכשיר."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="two">‏קוד האימות של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
-      <item quantity="many">‏קוד האימות של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
-      <item quantity="other">‏קוד האימות של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות.</item>
-      <item quantity="one">‏קוד האימות של כרטיס ה-SIM שגוי. נותר לך עוד ניסיון <xliff:g id="NUMBER_0">%d</xliff:g> לפני שיהיה עליך ליצור קשר עם הספק כדי לבטל את נעילת המכשיר.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{‏קוד האימות של כרטיס ה-SIM שגוי. נשאר לך עוד ניסיון אחד (#) לפני שיהיה צורך ליצור קשר עם הספק כדי לבטל את נעילת המכשיר.}two{‏קוד האימות של כרטיס ה-SIM שגוי. נשארו לך עוד # ניסיונות. }many{‏קוד האימות של כרטיס ה-SIM שגוי. נשארו לך עוד # ניסיונות. }other{‏קוד האימות של כרטיס ה-SIM שגוי. נשארו לך עוד # ניסיונות. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"‏לא ניתן להשתמש בכרטיס ה-SIM. יש ליצור קשר עם הספק."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="two">‏קוד ה-PUK של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות לפני שכרטיס ה-SIM יינעל לצמיתות.</item>
-      <item quantity="many">‏קוד ה-PUK של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות לפני שכרטיס ה-SIM יינעל לצמיתות.</item>
-      <item quantity="other">‏קוד ה-PUK של כרטיס ה-SIM שגוי. נותרו לך עוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות לפני שכרטיס ה-SIM יינעל לצמיתות.</item>
-      <item quantity="one">‏קוד ה-PUK של כרטיס ה-SIM שגוי. נותר לך ניסיון <xliff:g id="NUMBER_0">%d</xliff:g> נוסף לפני שכרטיס ה-SIM יינעל לצמיתות.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{‏קוד ה-PUK של כרטיס ה-SIM שגוי. נשאר לך עוד ניסיון אחד (#) לפני שכרטיס ה-SIM יינעל לתמיד.}two{‏קוד ה-PUK של כרטיס ה-SIM שגוי. נשארו לך עוד # ניסיונות לפני שכרטיס ה-SIM יינעל לתמיד.}many{‏קוד ה-PUK של כרטיס ה-SIM שגוי. נשארו לך עוד # ניסיונות לפני שכרטיס ה-SIM יינעל לתמיד.}other{‏קוד ה-PUK של כרטיס ה-SIM שגוי. נשארו לך עוד # ניסיונות לפני שכרטיס ה-SIM יינעל לתמיד.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"‏נכשלה פעולת קוד הגישה של כרטיס ה-SIM"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"‏הניסיון לביטול הנעילה של כרטיס ה-SIM באמצעות קוד PUK נכשל!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"החלפת שיטת קלט"</string>
@@ -95,18 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"המכשיר ננעל באופן ידני"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"לא זוהתה"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"לזיהוי הפנים יש להפעיל את הגישה למצלמה בהגדרות"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="two">‏יש להזין קוד אימות של כרטיס SIM. נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות נוספים.</item>
-      <item quantity="many">‏יש להזין קוד אימות של כרטיס SIM. נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות נוספים.</item>
-      <item quantity="other">‏יש להזין קוד אימות של כרטיס SIM. נותרו לך <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות נוספים.</item>
-      <item quantity="one">‏יש להזין קוד אימות של כרטיס SIM. נותר לך ניסיון נוסף (<xliff:g id="NUMBER_0">%d</xliff:g>) לפני שיהיה צורך ליצור קשר עם הספק כדי לבטל את נעילת המכשיר.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="two">‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נותרו לך <xliff:g id="_NUMBER_1">%d</xliff:g> ניסיונות נוספים לפני שכרטיס ה-SIM יינעל באופן סופי. למידע נוסף, ניתן לפנות לספק שלך.</item>
-      <item quantity="many">‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נותרו לך <xliff:g id="_NUMBER_1">%d</xliff:g> ניסיונות נוספים לפני שכרטיס ה-SIM יינעל באופן סופי. למידע נוסף, ניתן לפנות לספק שלך.</item>
-      <item quantity="other">‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נותרו לך <xliff:g id="_NUMBER_1">%d</xliff:g> ניסיונות נוספים לפני שכרטיס ה-SIM יינעל באופן סופי. למידע נוסף, ניתן לפנות לספק שלך.</item>
-      <item quantity="one">‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נותר לך ניסיון אחד (<xliff:g id="_NUMBER_0">%d</xliff:g>) נוסף לפני שכרטיס ה-SIM יינעל באופן סופי. למידע נוסף, ניתן לפנות לספק שלך.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{‏יש להזין את קוד האימות של כרטיס ה-SIM. נשאר לך עוד ניסיון אחד (#) לפני שיהיה צורך ליצור קשר עם הספק כדי לבטל את נעילת המכשיר.}two{‏יש להזין את קוד האימות של כרטיס ה-SIM. נשארו לך עוד # ניסיונות.}many{‏יש להזין את קוד האימות של כרטיס ה-SIM. נשארו לך עוד # ניסיונות.}other{‏יש להזין את קוד האימות של כרטיס ה-SIM. נשארו לך עוד # ניסיונות.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נשאר לך עוד ניסיון אחד (#) לפני שכרטיס ה-SIM יינעל לתמיד. למידע נוסף, ניתן לפנות לספק.}two{‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נשארו לך עוד # ניסיונות לפני שכרטיס ה-SIM יינעל לתמיד. למידע נוסף, ניתן לפנות לספק.}many{‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נשארו לך עוד # ניסיונות לפני שכרטיס ה-SIM יינעל לתמיד. למידע נוסף, ניתן לפנות לספק.}other{‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נשארו לך עוד # ניסיונות לפני שכרטיס ה-SIM יינעל לתמיד. למידע נוסף, ניתן לפנות לספק.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ברירת מחדל"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"בועה"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"אנלוגי"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 471bc12..efe13ec 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"パスワードの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後にもう一度お試しください。"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ロック解除パターンの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後にもう一度お試しください。"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM PIN コードが無効です。お使いのデバイスをロック解除するには携帯通信会社にお問い合わせいただく必要があります。"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM PIN コードが無効です。入力できるのはあと <xliff:g id="NUMBER_1">%d</xliff:g> 回です。</item>
-      <item quantity="one">SIM PIN コードが無効です。入力できるのはあと <xliff:g id="NUMBER_0">%d</xliff:g> 回です。この回数を超えると、お使いのデバイスをロック解除するのに携帯通信会社にお問い合わせいただく必要があります。</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM PIN コードが無効です。入力できるのはあと # 回です。この回数を超えると、お使いのデバイスをロック解除するのに携帯通信会社にお問い合わせいただく必要があります。}other{SIM PIN コードが無効です。入力できるのはあと # 回です。}}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM は使用できません。携帯通信会社にお問い合わせください。"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM PUK コードが無効です。入力できるのはあと <xliff:g id="NUMBER_1">%d</xliff:g> 回です。この回数を超えると SIM は完全に使用できなくなります。</item>
-      <item quantity="one">SIM PUK コードが無効です。入力できるのはあと <xliff:g id="NUMBER_0">%d</xliff:g> 回です。この回数を超えると SIM は完全に使用できなくなります。</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM PUK コードが無効です。入力できるのはあと # 回です。この回数を超えると SIM は完全に使用できなくなります。}other{SIM PUK コードが無効です。入力できるのはあと # 回です。この回数を超えると SIM は完全に使用できなくなります。}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN 操作に失敗しました。"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK 操作に失敗しました。"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"入力方法の切り替え"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"デバイスは手動でロックされました"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"認識されませんでした"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"顔認証の使用: 設定でカメラアクセスを有効にしてください"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM PIN を入力してください。入力できるのはあと <xliff:g id="NUMBER_1">%d</xliff:g> 回です。</item>
-      <item quantity="one">SIM PIN を入力してください。入力できるのはあと <xliff:g id="NUMBER_0">%d</xliff:g> 回です。この回数を超えた場合は、携帯通信会社にお問い合わせください。</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM が無効になりました。続行するには PUK コードを入力してください。入力できるのはあと <xliff:g id="_NUMBER_1">%d</xliff:g> 回です。この回数を超えると SIM は完全に使用できなくなります。詳しくは携帯通信会社にお問い合わせください。</item>
-      <item quantity="one">SIM が無効になりました。続行するには PUK コードを入力してください。入力できるのはあと <xliff:g id="_NUMBER_0">%d</xliff:g> 回です。この回数を超えると SIM は完全に使用できなくなります。詳しくは携帯通信会社にお問い合わせください。</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM PIN を入力してください。入力できるのはあと # 回です。この回数を超えると、お使いのデバイスをロック解除するのに携帯通信会社にお問い合わせいただく必要があります。}other{SIM PIN を入力してください。入力できるのはあと # 回です。}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM が無効になりました。続行するには PUK コードを入力してください。入力できるのはあと # 回です。この回数を超えると SIM は完全に使用できなくなります。詳しくは携帯通信会社にお問い合わせください。}other{SIM が無効になりました。続行するには PUK コードを入力してください。入力できるのはあと # 回です。この回数を超えると SIM は完全に使用できなくなります。詳しくは携帯通信会社にお問い合わせください。}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"デフォルト"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"バブル"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"アナログ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index 6f9fed9..67f85f0 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"თქვენ არასწორად აკრიფეთ პაროლი <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. \n\nცადეთ ხელახლა <xliff:g id="NUMBER_1">%2$d</xliff:g> წამში."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"თქვენ არასწორად დახატეთ განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. \n\nცადეთ ხელახლა <xliff:g id="NUMBER_1">%2$d</xliff:g> წამში."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM ბარათის PIN-კოდი არასწორია. ახლა თქვენი მოწყობილობის განსაბლოკად თქვენს ოპერატორთან დაკავშირება მოგიწევთ."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM ბარათის PIN-კოდი არასწორია. თქვენ დაგრჩათ <xliff:g id="NUMBER_1">%d</xliff:g> მცდელობა.</item>
-      <item quantity="one">SIM ბარათის PIN-კოდი არასწორია. თქვენ დაგრჩათ <xliff:g id="NUMBER_0">%d</xliff:g> მცდელობა, რომლის შემდეგაც თქვენი მოწყობილობის განსაბლოკად თქვენს ოპერატორთან დაკავშირება მოგიწევთ.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM-ის PIN კოდი არასწორია. თქვენ დაგრჩათ # მცდელობა, რის შემდეგაც მოწყობილობის განსაბლოკად ოპერატორთან დაკავშირება მოგიწევთ.}other{SIM ბარათის PIN-კოდი არასწორია. თქვენ დაგრჩათ # მცდელობა. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM ბარათი გამოუსადეგარია. დაუკავშირდით თქვენს ოპერატორს."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM ბარათის PUK-კოდი არასწორია. თქვენ დაგრჩათ <xliff:g id="NUMBER_1">%d</xliff:g> მცდელობა, რომელთა შემდეგაც თქვენი SIM სამუდამოდ გამოუსადეგარი გახდება.</item>
-      <item quantity="one">SIM ბარათის PUK-კოდი არასწორია. თქვენ დაგრჩათ <xliff:g id="NUMBER_0">%d</xliff:g> მცდელობა, რომლის შემდეგაც თქვენი SIM სამუდამოდ გამოუსადეგარი გახდება.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM ბარათის PUK-კოდი არასწორია. თქვენ დაგრჩათ # მცდელობა, რის შემდეგაც თქვენი SIM სამუდამოდ გამოუსადეგარი გახდება.}other{არასწორი SIM ბარათის PUK-კოდი. თქვენ დაგრჩათ # მცდელობა, სანამ SIM ბარათი სამუდამოდ გამოუსადეგარი გახდება.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM ბარათის PIN-კოდით განბლოკვა ვერ მოხერხდა!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM ბარათის PUK-კოდით განბლოკვა ვერ მოხერხდა!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"შეყვანის მეთოდის გადართვა"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"მოწყობილობა ხელით ჩაიკეტა"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"არ არის ამოცნობილი"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"სახით განბლოკვით სარგებლობისთვის, ჩართეთ კამერაზე წვდომა პარამეტრებში"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">შეიყვანეთ SIM ბარათის PIN-კოდი. თქვენ დაგრჩათ <xliff:g id="NUMBER_1">%d</xliff:g> მცდელობა.</item>
-      <item quantity="one">შეიყვანეთ SIM ბარათის PIN-კოდი. თქვენ დაგრჩათ <xliff:g id="NUMBER_0">%d</xliff:g> მცდელობა, რომლის შემდეგაც მოწყობილობის განსაბლოკად დაგჭირდებათ თქვენს ოპერატორთან დაკავშირება.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM ბარათი ახლა დეაქტივირებულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. თქვენ დაგრჩათ <xliff:g id="_NUMBER_1">%d</xliff:g> მცდელობა, სანამ SIM სამუდამოდ გამოუსადეგარი გახდება. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს.</item>
-      <item quantity="one">SIM ბარათი ახლა დეაქტივირებულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. თქვენ დაგრჩათ <xliff:g id="_NUMBER_0">%d</xliff:g> მცდელობა, სანამ SIM სამუდამოდ გამოუსადეგარი გახდება. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{შეიყვანეთ SIM ბარათის PIN-კოდი. თქვენ დაგრჩათ # მცდელობა, რის შემდეგაც მოწყობილობის განსაბლოკად დაგჭირდებათ თქვენს ოპერატორთან დაკავშირება.}other{შეიყვანეთ SIM ბარათის PIN-კოდი. თქვენ დაგრჩათ # მცდელობა.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM ბარათი ახლა გათიშულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. თქვენ დაგრჩათ # მცდელობა, სანამ SIM სამუდამოდ გამოუსადეგარი გახდება. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს.}other{SIM ბარათი ახლა გათიშულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. თქვენ დაგრჩათ # მცდელობა, სანამ SIM სამუდამოდ გამოუსადეგარი გახდება. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ნაგულისხმევი"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"ბუშტი"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ანალოგური"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index f4a51bd..71e9a9d 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Құпия сөз <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Құлыпты ашу өрнегі <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM PIN коды дұрыс емес, операторға хабарласып, құрылғының құлпын ашуды сұраңыз."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM PIN коды дұрыс емес. <xliff:g id="NUMBER_1">%d</xliff:g> әрекет қалды.</item>
-      <item quantity="one">SIM PIN коды дұрыс емес. <xliff:g id="NUMBER_0">%d</xliff:g> әрекет қалды. Одан кейін құрылғы құлпын ашу үшін операторға хабарласуға тура келеді.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM картасының PIN коды дұрыс емес. # мүмкіндігіңіз қалды. Одан кейін құрылғы құлпын ашу үшін операторға хабарласуға тура келеді.}other{SIM картасының PIN коды дұрыс емес. # әрекет қалды. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM қолданыстан шыққан. Оператормен хабарласыңыз."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM PUK коды дұрыс емес. <xliff:g id="NUMBER_1">%d</xliff:g> әрекет қалды. Одан кейін SIM біржола қолданыстан шығады.</item>
-      <item quantity="one">SIM PUK коды дұрыс емес. <xliff:g id="NUMBER_0">%d</xliff:g> әрекет қалды. Одан кейін SIM біржола қолданыстан шығады.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM картасының PUK коды дұрыс емес, # әрекеттен кейін SIM картасы біржола құлыпталады.}other{SIM картасының PUK коды дұрыс емес, # әрекеттен кейін SIM картасы біржола құлыпталады.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN кодымен құлпы ашылмады!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK кодымен құлпы ашылмады!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Енгізу әдісін ауыстыру"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Құрылғы қолмен құлыпталды"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Танылмады"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Face Unlock функциясын пайдалану үшін параметрлерден камераны пайдалану рұқсатын қосыңыз."</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM PIN кодын енгізіңіз. <xliff:g id="NUMBER_1">%d</xliff:g> мүмкіндік қалды, одан кейін оператордан SIM картасының құлпын ашуды сұрауға тура келеді.</item>
-      <item quantity="one">SIM PIN кодын енгізіңіз. <xliff:g id="NUMBER_0">%d</xliff:g> мүмкіндік қалды, одан кейін оператордан SIM картасының құлпын ашуды сұрауға тура келеді.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. <xliff:g id="_NUMBER_1">%d</xliff:g> мүмкіндік қалды, одан кейін SIM картасы біржола құлыпталады. Толығырақ мәліметті оператордан алыңыз.</item>
-      <item quantity="one">SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. <xliff:g id="_NUMBER_0">%d</xliff:g> мүмкіндік қалды, одан кейін SIM картасы біржола құлыпталады. Толығырақ мәліметті оператордан алыңыз.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM картасының PIN кодын енгізіңіз. # мүмкіндік қалды, одан кейін оператордан SIM картасының құлпын ашуды сұрауға тура келеді.}other{SIM картасының PIN кодын енгізіңіз. # әрекет қалды.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. # мүмкіндік қалды, одан кейін SIM картасы біржола құлыпталады. Толығырақ мәліметті оператордан алыңыз.}other{SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. # мүмкіндік қалды, одан кейін SIM картасы біржола құлыпталады. Толығырақ мәліметті оператордан алыңыз.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Әдепкі"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Көпіршік"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Аналогтық"</string>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index 8c90dec..645f6387 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"អ្នក​បាន​វាយ​បញ្ចូល​ពាក្យ​សម្ងាត់​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដង​ហើយ។ \n\nសូម​ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%2$d</xliff:g> វិនាទី​ទៀត។"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដង​ហើយ។ \n\nសូមព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%2$d</xliff:g> វិនាទី​ទៀត។"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"កូដ PIN របស់​ស៊ីម​មិន​ត្រឹមត្រូវ​ទេ អ្នក​ត្រូវ​ទាក់ទង​ទៅក្រុមហ៊ុន​បម្រើ​សេវា​ទូរសព្ទ​របស់​អ្នក​ឥឡូវ​នេះ ដើម្បី​ដោះ​សោ​ឧបករណ៍​របស់​អ្នក។"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">កូដ PIN របស់​ស៊ីម​មិន​ត្រឹមត្រូវ​ទេ អ្នក​អាច​ព្យាយាម​បាន <xliff:g id="NUMBER_1">%d</xliff:g> ដងទៀត។</item>
-      <item quantity="one">កូដ PIN របស់​ស៊ីម​មិន​ត្រឹមត្រូវ​ទេ ប្រសិន​បើ​អ្នក​បញ្ចូល​កូដខុស <xliff:g id="NUMBER_0">%d</xliff:g> ដងទៀត អ្នក​ត្រូវ​ទាក់ទង​ទៅ​ក្រុមហ៊ុន​បម្រើ​សេវាទូរសព្ទ​របស់អ្នក ដើម្បី​ដោះសោ​ឧបករណ៍របស់អ្នក។</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{កូដ PIN របស់ស៊ីម​មិនត្រឹមត្រូវទេ អ្នកអាច​ព្យាយាម​បញ្ចូលបាន # ដងទៀត មុនពេលដែល​ត្រូវទាក់ទង​ទៅក្រុមហ៊ុន​សេវាទូរសព្ទ​របស់អ្នក ដើម្បី​ដោះសោ​ឧបករណ៍​របស់អ្នក។}other{លេខ​កូដ​ PIN របស់​ស៊ីម​មិន​ត្រឹមត្រូវ​ អ្នកនៅ​សល់​ការ​ព្យាយាម # ដង​ទៀត។ }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"ស៊ីម​មិន​អាច​ប្រើ​បាន​ទេ។ សូម​ទាក់ទង​ទៅក្រុមហ៊ុន​បម្រើ​សេវា​ទូរសព្ទ​របស់​អ្នក។"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">កូដ PUK របស់​ស៊ីម​មិន​ត្រឹមត្រូវ​ទេ ប្រសិន​បើ​អ្នក​បញ្ចូល​កូដខុស <xliff:g id="NUMBER_1">%d</xliff:g> ដងទៀត ស៊ីមនឹង​មិន​អាច​ប្រើ​បាន​ជា​អចិន្ត្រៃយ៍។</item>
-      <item quantity="one">កូដ PUK របស់​ស៊ីម​មិន​ត្រឹមត្រូវ​ទេ ប្រសិន​បើ​អ្នក​បញ្ចូល​កូដខុស <xliff:g id="NUMBER_0">%d</xliff:g> ដងទៀត ស៊ីមនឹង​មិន​អាច​ប្រើ​បាន​ជា​អចិន្ត្រៃយ៍។</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{កូដ PUK របស់​ស៊ីម​មិន​ត្រឹមត្រូវ​ទេ អ្នក​នៅ​សល់​ការ​ព្យាយាម # ដង​ទៀត​ មុន​ពេល​​ស៊ីម​មិន​អាច​ប្រើ​បាន​ជាអចិន្ត្រៃយ៍។}other{លេខ​កូដ PUK ស៊ីម​មិន​ត្រឹមត្រូវ អ្នកនៅ​សល់​កា​រព្យាយាម # ដង​ទៀត មុន​ពេល​ស៊ីម​មិន​អាច​ប្រើបាន​ជាអចិន្ត្រៃយ៍។}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"មិន​អាច​ដោះ​សោ​ដោយ​ប្រើកូដ​ PIN របស់​ស៊ីម​បានទេ!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"មិន​អាច​ដោះ​សោ​ដោយ​ប្រើកូដ​ PUK របស់​ស៊ីម​បានទេ!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ប្ដូរ​វិធី​បញ្ចូល"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"ឧបករណ៍ត្រូវបានចាក់សោដោយអ្នកប្រើផ្ទាល់"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"មិនអាចសម្គាល់បានទេ"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"ដើម្បីដោះសោតាមទម្រង់មុខ សូមបើកសិទ្ធិចូលប្រើកាមេរ៉ានៅក្នុងការកំណត់"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">បញ្ចូល​កូដ PIN របស់ស៊ីម។ អ្នកនៅ​សល់ការ​ព្យាយាម <xliff:g id="NUMBER_1">%d</xliff:g> ដងទៀត។</item>
-      <item quantity="one">បញ្ចូលកូដ PIN របស់ស៊ីម។ អ្នក​នៅសល់​ការព្យាយាម <xliff:g id="NUMBER_0">%d</xliff:g> ដង​ទៀត មុន​ពេល​ដែលអ្នក​ត្រូវទាក់ទង​ទៅ​ក្រុមហ៊ុន​សេវា​ទូរសព្ទ​របស់អ្នក​ដើម្បី​ដោះសោ​ឧបករណ៍​របស់អ្នក។</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">ឥឡូវនេះស៊ីមត្រូវបានបិទ។ សូមបញ្ចូលកូដ PUK ដើម្បីបន្ត។ អ្នកនៅសល់ការព្យាយាម <xliff:g id="_NUMBER_1">%d</xliff:g> ដងទៀត​មុនពេល​ស៊ីម​មិនអាច​ប្រើបាន​ជា​អចិន្ត្រៃយ៍។ ទាក់ទង​ទៅ​ក្រុមហ៊ុន​សេវា​ទូរសព្ទ​សម្រាប់ព័ត៌មានលម្អិត។</item>
-      <item quantity="one">ឥឡូវនេះស៊ីមត្រូវបានបិទ។ សូមបញ្ចូលកូដ PUK ដើម្បីបន្ត។ អ្នកនៅសល់ការព្យាយាម <xliff:g id="_NUMBER_0">%d</xliff:g> ដងទៀតមុនពេលស៊ីមមិនអាចប្រើបានជាអចិន្ត្រៃយ៍។ ទាក់ទង​ទៅ​ក្រុមហ៊ុន​សេវា​ទូរសព្ទ​សម្រាប់​ព័ត៌មាន​លម្អិត។</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{បញ្ចូលកូដ PIN របស់ស៊ីម។ អ្នក​នៅសល់​ការព្យាយាម # ដង​ទៀត មុន​ពេល​ដែលអ្នក​ត្រូវទាក់ទង​ទៅ​ក្រុមហ៊ុន​សេវា​ទូរសព្ទ​របស់អ្នក​ដើម្បី​ដោះសោ​ឧបករណ៍​របស់អ្នក។}other{បញ្ចូល​កូដ PIN របស់​ស៊ីម។ អ្នកនៅ​សល់​ការ​ព្យាយាម ​# ដង​ទៀត។}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{ឥឡូវនេះស៊ីមត្រូវបានបិទ។ សូមបញ្ចូលកូដ PUK ដើម្បីបន្ត។ អ្នកនៅសល់ការព្យាយាម # ដងទៀតមុនពេលស៊ីមមិនអាចប្រើបានជាអចិន្ត្រៃយ៍។ ទាក់ទង​ទៅ​ក្រុមហ៊ុន​សេវា​ទូរសព្ទ​សម្រាប់ព័ត៌មានលម្អិត។}other{ឥឡូវនេះស៊ីមត្រូវបានបិទ។ សូមបញ្ចូលកូដ PUK ដើម្បីបន្ត។ អ្នកនៅសល់ការព្យាយាម # ដងទៀត​មុនពេល​ស៊ីម​មិនអាច​ប្រើបាន​ជា​អចិន្ត្រៃយ៍។ ទាក់ទង​ទៅ​ក្រុមហ៊ុន​សេវា​ទូរសព្ទ​សម្រាប់ព័ត៌មានលម្អិត។}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"លំនាំដើម"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"ពពុះ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"អាណាឡូក"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index 3299872..e5e4a5f 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ನಿಮ್ಮ ಪಾಸ್‍‍ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ನಮೂದಿಸಿದ್ದೀರಿ. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ನಿಮ್ಮ ಅನ್‍‍ಲಾಕ್ ಪ್ಯಾಟರ್ನ್‌ ಅನ್ನು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಎಳೆದಿದ್ದೀರಿ. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ಸಿಮ್‌ ಪಿನ್‌ ಕೋಡ್‌ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ನೀವು ಈ ಕೂಡಲೇ ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಬೇಕು."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">ಸಿಮ್‌ ಪಿನ್ ಕೋಡ್‌ ತಪ್ಪಾಗಿದೆ, ನಿಮಗೆ <xliff:g id="NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.</item>
-      <item quantity="other">ಸಿಮ್‌ ಪಿನ್ ಕೋಡ್‌ ತಪ್ಪಾಗಿದೆ, ನಿಮಗೆ <xliff:g id="NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM ಪಿನ್ ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡುವುದಕ್ಕಾಗಿ ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನ ಬಾಕಿ ಉಳಿದಿದೆ.}one{SIM ಪಿನ್ ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. }other{SIM ಪಿನ್ ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"ಸಿಮ್‌ ನಿಷ್ಪ್ರಯೋಜಕವಾಗಿದೆ. ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">ಸಿಮ್‌ PUK ಕೋಡ್‌ ತಪ್ಪಾಗಿದೆ, <xliff:g id="NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳ ನಂತರ ಸಿಮ್‌ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುತ್ತದೆ.</item>
-      <item quantity="other">ಸಿಮ್‌ PUK ಕೋಡ್‌ ತಪ್ಪಾಗಿದೆ, <xliff:g id="NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳ ನಂತರ ಸಿಮ್‌ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುತ್ತದೆ.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM PUK ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, SIM ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನ ಬಾಕಿ ಉಳಿದಿದೆ.}one{SIM PUK ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, SIM ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.}other{SIM PUK ಕೋಡ್ ತಪ್ಪಾಗಿದೆ, SIM ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"ಸಿಮ್‌ ಪಿನ್‌ ಕಾರ್ಯಾಚರಣೆ ವಿಫಲಗೊಂಡಿದೆ!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"ಸಿಮ್‌ PUK ಕಾರ್ಯಾಚರಣೆ ವಿಫಲಗೊಂಡಿದೆ!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ಇನ್‌ಪುಟ್‌‌ ವಿಧಾನ ಬದಲಿಸಿ"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"ಸಾಧನವನ್ನು ಹಸ್ತಚಾಲಿತವಾಗಿ ಲಾಕ್‌ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಬಳಸಲು, ಸೆಟ್ಟಿಂಗ್ಸ್‌ನಲ್ಲಿ ಕ್ಯಾಮರಾ ಪ್ರವೇಶ ಆನ್ ಮಾಡಿ"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ. ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.</item>
-      <item quantity="other">ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ. ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">ಸಿಮ್ ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ಸಿಮ್ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ <xliff:g id="_NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.</item>
-      <item quantity="other">ಸಿಮ್ ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ಸಿಮ್ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ <xliff:g id="_NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM ಪಿನ್ ಅನ್ನು ನಮೂದಿಸಿ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡುವುದಕ್ಕಾಗಿ ನಿಮ್ಮ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನ ಬಾಕಿ ಉಳಿದಿದೆ.}one{SIM ಪಿನ್ ಅನ್ನು ನಮೂದಿಸಿ. ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.}other{SIM ಪಿನ್ ಅನ್ನು ನಮೂದಿಸಿ. ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ. SIM ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನ ಬಾಕಿ ಉಳಿದಿದೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.}one{SIM ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ. SIM ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.}other{SIM ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ. SIM ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ # ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ಡೀಫಾಲ್ಟ್"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"ಬಬಲ್"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ಅನಲಾಗ್"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index ebddae2..4c1cfb7 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"비밀번호를 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g>초 후에 다시 시도하세요."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%1$d</xliff:g>번 잘못 그렸습니다. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g>초 후에 다시 시도하세요."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"잘못된 SIM PIN코드입니다. 이동통신사에 문의하여 기기를 잠금 해제해야 합니다."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">잘못된 SIM PIN 코드입니다. 입력을 <xliff:g id="NUMBER_1">%d</xliff:g>번 더 시도할 수 있습니다.</item>
-      <item quantity="one">잘못된 SIM PIN 코드입니다. 입력에 <xliff:g id="NUMBER_0">%d</xliff:g>번 더 실패할 경우 이동통신사에 문의하여 기기를 잠금 해제해야 합니다.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM의 PIN 코드가 잘못되었습니다. #회 이상 입력에 실패할 경우 이동통신사에 문의하여 기기를 잠금 해제해야 합니다.}other{SIM의 PIN 코드가 잘못되었습니다. 남은 시도 횟수는 #회입니다. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM을 사용할 수 없습니다. 이동통신사에 문의하세요."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">잘못된 SIM PUK 코드입니다. 입력에 <xliff:g id="NUMBER_1">%d</xliff:g>번 더 실패할 경우 SIM이 영구적으로 사용 중지됩니다.</item>
-      <item quantity="one">잘못된 SIM PUK 코드입니다. 입력에 <xliff:g id="NUMBER_0">%d</xliff:g>번 더 실패할 경우 SIM이 영구적으로 사용 중지됩니다.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM의 PUK 코드가 잘못되었습니다. #회 이상 입력에 실패할 경우 SIM을 완전히 사용할 수 없게 됩니다.}other{SIM의 PUK 코드가 잘못되었습니다. #회 이상 입력에 실패할 경우 SIM을 완전히 사용할 수 없게 됩니다.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN 작업이 실패했습니다."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK 작업이 실패했습니다."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"입력 방법 전환"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"기기가 수동으로 잠금 설정되었습니다."</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"인식할 수 없음"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"얼굴 인식 잠금 해제를 사용하려면 설정에서 카메라 액세스를 사용 설정하세요."</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM PIN을 입력하세요. 입력은 <xliff:g id="NUMBER_1">%d</xliff:g>번 더 시도할 수 있습니다.</item>
-      <item quantity="one">SIM PIN을 입력하세요. 입력에 <xliff:g id="NUMBER_0">%d</xliff:g>번 더 실패하면 이동통신사에 문의하여 기기를 잠금 해제해야 합니다.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. <xliff:g id="_NUMBER_1">%d</xliff:g>번 더 실패하면 SIM을 완전히 사용할 수 없게 됩니다. 자세한 내용은 이동통신사에 문의하세요.</item>
-      <item quantity="one">SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. <xliff:g id="_NUMBER_0">%d</xliff:g>번 더 실패하면 SIM을 완전히 사용할 수 없게 됩니다. 자세한 내용은 이동통신사에 문의하세요.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM의 PIN을 입력하세요. #회 이상 입력에 실패할 경우 이동통신사에 문의하여 기기를 잠금 해제해야 합니다.}other{SIM의 PIN을 입력하세요. 남은 시도 횟수는 #회입니다.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. #회 이상 입력에 실패할 경우 SIM을 완전히 사용할 수 없게 됩니다. 자세한 내용은 이동통신사에 문의하세요.}other{SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. #회 이상 입력에 실패할 경우 SIM을 완전히 사용할 수 없게 됩니다. 자세한 내용은 이동통신사에 문의하세요.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"기본"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"버블"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"아날로그"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index f6ed69d..ec276fe 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Түзмөктү ачуучу графикалык  ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секунддан кийин дагы аракет кылып көрүңүз."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM-картанын PIN-коду туура эмес. Эми түзмөктү бөгөттөн чыгаруу үчүн байланыш операторуңузга кайрылышыңыз керек."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM-картанын PIN-коду туура эмес, сизде <xliff:g id="NUMBER_1">%d</xliff:g> аракет калды.</item>
-      <item quantity="one">SIM-картанын PIN-коду туура эмес, сизде <xliff:g id="NUMBER_0">%d</xliff:g> аракет калды. Болбосо, түзмөктү бөгөттөн чыгаруу үчүн байланыш операторуңузга кайрылышыңыз керек.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM-картанын PIN коду туура эмес киргизилди. # аракет калды. Болбосо, түзмөктү бөгөттөн чыгаруу үчүн операторуңузга кайрылышыңыз керек болот.}other{SIM-картанын PIN коду туура эмес киргизилди. # аракет калды. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-карта жараксыз. Байланыш операторуңузга кайрылыңыз."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM-картанын PUK-коду туура эмес, SIM-картанын биротоло жарактан чыгаарына <xliff:g id="NUMBER_1">%d</xliff:g> аракет калды.</item>
-      <item quantity="one">SIM-картанын PUK-коду туура эмес, SIM-картанын биротоло жарактан чыгаарына <xliff:g id="NUMBER_0">%d</xliff:g> аракет калды.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM-картанын PUK коду туура эмес киргизилди. SIM-картанын биротоло жарактан чыгаарына # аракет калды.}other{SIM-картанын PUK коду туура эмес киргизилди. SIM-картанын биротоло жарактан чыгаарына # аракет калды.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM-картанын PIN-кодун ачуу кыйрады!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM-картанын PUK-кодун ачуу кыйрады!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Киргизүү ыкмасын өзгөртүү"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Түзмөк кол менен кулпуланды"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Таанылган жок"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Жөндөөлөрдөн камерага уруксат беришиңиз керек"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM-картанын PIN кодун киргизиңиз. Сизде <xliff:g id="NUMBER_1">%d</xliff:g> аракет калды.</item>
-      <item quantity="one">SIM-картанын PIN кодун киргизиңиз. Сизде <xliff:g id="NUMBER_0">%d</xliff:g> аракет калды, андан кийин түзмөктү бөгөттөн чыгаруу үчүн байланыш операторуна кайрылышыңыз керек болот.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. SIM-картанын биротоло жарактан чыгарына <xliff:g id="_NUMBER_1">%d</xliff:g> аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.</item>
-      <item quantity="one">SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. SIM-картанын биротоло жарактан чыгаарына <xliff:g id="_NUMBER_0">%d</xliff:g> аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM-картанын PIN кодун киргизиңиз. Сизде # аракет калды, андан кийин түзмөктү бөгөттөн чыгаруу үчүн байланыш операторуна кайрылышыңыз керек болот.}other{SIM-картанын PIN кодун киргизиңиз. # аракет калды.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK кодду киргизиңиз. SIM-картанын биротоло жарактан чыгаарына # аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.}other{SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK кодду киргизиңиз. SIM-картанын биротоло жарактан чыгарына # аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Демейки"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Көбүк"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Аналог"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index 1948f23..44051d8 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ທ່ານພິມລະຫັດຜ່ານຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. \n\nໃຫ້ລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ວິນາທີ."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ທ່ານແຕ້ມຮູບແບບປົດລັອກບໍ່ຖືກ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ວິນາທີ."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ລະຫັດ PIN ຂອງ SIM ບໍ່ຖືກຕ້ອງທ່ານຕ້ອງຕິດຕໍ່ຫາຜູ່ໃຫ້ບໍລິການ ເພື່ອປົດລັອກອຸປະກອນຂອງທ່ານ."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">ລະຫັດ SIM PIN ບໍ່ຖືກຕ້ອງ, ທ່ານຍັງພະຍາຍາມໄດ້ອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ຄັ້ງ.</item>
-      <item quantity="one">ລະຫັດ PIN ຂອງ SIM ບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອກ່ອນທີ່ທ່ານຈະຕ້ອງຕິດຕໍ່ຫາຜູ່ໃຫ້ບໍລິການຂອງທ່ານ ເພື່ອປົດລັອກອຸປະກອນຂອງທ່ານ.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{ລະຫັດ PIN ຂອງຊິມບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ # ເທື່ອກ່ອນທີ່ທ່ານຈະຕ້ອງຕິດຕໍ່ຫາຜູ້ໃຫ້ບໍລິການຂອງທ່ານເພື່ອປົດລັອກອຸປະກອນທ່ານ.}other{ລະຫັດ PIN ຂອງຊິມບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ # ເທື່ອ. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM ໃຊ້ບໍ່ໄດ້ແລ້ວ. ກະລຸນາຕິດຕໍ່ຫາຜູ່ໃຫ້ບໍລິການຂອງທ່ານ."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">ລະຫັດ PUK ຂອງ SIM ບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຂອງທ່ານຈະໃຊ້ບໍ່ໄດ້ຢ່າງຖາວອນ.</item>
-      <item quantity="one">ລະຫັດ PUK ຂອງ SIM ບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຂອງທ່ານຈະໃຊ້ບໍ່ໄດ້ຢ່າງຖາວອນ.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{ລະຫັດ PUK ຂອງຊິມບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ # ເທື່ອກ່ອນທີ່ຊິມຂອງທ່ານຈະບໍ່ສາມາດໃຊ້ໄດ້ຖາວອນ.}other{ລະຫັດ PUK ຂອງຊິມບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ # ເທື່ອກ່ອນທີ່ຊິມຂອງທ່ານຈະບໍ່ສາມາດໃຊ້ໄດ້ຖາວອນ.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"PIN ຂອງ SIM ເຮັດວຽກລົ້ມເຫຼວ!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"PUK ຂອງ SIM ເຮັດວຽກລົ້ມເຫຼວ!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ສະລັບຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"ອຸປະກອນຖືກສັ່ງໃຫ້ລັອກ"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"ບໍ່ຮູ້ຈັກ"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"ເພື່ອໃຊ້ການປົດລັອກດ້ວຍໜ້າ, ໃຫ້ເປີດໃຊ້ສິດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບໃນການຕັ້ງຄ່າ"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">ລະຫັດ SIM PIN ບໍ່ຖືກຕ້ອງ. ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ.</item>
-      <item quantity="one">ໃສ່ລະຫັດ SIM PIN. ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອກ່ອນທີ່ຈະຕ້ອງຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການເພື່ອປົດລັອກ.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">ຕອນນີ້ປິດການນຳໃຊ້ SIM ແລ້ວ. ໃສ່ລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="_NUMBER_1">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຈະບໍ່ສາມາດໃຊ້ໄດ້ຖາວອນ. ກະລຸນາຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ.</item>
-      <item quantity="one">ຕອນນີ້ປິດການນຳໃຊ້ SIM ແລ້ວ. ໃສ່ລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="_NUMBER_0">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຈະບໍ່ສາມາດໃຊ້ໄດ້ຖາວອນ. ກະລຸນາຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{ໃສ່ລະຫັດ PIN ຂອງຊິມ. ທ່ານສາມາດລອງໄດ້ອີກ # ເທື່ອກ່ອນທີ່ຈະຕ້ອງຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການຂອງທ່ານເພື່ອປົດລັອກອຸປະກອນທ່ານ.}other{ໃສ່ລະຫັດ PIN ຂອງຊິມ. ທ່ານສາມາດລອງໄດ້ອີກ # ເທື່ອ.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{ຕອນນີ້ປິດການນຳໃຊ້ຊິມແລ້ວ. ໃສ່ລະຫັດ PUK ເພື່ອສືບຕໍ່. ທ່ານສາມາດລອງໄດ້ອີກ # ເທື່ອກ່ອນທີ່ຊິມຈະບໍ່ສາມາດໃຊ້ໄດ້ຖາວອນ. ກະລຸນາຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ.}other{ຕອນນີ້ປິດການນຳໃຊ້ຊິມແລ້ວ. ໃສ່ລະຫັດ PUK ເພື່ອສືບຕໍ່. ທ່ານສາມາດລອງໄດ້ອີກ # ເທື່ອກ່ອນທີ່ຊິມຈະບໍ່ສາມາດໃຊ້ໄດ້ຖາວອນ. ກະລຸນາຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ຄ່າເລີ່ມຕົ້ນ"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"ຟອງ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ໂມງເຂັມ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index 59135a9..26c54c0 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -68,19 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai įvedėte slaptažodį. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai nupiešėte atrakinimo piešinį. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Netinkamas SIM kortelės PIN kodas. Reikės susisiekti su operatoriumi, kad atrakintų įrenginį."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Netinkamas SIM kortelės PIN kodas. Liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymas.</item>
-      <item quantity="few">Netinkamas SIM kortelės PIN kodas. Liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymai.</item>
-      <item quantity="many">Netinkamas SIM kortelės PIN kodas. Liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymo.</item>
-      <item quantity="other">Netinkamas SIM kortelės PIN kodas. Liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymų.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Netinkamas SIM kortelės PIN kodas. Jums liko # bandymas. Paskui reikės susisiekti su operatoriumi, kad atrakintumėte įrenginį.}one{Netinkamas SIM kortelės PIN kodas. Jums liko # bandymas. }few{Netinkamas SIM kortelės PIN kodas. Jums liko # bandymai. }many{Netinkamas SIM kortelės PIN kodas. Jums liko # bandymo. }other{Netinkamas SIM kortelės PIN kodas. Jums liko # bandymų. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM kortelės naudoti nebegalima. Susisiekite su operatoriumi."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Netinkamas SIM kortelės PUK kodas. Liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymas. Paskui visiškai nebegalėsite naudoti SIM kortelės.</item>
-      <item quantity="few">Netinkamas SIM kortelės PUK kodas. Liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymai. Paskui visiškai nebegalėsite naudoti SIM kortelės.</item>
-      <item quantity="many">Netinkamas SIM kortelės PUK kodas. Liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymo. Paskui visiškai nebegalėsite naudoti SIM kortelės.</item>
-      <item quantity="other">Netinkamas SIM kortelės PUK kodas. Liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymų. Paskui visiškai nebegalėsite naudoti SIM kortelės.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Netinkamas SIM kortelės PUK kodas. Jums liko # bandymas. Paskui visiškai nebegalėsite naudoti SIM kortelės.}one{Netinkamas SIM kortelės PUK kodas. Jums liko # bandymas. Paskui visiškai nebegalėsite naudoti SIM kortelės.}few{Netinkamas SIM kortelės PUK kodas. Jums liko # bandymai. Paskui visiškai nebegalėsite naudoti SIM kortelės.}many{Netinkamas SIM kortelės PUK kodas. Jums liko # bandymo. Paskui visiškai nebegalėsite naudoti SIM kortelės.}other{Netinkamas SIM kortelės PUK kodas. Jums liko # bandymų. Paskui visiškai nebegalėsite naudoti SIM kortelės.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Nepavyko atlikti SIM kortelės PIN kodo operacijos."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Nepavyko atlikti SIM kortelės PUK kodo operacijos."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Perjungti įvesties metodą"</string>
@@ -95,18 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Įrenginys užrakintas neautomatiškai"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Neatpažinta"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Jei nor. naud. atr. pagal veidą, įj. pr. prie fotoap. sk. „Nustatymai“"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Įveskite SIM kortelės PIN kodą. Jums liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymas.</item>
-      <item quantity="few">Įveskite SIM kortelės PIN kodą. Jums liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymai.</item>
-      <item quantity="many">Įveskite SIM kortelės PIN kodą. Jums liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymo.</item>
-      <item quantity="other">Įveskite SIM kortelės PIN kodą. Jums liko <xliff:g id="NUMBER_1">%d</xliff:g> bandymų.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko <xliff:g id="_NUMBER_1">%d</xliff:g> bandymas. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.</item>
-      <item quantity="few">SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko <xliff:g id="_NUMBER_1">%d</xliff:g> bandymai. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.</item>
-      <item quantity="many">SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko <xliff:g id="_NUMBER_1">%d</xliff:g> bandymo. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.</item>
-      <item quantity="other">SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko <xliff:g id="_NUMBER_1">%d</xliff:g> bandymų. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Įveskite SIM kortelės PIN kodą. Jums liko # bandymas. Paskui reikės susisiekti su operatoriumi, kad atrakintumėte įrenginį.}one{Įveskite SIM kortelės PIN kodą. Jums liko # bandymas.}few{Įveskite SIM kortelės PIN kodą. Jums liko # bandymai.}many{Įveskite SIM kortelės PIN kodą. Jums liko # bandymo.}other{Įveskite SIM kortelės PIN kodą. Jums liko # bandymų.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko # bandymas. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.}one{SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko # bandymas. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.}few{SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko # bandymai. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.}many{SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko # bandymo. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.}other{SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko # bandymų. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Numatytasis"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Debesėlis"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analoginis"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index 88bb114..fb913ea 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -68,17 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) esat ievadījis nepareizu paroli.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundes(-ēm)."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) esat nepareizi uzzīmējis atbloķēšanas kombināciju.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%2$d</xliff:g> sekundes(-ēm)."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Nepareizs SIM kartes PIN kods. Lai atbloķētu ierīci, sazinieties ar mobilo sakaru operatoru."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="zero">Nepareizs SIM kartes PIN kods. Varat mēģināt vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizes.</item>
-      <item quantity="one">Nepareizs SIM kartes PIN kods. Varat mēģināt vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizi.</item>
-      <item quantity="other">Nepareizs SIM kartes PIN kods. Varat mēģināt vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizes.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Nepareizs SIM kartes PIN. Varat mēģināt vēl # reizi. Kļūdas gadījumā būs jāsazinās ar mobilo sakaru operatoru, lai tas atbloķētu jūsu ierīci.}zero{Nepareizs SIM kartes PIN. Varat mēģināt vēl # reizes. }one{Nepareizs SIM kartes PIN. Varat mēģināt vēl # reizi. }other{Nepareizs SIM kartes PIN. Varat mēģināt vēl # reizes. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM karte nav lietojama. Sazinieties ar mobilo sakaru operatoru."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="zero">Nepareizs SIM kartes PUK kods. Varat mēģināt vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizes. Ja pēdējais mēģinājums būs kļūdains, SIM karti vairs nevarēs izmantot.</item>
-      <item quantity="one">Nepareizs SIM kartes PUK kods. Varat mēģināt vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizi. Ja pēdējais mēģinājums būs kļūdains, SIM karti vairs nevarēs izmantot.</item>
-      <item quantity="other">Nepareizs SIM kartes PUK kods. Varat mēģināt vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizes. Ja pēdējais mēģinājums būs kļūdains, SIM karti vairs nevarēs izmantot.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Nepareizs SIM kartes PUK kods. Varat mēģināt vēl # reizi. Kļūdas gadījumā SIM karti vairs nevarēs izmantot.}zero{Nepareizs SIM kartes PUK kods. Varat mēģināt vēl # reizes. Ja pēdējais mēģinājums būs kļūdains, SIM karti vairs nevarēs izmantot.}one{Nepareizs SIM kartes PUK kods. Varat mēģināt vēl # reizi. Ja pēdējais mēģinājums būs kļūdains, SIM karti vairs nevarēs izmantot.}other{Nepareizs SIM kartes PUK kods. Varat mēģināt vēl # reizes. Ja pēdējais mēģinājums būs kļūdains, SIM karti vairs nevarēs izmantot.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM kartes PIN koda ievadīšana neizdevās!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM kartes PUK koda ievadīšana neizdevās!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Pārslēgt ievades metodi"</string>
@@ -93,16 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Ierīce tika bloķēta manuāli."</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nav atpazīts"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Lai izmantotu autorizāciju pēc sejas, iestatījumos ieslēdziet piekļuvi kamerai."</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="zero">Ievadiet SIM kartes PIN. Varat mēģināt vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizes.</item>
-      <item quantity="one">Ievadiet SIM kartes PIN. Varat mēģināt vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizi.</item>
-      <item quantity="other">Ievadiet SIM kartes PIN. Varat mēģināt vēl <xliff:g id="NUMBER_1">%d</xliff:g> reizes.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="zero">SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl <xliff:g id="_NUMBER_1">%d</xliff:g> reizes. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.</item>
-      <item quantity="one">SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl <xliff:g id="_NUMBER_1">%d</xliff:g> reizi. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.</item>
-      <item quantity="other">SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl <xliff:g id="_NUMBER_1">%d</xliff:g> reizes. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Ievadiet SIM kartes PIN. Varat mēģināt vēl # reizi. Kļūdas gadījumā jums būs jāsazinās ar mobilo sakaru operatoru, lai atbloķētu savu ierīci.}zero{Ievadiet SIM kartes PIN. Jums ir atlikuši # mēģinājumi.}one{Ievadiet SIM kartes PIN. Jums ir atlicis # mēģinājums.}other{Ievadiet SIM kartes PIN. Jums ir atlikuši # mēģinājumi.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl # reizi. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.}zero{SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl # reizes. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.}one{SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl # reizi. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.}other{SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl # reizes. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Noklusējums"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Burbuļi"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogais"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index 7eb7a00..9769c7e 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Погрешно сте ја напишале вашата лозинка <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Погрешно сте ја нацртале вашата шема за отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. \n\nОбидете се повторно за <xliff:g id="NUMBER_1">%2$d</xliff:g> секунди."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Погрешен PIN-код за SIM, сега мора да контактирате со вашиот оператор за да го отклучите уредот."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Погрешен PIN-код за SIM, ви преостанува уште <xliff:g id="NUMBER_1">%d</xliff:g> обид.</item>
-      <item quantity="other">Погрешен PIN-код за SIM, ви преостануваат уште <xliff:g id="NUMBER_1">%d</xliff:g> обиди.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Погрешен PIN-код за SIM-картичката. Ви преостанува уште # обид пред да мора да контактирате со вашиот оператор за да го отклучи уредот.}one{Погрешен PIN-код за SIM, ви преостанува уште # обид. }other{Погрешен PIN-код за SIM, ви преостануваат уште # обиди. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-картичката е неупотреблива. Контактирајте со вашиот оператор."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Погрешен PUK-код за SIM, ви преостанува уште <xliff:g id="NUMBER_1">%d</xliff:g> обид пред SIM-картичката да стане трајно неупотреблива.</item>
-      <item quantity="other">Погрешен PUK-код за SIM, ви преостануваат уште <xliff:g id="NUMBER_1">%d</xliff:g> обиди пред SIM-картичката да стане трајно неупотреблива.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{ПУК кодот за SIM-картичката е неточен. Ви преостанува уште # обид, а потоа SIM-картичката ќе стане трајно неупотреблива.}one{Погрешен PUK-код за SIM, ви преостанува уште # обид пред SIM-картичката да стане трајно неупотреблива.}other{Погрешен PUK-код за SIM, ви преостануваат уште # обиди пред SIM-картичката да стане трајно неупотреблива.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM-картичката не се отклучи со PIN-кодот!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM-картичката не се отклучи со PUK-кодот!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Префрли метод за внесување"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Уредот е заклучен рачно"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Непознат"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"За „Отклучување со лик“, вклучете пристап до камерата"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Внесете PIN-код за SIM-картичката. Ви преостанува уште <xliff:g id="NUMBER_1">%d</xliff:g> обид.</item>
-      <item quantity="other">Внесете PIN-код за SIM-картичката. Ви преостануваат уште <xliff:g id="NUMBER_1">%d</xliff:g> обиди.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Ви преостанува уште <xliff:g id="_NUMBER_1">%d</xliff:g> обид пред SIM-картичката да стане трајно неупотреблива. Контактирајте го операторот за детали.</item>
-      <item quantity="other">SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Ви преостануваат уште <xliff:g id="_NUMBER_1">%d</xliff:g> обиди пред SIM-картичката да стане трајно неупотреблива. Контактирајте го операторот за детали.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Внесете PIN-код за SIM-картичката. Ви преостанува уште # обид пред да мора да контактирате со вашиот оператор да го отклучи уредот.}one{Внесете PIN на SIM. Имате уште # обид.}other{Внесете PIN на SIM. Имате уште # обиди.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Ви преостанува уште # обид пред SIM-картичката да стане трајно неупотреблива. Контактирајте го операторот за детали.}one{SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Ви преостанува уште # обид пред SIM-картичката да стане трајно неупотреблива. Контактирајте го операторот за детали.}other{SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Ви преостануваат уште # обиди пред SIM-картичката да стане трајно неупотреблива. Контактирајте го операторот за детали.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Стандарден"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Балонче"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Аналоген"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index 32bf03c..e1d3f82 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ നിങ്ങളുടെ പാസ്‌വേഡ് ‌തെറ്റായി ‌ടൈപ്പുചെയ്തു. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> സെക്കന്റിനു‌ശേഷം വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ അൺലോക്ക് പാറ്റേൺ ‌തെറ്റായി ‌വരച്ചു. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> സെക്കന്റിനു‌ശേഷം വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"സിം പിൻ കോഡ് തെറ്റാണ്, നിങ്ങളുടെ ഉപകരണം അൺലോക്കുചെയ്യാൻ ഇനി നിങ്ങളുടെ കാരിയറുമായി ബന്ധപ്പെടണം."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">സിം പിൻ കോഡ് തെറ്റാണ്, നിങ്ങൾക്ക് <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു.</item>
-      <item quantity="one">സിം പിൻ കോഡ് തെറ്റാണ്, ഉപകരണം അൺലോക്കുചെയ്യാൻ സേവനദാതാവുമായി ബന്ധപ്പെടേണ്ടിവരുന്നതിനു മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER_0">%d</xliff:g> ശ്രമം കൂടി ശേഷിക്കുന്നു.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{സിം പിൻ കോഡ് തെറ്റാണ്, # ശ്രമം ശേഷിക്കുന്നു, അതുകഴിഞ്ഞാൽ ഉപകരണം അൺലോക്ക് ചെയ്യാൻ സേവനദാതാവിനെ ബന്ധപ്പെണം.}other{സിം പിൻ കോഡ് തെറ്റാണ്, # ശ്രമങ്ങൾ ശേഷിക്കുന്നു. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"സിം ഉപയോഗയോഗ്യമല്ല. നിങ്ങളുടെ കാരിയറെ ബന്ധപ്പെടുക."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">സിം PUK കോഡ് തെറ്റാണ്, സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു.</item>
-      <item quantity="one">സിം PUK കോഡ് തെറ്റാണ്, സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി നിങ്ങൾക്ക് <xliff:g id="NUMBER_0">%d</xliff:g> ശ്രമം കൂടി ശേഷിക്കുന്നു.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{സിം PUK കോഡ് തെറ്റാണ്, # ശ്രമം ശേഷിക്കുന്നു, അതുകഴിഞ്ഞാൽ സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകും.}other{സിം PUK കോഡ് തെറ്റാണ്, # ശ്രമങ്ങൾ ശേഷിക്കുന്നു, അതുകഴിഞ്ഞാൽ സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകും.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"പിൻ ഉപയോഗിച്ച് സിം അൺലോക്കു‌ചെയ്യാനുള്ള ‌ശ്രമം പരാജയപ്പെട്ടു!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"PUK ഉപയോഗിച്ച് സിം അൺലോക്കു‌ചെയ്യാനുള്ള ‌ശ്രമം പരാജയപ്പെട്ടു!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ഇൻപുട്ട് രീതി മാറുക"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"ഉപകരണം നേരിട്ട് ലോക്കുചെയ്തു"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"തിരിച്ചറിയുന്നില്ല"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"ഫെയ്സ് അൺലോക്കിന് ക്രമീകരണത്തിൽ ക്യാമറാ ആക്സസ് ഓണാക്കൂ"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">സിം പിൻ നൽകുക. നിങ്ങൾക്ക് <xliff:g id="NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു.</item>
-      <item quantity="one">സിം പിൻ നൽകുക. ഉപകരണം അൺലോക്ക് ചെയ്യാൻ കാരിയറുമായി ബന്ധപ്പെടേണ്ടിവരുന്നതിന് മുമ്പ് <xliff:g id="NUMBER_0">%d</xliff:g> ശ്രമം കൂടി ശേഷിക്കുന്നു.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി <xliff:g id="_NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു. വിശദാംശങ്ങൾക്ക് കാരിയറുമായി ബന്ധപ്പെടുക.</item>
-      <item quantity="one">സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി <xliff:g id="_NUMBER_0">%d</xliff:g> ശ്രമം കൂടി ശേഷിക്കുന്നു. വിശദാംശങ്ങൾക്ക് കാരിയറുമായി ബന്ധപ്പെടുക.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{സിം പിൻ നൽകുക. # ശ്രമം ശേഷിക്കുന്നു, അതുകഴിഞ്ഞാൽ ഉപകരണം അൺലോക്ക് ചെയ്യാൻ സേവനദാതാവിനെ ബന്ധപ്പെടണം.}other{സിം പിൻ നൽകുക. # ശ്രമങ്ങൾ ശേഷിക്കുന്നു.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമായിരിക്കുന്നു. തുടരുന്നതിന് PUK കോഡ് നൽകുക. # ശ്രമം ശേഷിക്കുന്നു, അതുകഴിഞ്ഞാൽ സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകും. വിശദാംശങ്ങൾക്ക് സേവനദാതാവിനെ ബന്ധപ്പെടുക.}other{സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമായിരിക്കുന്നു. തുടരുന്നതിന് PUK കോഡ് നൽകുക. # ശ്രമങ്ങൾ ശേഷിക്കുന്നു, അതുകഴിഞ്ഞാൽ സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകും. വിശദാംശങ്ങൾക്ക് സേവനദാതാവിനെ ബന്ധപ്പെടുക.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ഡിഫോൾട്ട്"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"ബബിൾ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"അനലോഗ്"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index ba167cf..8c42abc 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Та нууц үгээ <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Та тайлах хээг <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу орууллаа. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> секундын дараа дахин оролдоно уу."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM-н ПИН кодыг буруу оруулсан тул та төхөөрөмжийнхөө түгжээг тайлахын тулд оператор компанитайгаа холбогдоно уу."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM-н ПИН код буруу байна. Танд <xliff:g id="NUMBER_1">%d</xliff:g> оролдлого үлдлээ.</item>
-      <item quantity="one">SIM-н ПИН код буруу байна, танд мобайл оператортойгоо холбогдохгүйгээр төхөөрөмжийн түгжээг тайлахад <xliff:g id="NUMBER_0">%d</xliff:g> оролдлого хийх боломж үлдсэн байна.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM-н ПИН код буруу байна, танд оператор компанитайгаа холбогдохгүйгээр төхөөрөмжийн түгжээг тайлах # оролдлого үлдлээ.}other{SIM-н ПИН код буруу байна, танд # оролдлого үлдлээ. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-г ашиглах боломжгүй байна. Оператор компанитайгаа холбогдоно уу."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM-н PUK код буруу байна. Таны SIM бүрмөсөн хаагдах хүртэл танд <xliff:g id="NUMBER_1">%d</xliff:g> оролдлого үлдлээ.</item>
-      <item quantity="one">SIM-н PUK код буруу байна. Таны SIM бүрмөсөн хаагдах хүртэл танд <xliff:g id="NUMBER_0">%d</xliff:g> оролдлого үлдлээ.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM-н PUK код буруу байна, таны SIM бүрмөсөн хүчингүй болох хүртэл # оролдлого үлдлээ.}other{SIM-н PUK код буруу байна, таны SIM бүрмөсөн хүчингүй болох хүртэл # оролдлого үлдлээ.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM-н ПИН-г буруу орууллаа!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM-н PUK-г буруу орууллаа!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Оруулах аргыг сэлгэх"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Төхөөрөмжийг гараар түгжсэн"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Таньж чадсангүй"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Царайгаар түгжээ тайлахыг ашиглахын тулд Тохиргоо хэсэгт камерын хандалтыг асаана уу"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM-н ПИН кодыг оруулна уу. Танд <xliff:g id="NUMBER_1">%d</xliff:g> оролдлого үлдлээ.</item>
-      <item quantity="one">SIM-н ПИН кодыг оруулна уу. Танд оператор компанитайгаа холбогдохгүйгээр төхөөрөмжийн түгжээг тайлах <xliff:g id="NUMBER_0">%d</xliff:g> оролдлого үлдлээ.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM-г идэвхгүй болголоо. Үргэлжлүүлэхийн тулд PUK кодыг оруулна уу. Таны SIM бүрмөсөн хүчингүй болох хүртэл <xliff:g id="_NUMBER_1">%d</xliff:g> оролдлого үлдлээ. Дэлгэрэнгүй мэдээлэл авахын тулд оператор компанитайгаа холбогдоно уу.</item>
-      <item quantity="one">SIM-г идэвхгүй болголоо. Үргэлжлүүлэхийн тулд PUK кодыг оруулна уу. Таны SIM бүрмөсөн хүчингүй болох хүртэл <xliff:g id="_NUMBER_0">%d</xliff:g> оролдлого үлдлээ. Дэлгэрэнгүй мэдээлэл авахын тулд оператор компанитайгаа холбогдоно уу.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM-н ПИН-г оруулна уу. Танд оператор компанитайгаа холбогдохгүйгээр төхөөрөмжийн түгжээг тайлах # оролдлого үлдлээ.}other{SIM-н ПИН-г оруулна уу. Танд # оролдлого үлдлээ.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-г идэвхгүй болголоо. Үргэлжлүүлэхийн тулд PUK кодыг оруулна уу. Таны SIM бүрмөсөн хүчингүй болох хүртэл # оролдлого үлдлээ. Дэлгэрэнгүй мэдээлэл авахын тулд оператор компанитайгаа холбогдоно уу.}other{SIM-г идэвхгүй болголоо. Үргэлжлүүлэхийн тулд PUK кодыг оруулна уу. Таны SIM бүрмөсөн хүчингүй болох хүртэл # оролдлого үлдлээ. Дэлгэрэнгүй мэдээлэл авахын тулд оператор компанитайгаа холбогдоно уу.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Өгөгдмөл"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Бөмбөлөг"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Aналог"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 28368f9..2c0bf0f 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"तुम्ही तुमचा पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने काढला. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"सिम पिन कोड चुकीचा आहे तुम्ही आता तुमचे डिव्हाइस अनलॉक करण्‍यासाठी तुमच्या वाहकाशी संपर्क साधावा."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">चुकीचा सिम पिन कोड, तुमच्याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत.</item>
-      <item quantity="one"> चुकीचा सिम पिन कोड, तुमचे डिव्हाइस अनलॉक करण्‍यासाठी तुमच्या वाहकाशी संपर्क साधण्‍यापूर्वी तुमच्याकडे <xliff:g id="NUMBER_0">%d</xliff:g> प्रयत्न शिल्लक आहेत.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{सिमचा पिन कोड चुकीचा आहे, तुम्ही तुमचे डिव्‍हाइस अनलॉक करण्‍यासाठी तुमच्या वाहकाशी संपर्क साधण्‍यापूर्वी तुमच्याकडे # प्रयत्न शिल्लक आहे.}other{सिमचा पिन कोड चुकीचा आहे, तुमच्याकडे # प्रयत्न शिल्लक आहेत. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"सिम निरुपयोगी आहे. आपल्या वाहकाशी संपर्क साधा."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">चुकीचा सिम PUK कोड, सिम कायमचे निरुपयोगी होण्यापूर्वी आपल्याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत.</item>
-      <item quantity="one">चुकीचा सिम PUK कोड, सिम कायमचे निरुपयोगी होण्यापूर्वी आपल्याकडे <xliff:g id="NUMBER_0">%d</xliff:g> प्रयत्न शिल्लक आहे.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{सिमचा PUK कोड चुकीचा आहे, सिम कायमचे निरुपयोगी होण्‍यापूर्वी तुमच्याकडे # प्रयत्न शिल्लक आहे.}other{सिमचा PUK कोड चुकीचा आहे, सिम कायमचे निरुपयोगी होण्‍यापूर्वी तुमच्याकडे # प्रयत्न शिल्लक आहेत.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"सिम पिन ऑपरेशन अयशस्वी झाले!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"सिम PUK कार्य अयशस्‍वी झाले!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"इनपुट पद्धत स्विच करा"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"डिव्हाइस मॅन्युअली लॉक केले होते"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"ओळखले नाही"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"फेस अनलॉक साठी, सेटिंग्ज मध्ये कॅमेराचा अ‍ॅक्सेस द्या"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">सिम पिन एंटर करा, तुमच्याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत.</item>
-      <item quantity="one">सिम पिन एंटर करा. तुम्ही तुमचे डिव्‍हाइस अनलॉक करण्‍यासाठी तुमच्या वाहकाशी संपर्क साधण्‍यापूर्वी, तुमच्याकडे <xliff:g id="NUMBER_0">%d</xliff:g> प्रयत्न शिल्लक आहे.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">सिम आता बंद केलेले आहे. सुरू ठेवण्यासाठी PUK कोड टाका. सिम कायमचे बंद होण्याआधी तुमच्याकडे <xliff:g id="_NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत. तपशीलांसाठी वाहकाशी संपर्क साधा.</item>
-      <item quantity="one">सिम आता बंद केलेले आहे. सुरू ठेवण्यासाठी PUK कोड टाका. सिम कायमचे बंद होण्याआधी तुमच्याकडे <xliff:g id="_NUMBER_0">%d</xliff:g> प्रयत्न शिल्लक आहे. तपशीलांसाठी वाहकाशी संपर्क साधा.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{सिमचा पिन एंटर करा. तुम्ही तुमचे डिव्‍हाइस अनलॉक करण्‍यासाठी तुमच्या वाहकाशी संपर्क साधण्‍यापूर्वी, तुमच्याकडे # प्रयत्न शिल्लक आहे.}other{सिमचा पिन एंटर करा. तुमच्याकडे # शिल्लक प्रयत्न आहेत.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{सिम आता बंद केलेले आहे. पुढे सुरू ठेवण्यासाठी PUK कोड एंटर करा. सिम कायमचे निरुपयोगी होण्यापूर्वी तुमच्याकडे # प्रयत्न शिल्लक आहे. तपशिलांसाठी वाहकाशी संपर्क साधा.}other{सिम आता बंद केलेले आहे. पुढे सुरू ठेवण्यासाठी PUK कोड एंटर करा. सिम कायमचे निरुपयोगी होण्यापूर्वी तुमच्याकडे # प्रयत्न शिल्लक आहेत. तपशिलांसाठी वाहकाशी संपर्क साधा.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"डीफॉल्ट"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"बबल"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"अ‍ॅनालॉग"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index e2efa90..fc18b42 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Anda telah tersilap taip kata laluan sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%2$d</xliff:g> saat."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Kod PIN SIM salah. Anda mesti menghubungi pembawa anda untuk membuka kunci peranti."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Kod PIN SIM salah, tinggal <xliff:g id="NUMBER_1">%d</xliff:g> percubaan.</item>
-      <item quantity="one">Kod PIN SIM salah. Tinggal <xliff:g id="NUMBER_0">%d</xliff:g> percubaan sebelum anda perlu menghubungi pembawa anda untuk membuka kunci peranti.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Kod PIN SIM tidak betul, anda mempunyai # percubaan lagi sebelum perlu menghubungi pembawa anda untuk membuka kunci peranti.}other{Kod PIN SIM tidak betul, anda mempunyai # percubaan lagi. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM tidak boleh digunakan. Hubungi pembawa anda."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Kod PUK SIM salah. Tinggal <xliff:g id="NUMBER_1">%d</xliff:g> percubaan sebelum SIM tidak boleh digunakan secara kekal.</item>
-      <item quantity="one">Kod PUK SIM salah. Tinggal <xliff:g id="NUMBER_0">%d</xliff:g> percubaan sebelum SIM tidak boleh digunakan secara kekal.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Kod PUK SIM tidak betul, anda mempunyai # percubaan lagi sebelum SIM tidak boleh digunakan secara kekal.}other{Kod PUK SIM tidak betul, anda mempunyai # percubaan lagi sebelum SIM tidak boleh digunakan secara kekal.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Pengendalian PIN SIM gagal!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Pengendalian PUK SIM gagal!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Tukar kaedah masukan"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Peranti telah dikunci secara manual"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Tidak dikenali"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Hidupkan kamera dalam Tetapan untuk Buka Kunci Wajah"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Masukkan PIN SIM. Tinggal <xliff:g id="NUMBER_1">%d</xliff:g> percubaan lagi.</item>
-      <item quantity="one">Masukkan PIN SIM. Tinggal <xliff:g id="NUMBER_0">%d</xliff:g> percubaan lagi sebelum anda perlu menghubungi pembawa anda untuk membuka kunci peranti.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Tinggal <xliff:g id="_NUMBER_1">%d</xliff:g> percubaan sebelum SIM tidak boleh digunakan secara kekal. Hubungi pembawa untuk mendapatkan butiran.</item>
-      <item quantity="one">Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Tinggal <xliff:g id="_NUMBER_0">%d</xliff:g> percubaan sebelum SIM tidak boleh digunakan secara kekal. Hubungi pembawa untuk mendapatkan butiran.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Masukkan PIN SIM. Anda mempunyai # percubaan lagi sebelum perlu menghubungi pembawa anda untuk membuka kunci peranti.}other{Masukkan PIN SIM. Anda mempunyai # percubaan lagi.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Anda mempunyai # percubaan lagi sebelum SIM tidak boleh digunakan secara kekal. Hubungi pembawa untuk mendapatkan butiran.}other{Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Anda mempunyai # percubaan lagi sebelum SIM tidak boleh digunakan secara kekal. Hubungi pembawa untuk mendapatkan butiran.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Lalai"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Gelembung"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index fd62450..38d94e4 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"သင်သည် စကားဝှက်ကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ်မှားယွင်းစွာ ထည့်ခဲ့ပါသည်။ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"သင်သည် ပုံစံကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ်မှားယွင်းစွာ ဆွဲခဲ့ပါသည်။ \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ဆင်းမ်ကဒ်ပင်နံပါတ် မှားယွင်းနေသောကြောင့် ယခုအခါ သင့်စက်ပစ္စည်းအား လော့ခ်ဖွင့်ရန် ဝန်ဆောင်မှုပေးသူကို ဆက်သွယ်ရပါမည်။"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">ဆင်းမ်ပင်နံပါတ် မှန်ကန်မှုမရှိပါ။ <xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့်ရှိပါသေးသည်။</item>
-      <item quantity="one">ဆင်းမ်ပင်နံပါတ် မှန်ကန်မှုမရှိပါ။ သင့်စက်ပစ္စည်းအား လော့ခ်ဖွင့်ပေးရန်အတွက် မိုဘိုင်းဝန်ဆောင်မှုပေးသူကို မဆက်သွယ်မီ <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့်ရှိပါသေးသည်။</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{ဆင်းမ်ပင်နံပါတ်ကုဒ် မှားနေသည်။ စက်ကို လော့ခ်ဖွင့်ရန် မိုဘိုင်းဖုန်းကုမ္ပဏီသို့ မဆက်သွယ်မီ သင့်တွင် # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။}other{ဆင်းမ်ပင်နံပါတ်ကုဒ် မှားနေသည်။ သင့်တွင် # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။ }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"ဆင်းမ်ကဒ်ကို အသုံးပြု၍ မရတော့ပါ။ ဝန်ဆောင်မှုပေးသူကို ဆက်သွယ်ပါ။"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">ဆင်းမ် ပင်နံပါတ် ပြန်ဖွင့်သည့်ကုဒ် မှန်ကန်မှုမရှိပါ။ ဆင်းမ်ကဒ်ကို အပြီးအပိုင်မပိတ်ခင် <xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ်စမ်းသပ်ခွင့် ရှိပါသေးသည်။</item>
-      <item quantity="one">ဆင်းမ် ပင်နံပါတ် ပြန်ဖွင့်သည့်ကုဒ် မှန်ကန်မှုမရှိပါ။ ဆင်းမ်ကဒ်ကို အပြီးအပိုင်မပိတ်ခင် <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ်စမ်းသပ်ခွင့် ရှိပါသေးသည်။</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{ဆင်းမ် PUK ကုဒ် မှားနေသည်။ ဆင်းမ် အပြီးပိတ်မသွားမီ သင့်တွင် # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။}other{ဆင်းမ် PUK ကုဒ် မှားနေသည်။ ဆင်းမ် အပြီးပိတ်မသွားမီ သင့်တွင် # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"ဆင်းမ်ကဒ်ပင်နံပါတ် လုပ်ဆောင်ချက် မအောင်မြင်ပါ။"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"ဆင်းမ်ကတ် ပင်နံပါတ် ပြန်ဖွင့်သည့်ကုဒ် လုပ်ဆောင်ချက် မအောင်မြင်ပါ။"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"စာရိုက်စနစ်ပြောင်းရန်"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"စက်ပစ္စည်းကို ကိုယ်တိုင်ကိုယ်ကျ လော့ခ်ချထားခဲ့သည်"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"မသိ"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"‘မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း’ သုံးရန် ‘ဆက်တင်များ’ တွင်ကင်မရာသုံးခွင့်ကိုဖွင့်ပါ"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">ဆင်းမ်ကတ် ပင်နံပါတ် ထည့်ပါ။ <xliff:g id="NUMBER_1">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့်ရှိပါသေးသည်။</item>
-      <item quantity="one">ဆင်းမ်ကတ် ပင်နံပါတ် ထည့်ပါ။ သင့်စက်ကို လော့ခ်ဖွင့်ပေးရန်အတွက် ဝန်ဆောင်မှုပေးသူသို့ မဆက်သွယ်မီ <xliff:g id="NUMBER_0">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့်ရှိပါသေးသည်။</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">ဆင်းမ်ကတ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် PUK ကုဒ်ကို ထည့်ပါ။ ဆင်းမ်ကတ် အပြီးပိတ်မသွားမီ သင့်တွင် <xliff:g id="_NUMBER_1">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့် ကျန်ပါသေးသည်။ အသေးစိတ်အချက်များအတွက် ဝန်ဆောင်မှုပေးသူကို ဆက်သွယ်ပါ။</item>
-      <item quantity="one">ဆင်းမ်ကတ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် PUK ကုဒ်ကို ထည့်ပါ။ ဆင်းမ်ကတ် အပြီးပိတ်မသွားမီ သင့်တွင် <xliff:g id="_NUMBER_0">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့် ကျန်ပါသေးသည်။ အသေးစိတ်အချက်များအတွက် ဝန်ဆောင်မှုပေးသူကို ဆက်သွယ်ပါ။</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{ဆင်းမ်ပင်နံပါတ် ထည့်သွင်းပါ။ သင့်စက်ကို လော့ခ်ဖွင့်ရန် မိုဘိုင်းဖုန်းကုမ္ပဏီသို့ မဆက်သွယ်မီ # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။}other{ဆင်းမ်ပင်နံပါတ် ထည့်သွင်းပါ။ သင့်တွင် # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{ဆင်းမ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် PUK ကုဒ်ကို ထည့်ပါ။ ဆင်းမ် အပြီးပိတ်မသွားမီ သင့်တွင် # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။ အသေးစိတ်အတွက် မိုဘိုင်းဖုန်းကုမ္ပဏီကို ဆက်သွယ်ပါ။}other{ဆင်းမ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် PUK ကုဒ်ကို ထည့်ပါ။ ဆင်းမ် အပြီးပိတ်မသွားမီ သင့်တွင် # ကြိမ် ကြိုးစားခွင့်ရှိသေးသည်။ အသေးစိတ်အတွက် မိုဘိုင်းဖုန်းကုမ္ပဏီကို ဆက်သွယ်ပါ။}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"မူလ"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"ပူဖောင်းကွက်"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ရိုးရိုး"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index 474700c..8730723 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Du har tastet inn passordet ditt feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Du har tegnet opplåsningsmønsteret ditt feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Feil PIN-kode for SIM-kortet. Du må nå kontakte operatøren din for å låse opp enheten."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Feil PIN-kode for SIM-kortet. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøk igjen.</item>
-      <item quantity="one">Feil PIN-kode for SIM-kortet. Du har <xliff:g id="NUMBER_0">%d</xliff:g> forsøk igjen før du må kontakte operatøren din for å låse opp enheten.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Feil PIN-kode for SIM-kortet. Du har # forsøk igjen før du må kontakte operatøren din for å låse opp enheten.}other{Feil PIN-kode for SIM-kortet. Du har # forsøk igjen. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-kortet er ubrukelig. Ta kontakt med operatøren din."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Feil PUK-kode for SIM-kortet. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøk igjen før SIM-kortet blir permanent ubrukelig.</item>
-      <item quantity="one">Feil PUK-kode for SIM-kortet. Du har <xliff:g id="NUMBER_0">%d</xliff:g> forsøk igjen før SIM-kortet blir permanent ubrukelig.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Feil PUK-kode for SIM-kortet. Du har # forsøk igjen før SIM-kortet blir permanent ubrukelig.}other{Feil PUK-kode for SIM-kortet. Du har # forsøk igjen før SIM-kortet blir permanent ubrukelig.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"PIN-koden for SIM-kortet ble avvist."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"PUK-koden for SIM-kortet ble avvist."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Bytt inndatametode"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Enheten ble låst manuelt"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Ikke gjenkjent"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Slå på kameratilgang i Innstillinger for å bruke ansiktslås"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Skriv inn PIN-koden for SIM-kortet. Du har <xliff:g id="NUMBER_1">%d</xliff:g> forsøk igjen.</item>
-      <item quantity="one">Skriv inn PIN-koden for SIM-kortet. Du har <xliff:g id="NUMBER_0">%d</xliff:g> forsøk igjen før du må kontakte operatøren din for å låse opp enheten.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM-kortet er deaktivert nå. Skriv inn PUK-koden for å fortsette. Du har <xliff:g id="_NUMBER_1">%d</xliff:g> forsøk igjen før SIM-kortet blir permanent ubrukelig. Kontakt operatøren for å få vite mer.</item>
-      <item quantity="one">SIM-kortet er deaktivert nå. Skriv inn PUK-koden for å fortsette. Du har <xliff:g id="_NUMBER_0">%d</xliff:g> forsøk igjen før SIM-kortet blir permanent ubrukelig. Kontakt operatøren for å få vite mer.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Skriv inn PIN-koden for SIM-kortet. Du har # forsøk igjen før du må kontakte operatøren din for å låse opp enheten.}other{Skriv inn PIN-koden for SIM-kortet. Du har # forsøk igjen.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-kortet er deaktivert nå. Skriv inn PUK-koden for å fortsette. Du har # forsøk igjen før SIM-kortet blir permanent ubrukelig. Kontakt operatøren for å få vite mer.}other{SIM-kortet er deaktivert nå. Skriv inn PUK-koden for å fortsette. Du har # forsøk igjen før SIM-kortet blir permanent ubrukelig. Kontakt operatøren for å få vite mer.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Standard"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Boble"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index c55aa8f..98e9813 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो गलत पासवर्ड  प्रविष्ट गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले आफ्नो अनलक प्याटर्न कोर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM को PIN कोड गलत छ। तपाईंले अब आफ्नो यन्त्र खोल्न आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नै पर्ने हुन्छ।"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM को PIN कोड गलत छ, तपाईं अझै <xliff:g id="NUMBER_1">%d</xliff:g> पटक प्रयास गर्न सक्नुहुन्छ।</item>
-      <item quantity="one">SIM को PIN कोड गलत छ,तपाईंले आफ्नो डिभाइस अनलक गर्न आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नैपर्ने अवस्था आउनु अघि तपाईं अझै <xliff:g id="NUMBER_0">%d</xliff:g> पटक प्रयास गर्न सक्नुहुन्छ।</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{तपाईंले SIM को गलत PIN कोड हाल्नुभयो, तपाईं अब # पटक PIN हाल्ने प्रयास गर्न सक्नुहुन्छ। त्यसपछि आफ्नो डिभाइस अनलक गर्न तपाईंले आफ्नो सेवा प्रदायकमा सम्पर्क गर्नु पर्ने हुन्छ।}other{तपाईंले SIM को गलत PIN कोड हाल्नुभयो, तपाईं अब # पटक PIN हाल्ने प्रयास गर्न सक्नुहुन्छ। }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM काम नलाग्ने भएको छ। आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM को PUK कोड गलत छ, SIM सदाका लागि काम नलाग्ने हुनु अघि तपाईं अझै <xliff:g id="NUMBER_1">%d</xliff:g> पटक प्रयास गर्न सक्नुहुन्छ।</item>
-      <item quantity="one">SIM को PUK कोड गलत छ, SIM सदाका लागि काम नलाग्ने हुनु अघि तपाईं अझै <xliff:g id="NUMBER_0">%d</xliff:g> पटक प्रयास गर्न सक्नुहुन्छ।</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{तपाईंले SIM को गलत PUK कोड हाल्नुभयो, तपाईं अब # पटक PUK हाल्ने प्रयास गर्न सक्नुहुन्छ। त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुने छ।}other{तपाईंले SIM को गलत PUK कोड हाल्नुभयो, तपाईं अब # पटक PUK हाल्ने प्रयास गर्न सक्नुहुन्छ। त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुने छ।}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM को PIN कोड राखेर अनलक गर्ने कार्य असफल भयो!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM को PUK कोड राखेर अनलक गर्ने कार्य असफल भयो!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"इनपुट विधिलाई स्विच गर्नुहोस्"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"यन्त्रलाई म्यानुअल तरिकाले लक गरिएको थियो"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"पहिचान भएन"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"तपाईं \"फेस अनलक\" प्रयोग गर्न चाहनुहुन्छ भने सेटिङमा गई क्यामेरा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM को PIN प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="NUMBER_1">%d</xliff:g>  प्रयासहरू बाँकी छन्।</item>
-      <item quantity="one">SIM को PIN प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="NUMBER_0">%d</xliff:g> प्रयास बाँकी छ, त्यसपछि भने आफ्नो डिभाइस अनलक गर्नका लागि तपाईंले अनिवार्य रूपमा आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नु पर्ने हुन्छ।</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_1">%d</xliff:g> प्रयासहरू बाँकी छन्, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item>
-      <item quantity="one">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_0">%d</xliff:g> प्रयास बाँकी छ, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM को PIN हाल्नुहोस्। तपाईं अब # पटक PIN हाल्ने प्रयास गर्न सक्नुहुन्छ। त्यसपछि आफ्नो डिभाइस अनलक गर्न तपाईंले आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नु पर्ने हुन्छ।}other{SIM को PIN हाल्नुहोस्। तपाईं अब # पटक PIN हाल्ने प्रयास गर्न सक्नुहुन्छ।}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM अहिले अफ गरिएको छ। जारी राख्न PUK कोड हाल्नुहोस्। तपाईं अब # पटक PUK हाल्ने प्रयास गर्न सक्नुहुन्छ। त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुने छ। थप जानकारी प्राप्त गर्न आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।}other{SIM अहिले अफ गरिएको छ। जारी राख्न PUK कोड हाल्नुहोस्। तपाईं अब # पटक PUK हाल्ने प्रयास गर्न सक्नुहुन्छ। त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुने छ। थप जानकारी प्राप्त गर्न आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"डिफल्ट"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"बबल"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"एनालग"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 18558eb..77bf29c 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Je hebt je wachtwoord <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getypt. \n\nProbeer het over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden opnieuw."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. \n\nProbeer het over <xliff:g id="NUMBER_1">%2$d</xliff:g> seconden opnieuw."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Onjuiste pincode voor simkaart. Je moet nu contact opnemen met je provider om je apparaat te ontgrendelen."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Onjuiste pincode voor simkaart. Je hebt nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over.</item>
-      <item quantity="one">Onjuiste pincode voor simkaart. Je hebt nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat je contact met je provider moet opnemen om je apparaat te ontgrendelen.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Onjuiste pincode voor simkaart. Je hebt nog # poging over voordat je contact met je provider moet opnemen om je apparaat te laten ontgrendelen.}other{Onjuiste pincode voor simkaart. Je hebt nog # pogingen over. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"Simkaart is onbruikbaar. Neem contact op met je provider."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Onjuiste pukcode voor simkaart. Je hebt nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart definitief onbruikbaar wordt.</item>
-      <item quantity="one">Onjuiste pukcode voor simkaart. Je hebt nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat de simkaart definitief onbruikbaar wordt.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Onjuiste pukcode voor simkaart. Je hebt nog # poging over voordat de simkaart definitief onbruikbaar wordt.}other{Onjuiste pukcode voor simkaart. Je hebt nog # pogingen over voordat de simkaart definitief onbruikbaar wordt.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Bewerking met pincode voor simkaart is mislukt."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Bewerking met pukcode voor simkaart is mislukt."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Invoermethode wijzigen"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Apparaat is handmatig vergrendeld"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Niet herkend"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Zet cameratoegang aan in Instellingen om Ontgrendelen via gezichtsherkenning te gebruiken"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Geef de pincode van de simkaart op. Je hebt nog <xliff:g id="NUMBER_1">%d</xliff:g> pogingen over.</item>
-      <item quantity="one">Geef de pincode van de simkaart op. Je hebt nog <xliff:g id="NUMBER_0">%d</xliff:g> poging over voordat je contact met je provider moet opnemen om het apparaat te ontgrendelen.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">De simkaart is nu uitgezet. Geef de pukcode op om door te gaan. Je hebt nog <xliff:g id="_NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.</item>
-      <item quantity="one">De simkaart is nu uitgezet. Geef de pukcode op om door te gaan. Je hebt nog <xliff:g id="_NUMBER_0">%d</xliff:g> poging over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Geef de pincode van de simkaart op. Je hebt nog # poging over voordat je contact met je provider moet opnemen om het apparaat te laten ontgrendelen.}other{Geef de pincode van de simkaart op. Je hebt nog # pogingen.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{De simkaart is nu gedeactiveerd. Geef de pukcode op om door te gaan. Je hebt nog # poging over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.}other{De simkaart is nu gedeactiveerd. Geef de pukcode op om door te gaan. Je hebt nog # pogingen over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Standaard"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bel"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analoog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index a90e256..8765781 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ଆପଣଙ୍କ ପାସ୍‌ୱର୍ଡକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଥର ଭୁଲ ଭାବେ ଟାଇପ୍ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ଆପଣଙ୍କ ଲକ୍‍ ଖୋଲିବା ପାଟର୍ନକୁ ଆପଣ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଅଙ୍କନ କରିଛନ୍ତି। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ଭୁଲ SIM PIN କୋଡ୍‌, ଆପଣଙ୍କ ଡିଭାଇସକୁ ଅନଲକ୍‌ କରିବା ପାଇଁ ଏବେ ହିଁ ନିଜ କେରିଅର୍‌ଙ୍କ ସହ ସମ୍ପର୍କ କରନ୍ତୁ।"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">ଭୁଲ SIM PIN କୋଡ୍, ଆପଣଙ୍କର ଆଉ <xliff:g id="NUMBER_1">%d</xliff:g>ଟି ପ୍ରୟାସ ବାକି ରହିଛି।</item>
-      <item quantity="one">ଭୁଲ SIM PIN କୋଡ୍, ଡିଭାଇସ୍‍ ଅନଲକ୍‍ କରିବା ପାଇଁ କେରିଅରଙ୍କ ସହିତ ଯୋଗାଯୋଗ କରିବା ପୂର୍ବରୁ ଆପଣଙ୍କ ପାଖରେ ଆଉ <xliff:g id="NUMBER_0">%d</xliff:g>ଟି ପ୍ରୟାସ ବାକି ରହିଛି।</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{ଭୁଲ SIM PIN କୋଡ, ଆପଣଙ୍କ ଡିଭାଇସକୁ ଅନଲକ କରିବା ପାଇଁ ଆପଣ ଆପଣଙ୍କର କ୍ୟାରିଅର ସହ ନିଶ୍ଚିତରୂପେ ଯୋଗାଯୋଗ କରିବା ପୂର୍ବରୁ ଆପଣଙ୍କ ପାଖରେ #ଟି ପ୍ରଚେଷ୍ଟା ବାକି ଅଛି।}other{ଭୁଲ SIM PIN କୋଡ, ଆପଣଙ୍କ ପାଖରେ #ଟି ପ୍ରଚେଷ୍ଟା ବାକି ଅଛି। }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM ବ୍ୟବହାର କରାଯାଇପାରିବ ନାହିଁ। ନିଜ କେରିଅର୍‌ଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">ଭୁଲ SIM PUK କୋଡ୍‍, SIMଟି ଆଉ <xliff:g id="NUMBER_1">%d</xliff:g>ଟି ପ୍ରୟାସ ପରେ ସ୍ଥାୟୀ ଭାବେ ବ୍ୟବହାର କରାଯାଇରିବ ନାହିଁ।</item>
-      <item quantity="one">ଭୁଲ SIM PUK କୋଡ୍‍, SIMଟି ଆଉ <xliff:g id="NUMBER_0">%d</xliff:g>ଟି ପ୍ରୟାସ ପରେ ସ୍ଥାୟୀ ଭାବେ ବ୍ୟବହାର କରାଯାଇରିବ ନାହିଁ।</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{ଭୁଲ SIM PUK କୋଡ, SIM ସ୍ଥାୟୀ ଭାବେ ବ୍ୟବହାର ଅଯୋଗ୍ୟ ହେବା ପୂର୍ବରୁ ଆପଣଙ୍କ ପାଖରେ #ଟି ପ୍ରଚେଷ୍ଟା ବାକି ଅଛି।}other{ଭୁଲ SIM PUK କୋଡ, SIM ସ୍ଥାୟୀ ଭାବେ ବ୍ୟବହାର ଅଯୋଗ୍ୟ ହେବା ପୂର୍ବରୁ ଆପଣଙ୍କ ପାଖରେ #ଟି ପ୍ରଚେଷ୍ଟା ବାକି ଅଛି।}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN କାମ ବିଫଳ ହେଲା!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUKର କାମ ବିଫଳ ହେଲା!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ଇନପୁଟ୍‌ ପଦ୍ଧତି ବଦଳାନ୍ତୁ"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"ଡିଭାଇସ୍‍ ମାନୁଆଲ ଭାବେ ଲକ୍‍ କରାଗଲା"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"ଚିହ୍ନଟ ହେଲାନାହିଁ"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"ଫେସ ଅନଲକର ବ୍ୟବହାର ପାଇଁ ସେଟିଂସରେ କ୍ୟାମେରାକୁ ଆକ୍ସେସ ଦିଅ"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM PIN ପ୍ରବେଶ କରନ୍ତୁ। ଆପଣଙ୍କ ପାଇଁ <xliff:g id="NUMBER_1">%d</xliff:g>ଟି ପ୍ରୟାସ ବଳକା ଅଛି।</item>
-      <item quantity="one">SIM PIN ପ୍ରବେଶ କରନ୍ତୁ। ଆପଣଙ୍କ ଡିଭାଇସ୍‍କୁ ଅନଲକ୍ କରିବା ପାଇଁ ପାଖରେ ବଳକା ଥିବା <xliff:g id="NUMBER_0">%d</xliff:g>ଟି ପ୍ରୟାସର ବ୍ୟବହାର କରିବା ପୂର୍ବରୁ ନିଜର କେରିଅର୍‍ଙ୍କୁ ସମ୍ପର୍କ କରନ୍ତୁ।</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM କାର୍ଡକୁ ବର୍ତ୍ତମାନ ଅକ୍ଷମ କରିଦିଆଯାଇଛି। ଜାରି ରଖିବାକୁ PUK କୋଡ୍‍ ଲେଖନ୍ତୁ। ଆଉ <xliff:g id="_NUMBER_1">%d</xliff:g> ଥର ଭୁଲ କୋଡ୍‍ ଲେଖିବା ପରେ SIM କାର୍ଡ ସ୍ଥାୟୀ ଭାବେ ଅନୁପଯୋଗୀ ହୋଇଯିବ। ବିବରଣୀ ପାଇଁ କେରିଅର୍‌ର ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।</item>
-      <item quantity="one">SIM କାର୍ଡକୁ ବର୍ତ୍ତମାନ ଅକ୍ଷମ କରିଦିଆଯାଇଛି। ଜାରି ରଖିବାକୁ PUK କୋଡ୍‍ ଲେଖନ୍ତୁ। ଆଉ <xliff:g id="_NUMBER_0">%d</xliff:g> ଥର ଭୁଲ କୋଡ୍‍ ଲେଖିବା ପରେ SIM କାର୍ଡ ସ୍ଥାୟୀ ଭାବେ ଅନୁପଯୋଗୀ ହୋଇଯିବ। ବିବରଣୀ ପାଇଁ କେରିଅର୍‌ର ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM PIN ଲେଖନ୍ତୁ। ଆପଣଙ୍କ ଡିଭାଇସକୁ ଅନଲକ କରିବା ପାଇଁ ଆପଣ ଆପଣଙ୍କର କ୍ୟାରିଅର ସହ ନିଶ୍ଚିତରୂପେ ଯୋଗାଯୋଗ କରିବା ପୂର୍ବରୁ ଆପଣଙ୍କ ପାଖରେ #ଟି ପ୍ରଚେଷ୍ଟା ବାକି ଅଛି।}other{SIM PIN ଲେଖନ୍ତୁ। ଆପଣଙ୍କର #ଟି ପ୍ରଚେଷ୍ଟା ବାକି ଅଛି।}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIMକୁ ବର୍ତ୍ତମାନ ଅକ୍ଷମ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ PUK କୋଡ ଲେଖନ୍ତୁ। SIM ସ୍ଥାୟୀ ଭାବେ ବ୍ୟବହାର ଅଯୋଗ୍ୟ ହେବା ପୂର୍ବରୁ ଆପଣଙ୍କ ପାଖରେ #ଟି ପ୍ରଚେଷ୍ଟା ବାକି ଅଛି। ବିବରଣୀ ପାଇଁ କ୍ୟାରିଅର ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।}other{SIMକୁ ବର୍ତ୍ତମାନ ଅକ୍ଷମ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ PUK କୋଡ ଲେଖନ୍ତୁ। SIM ସ୍ଥାୟୀ ଭାବେ ବ୍ୟବହାର ଅଯୋଗ୍ୟ ହେବା ପୂର୍ବରୁ ଆପଣଙ୍କ ପାଖରେ #ଟି ପ୍ରଚେଷ୍ଟା ବାକି ଅଛି। ବିବରଣୀ ପାଇଁ କ୍ୟାରିଅର ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ଡିଫଲ୍ଟ"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"ବବଲ୍"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ଆନାଲଗ୍"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 243bbc3..e1c7d26 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਪਾਸਵਰਡ ਗਲਤ ਢੰਗ ਨਾਲ ਟਾਈਪ ਕੀਤਾ ਹੈ।\n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਹੁਣ ਤੁਹਾਨੂੰ ਲਾਜ਼ਮੀ ਤੌਰ \'ਤੇ ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰਨਾ ਚਾਹੀਦਾ ਹੈ।"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
-      <item quantity="other">ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ ਉਸ ਤੋਂ ਬਾਅਦ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਤੁਹਾਨੂੰ ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰਨਾ ਪਵੇਗਾ।}one{ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ। }other{ਗਲਤ ਸਿਮ ਪਿੰਨ ਕੋਡ, ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ। }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM ਨਾ-ਵਰਤਣਯੋਗ ਹੈ। ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">ਗਲਤ ਸਿਮ PUK ਕੋਡ, ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ ਸਿਮ ਸਥਾਈ ਤੌਰ \'ਤੇ ਵਰਤਣਯੋਗ ਨਾ ਰਹੇ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
-      <item quantity="other">ਗਲਤ ਸਿਮ PUK ਕੋਡ, ਇਸਤੋਂ ਪਹਿਲਾਂ ਕਿ ਸਿਮ ਸਥਾਈ ਤੌਰ \'ਤੇ ਵਰਤਣਯੋਗ ਨਾ ਰਹੇ, ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{ਗਲਤ ਸਿਮ PUK ਕੋਡ, ਇਸ ਤੋਂ ਪਹਿਲਾਂ ਕਿ ਸਿਮ ਬਿਲਕੁਲ ਬੇਕਾਰ ਹੋ ਜਾਵੇ, ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।}one{ਗਲਤ ਸਿਮ PUK ਕੋਡ, ਇਸ ਤੋਂ ਪਹਿਲਾਂ ਕਿ ਸਿਮ ਬਿਲਕੁਲ ਬੇਕਾਰ ਹੋ ਜਾਵੇ, ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।}other{ਗਲਤ ਸਿਮ PUK ਕੋਡ, ਇਸ ਤੋਂ ਪਹਿਲਾਂ ਕਿ ਸਿਮ ਬਿਲਕੁਲ ਬੇਕਾਰ ਹੋ ਜਾਵੇ, ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"ਸਿਮ ਪਿੰਨ ਕਾਰਵਾਈ ਅਸਫਲ ਰਹੀ!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK ਕਾਰਵਾਈ ਅਸਫਲ ਰਹੀ!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ਇਨਪੁੱਟ ਵਿਧੀ ਸਵਿੱਚ ਕਰੋ"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"ਡੀਵਾਈਸ ਨੂੰ ਹੱਥੀਂ ਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"ਪਛਾਣ ਨਹੀਂ ਹੋਈ"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"ਫ਼ੇਸ ਅਣਲਾਕ ਵਰਤਣ ਲਈ, ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਕੈਮਰਾ ਪਹੁੰਚ ਚਾਲੂ ਕਰੋ"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ। ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।</item>
-      <item quantity="other">ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ। ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਸਿਮ ਦੇ ਪੱਕੇ ਤੌਰ \'ਤੇ ਬੇਕਾਰ ਹੋ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="_NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।</item>
-      <item quantity="other">ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਸਿਮ ਦੇ ਪੱਕੇ ਤੌਰ \'ਤੇ ਬੇਕਾਰ ਹੋ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="_NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ। ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ, ਉਸ ਤੋਂ ਬਾਅਦ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਤੁਹਾਨੂੰ ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰਨਾ ਪਵੇਗਾ।}one{ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ। ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ।}other{ਸਿਮ ਪਿੰਨ ਦਾਖਲ ਕਰੋ। ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ।}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਇਸ ਤੋਂ ਪਹਿਲਾਂ ਕਿ ਸਿਮ ਬਿਲਕੁਲ ਬੇਕਾਰ ਹੋ ਜਾਵੇ, ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।}one{ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਇਸ ਤੋਂ ਪਹਿਲਾਂ ਕਿ ਸਿਮ ਬਿਲਕੁਲ ਬੇਕਾਰ ਹੋ ਜਾਵੇ, ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।}other{ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਇਸ ਤੋਂ ਪਹਿਲਾਂ ਕਿ ਸਿਮ ਬਿਲਕੁਲ ਬੇਕਾਰ ਹੋ ਜਾਵੇ, ਤੁਹਾਡੇ ਕੋਲ # ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"ਬੁਲਬੁਲਾ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ਐਨਾਲੌਗ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index 5165b10..7cf1784 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -68,19 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> wpisałeś nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Nieprawidłowy kod PIN karty SIM. Musisz teraz skontaktować się z operatorem, by odblokował Twoje urządzenie."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="few">Nieprawidłowy kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> próby.</item>
-      <item quantity="many">Nieprawidłowy kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> prób.</item>
-      <item quantity="other">Nieprawidłowy kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> próby.</item>
-      <item quantity="one">Nieprawidłowy kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER_0">%d</xliff:g> próbę, zanim będziesz musiał skontaktować się z operatorem, by odblokował Twoje urządzenie.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Nieprawidłowy kod PIN karty SIM. Masz jeszcze # próbę, zanim trzeba będzie skontaktować się z operatorem, aby odblokował Twoje urządzenie.}few{Nieprawidłowy kod PIN karty SIM. Masz jeszcze # próby. }many{Nieprawidłowy kod PIN karty SIM. Masz jeszcze # prób. }other{Nieprawidłowy kod PIN karty SIM. Masz jeszcze # próby. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"Karta SIM została trwale zablokowana. Skontaktuj się z operatorem."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="few">Nieprawidłowy kod PUK karty SIM. Masz jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> próby, zanim karta SIM zostanie trwale zablokowana.</item>
-      <item quantity="many">Nieprawidłowy kod PUK karty SIM. Masz jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> prób, zanim karta SIM zostanie trwale zablokowana.</item>
-      <item quantity="other">Nieprawidłowy kod PUK karty SIM. Masz jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> próby, zanim karta SIM zostanie trwale zablokowana.</item>
-      <item quantity="one">Nieprawidłowy kod PUK karty SIM. Masz jeszcze <xliff:g id="NUMBER_0">%d</xliff:g> próbę, zanim karta SIM zostanie trwale zablokowana.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Nieprawidłowy kod PUK karty SIM. Masz jeszcze # próbę, zanim karta SIM zostanie trwale zablokowana.}few{Nieprawidłowy kod PUK karty SIM. Masz jeszcze # próby, zanim karta SIM zostanie trwale zablokowana.}many{Nieprawidłowy kod PUK karty SIM. Masz jeszcze # prób, zanim karta SIM zostanie trwale zablokowana.}other{Nieprawidłowy kod PUK karty SIM. Masz jeszcze # próby, zanim karta SIM zostanie trwale zablokowana.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Operacja z kodem PIN karty SIM nie udała się."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Operacja z kodem PUK karty SIM nie udała się."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Przełączanie metody wprowadzania"</string>
@@ -95,18 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Urządzenie zostało zablokowane ręcznie"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nie rozpoznano"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Aby używać rozpoznawania twarzy, włącz w Ustawieniach dostęp do aparatu"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="few">Wpisz kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> próby.</item>
-      <item quantity="many">Wpisz kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> prób.</item>
-      <item quantity="other">Wpisz kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER_1">%d</xliff:g> próby.</item>
-      <item quantity="one">Wpisz kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER_0">%d</xliff:g> próbę, zanim będzie trzeba skontaktować się z operatorem, by odblokować to urządzenie.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="few">Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Masz jeszcze <xliff:g id="_NUMBER_1">%d</xliff:g> próby, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.</item>
-      <item quantity="many">Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Masz jeszcze <xliff:g id="_NUMBER_1">%d</xliff:g> prób, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.</item>
-      <item quantity="other">Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Masz jeszcze <xliff:g id="_NUMBER_1">%d</xliff:g> próby, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.</item>
-      <item quantity="one">Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Masz jeszcze <xliff:g id="_NUMBER_0">%d</xliff:g> próbę, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Wpisz kod PIN karty SIM. Masz jeszcze # próbę, zanim będzie trzeba skontaktować się z operatorem, aby odblokować to urządzenie.}few{Wpisz kod PIN karty SIM. Masz jeszcze # próby.}many{Wpisz kod PIN karty SIM. Masz jeszcze # prób.}other{Wpisz kod PIN karty SIM. Masz jeszcze # próby.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Karta SIM została wyłączona. Wpisz kod PUK, aby przejść dalej. Masz jeszcze # próbę, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.}few{Karta SIM została wyłączona. Wpisz kod PUK, aby przejść dalej. Masz jeszcze # próby, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.}many{Karta SIM została wyłączona. Wpisz kod PUK, aby przejść dalej. Masz jeszcze # prób, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.}other{Karta SIM została wyłączona. Wpisz kod PUK, aby przejść dalej. Masz jeszcze # próby, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Domyślna"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bąbelkowy"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogowy"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index 04206fd..863a419 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Código PIN do chip incorreto. Entre em contato com a operadora para desbloquear o dispositivo."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Código PIN do chip incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>.</item>
-      <item quantity="other">Código PIN do chip incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Código PIN do chip incorreto. Você tem # tentativa restante. Se o código correto não for digitado, será necessário entrar em contato com a operadora para desbloquear o dispositivo.}one{Código PIN do chip incorreto. Você tem # tentativa restante. }other{Código PIN do chip incorreto. Você tem # tentativas restantes. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"O chip não pode ser utilizado. Entre em contato com a operadora."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Código PUK do chip incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o chip se tornará permanentemente inutilizável.</item>
-      <item quantity="other">Código PUK do chip incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o chip se tornará permanentemente inutilizável.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Código PUK do chip incorreto. Você tem # tentativa restante. Se o código correto não for digitado, o chip vai ficar permanentemente inutilizável.}one{Código PUK do chip incorreto. Você tem # tentativa restante. Se o código correto não for digitado, o chip vai ficar permanentemente inutilizável.}other{Código PUK do chip incorreto. Você tem # tentativas restantes. Se o código correto não for digitado, o chip vai ficar permanentemente inutilizável.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Falha na operação de PIN do chip."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Falha na operação de PUK do chip."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Alterar o método de entrada"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"O dispositivo foi bloqueado manualmente"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Não reconhecido"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Para usar o Desbloqueio facial, ative o acesso à câmera nas Configurações"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Informe o PIN do chip. Você tem <xliff:g id="NUMBER_1">%d</xliff:g> tentativa restante.</item>
-      <item quantity="other">Informe o PIN do chip. Você tem <xliff:g id="NUMBER_1">%d</xliff:g> tentativas restantes.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativa restante antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item>
-      <item quantity="other">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativas restantes antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Informe o PIN do chip. Você tem # tentativa restante antes de precisar entrar em contato com a operadora para desbloquear seu dispositivo.}one{Informe o PIN do chip. Você tem # tentativa restante.}other{Informe o PIN do chip. Você tem # tentativas restantes.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{O chip está desativado. Informe o código PUK para continuar. Você tem # tentativa restante antes que o chip fique permanentemente inutilizável. Consulte sua operadora para saber mais.}one{O chip está desativado. Informe o código PUK para continuar. Você tem # tentativa restante antes que o chip fique permanentemente inutilizável. Consulte sua operadora para saber mais.}other{O chip está desativado. Informe o código PUK para continuar. Você tem # tentativas restantes antes que o chip fique permanentemente inutilizável. Consulte sua operadora para saber mais.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Padrão"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bolha"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analógico"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index abfed2e..6073951c 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Introduziu a palavra-passe incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Desenhou a sua padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Código PIN do cartão SIM incorreto. Tem de contactar o seu operador para desbloquear o dispositivo."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Código PIN do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas.</item>
-      <item quantity="one">Código PIN do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER_0">%d</xliff:g> tentativa antes de precisar de contactar o seu operador para desbloquear o dispositivo.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Código PIN do SIM incorreto. Tem mais # tentativa antes de ser necessário contactar o operador para desbloquear o dispositivo.}other{Código PIN do SIM incorreto. Tem mais # tentativas. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"Cartão SIM inutilizável. Contacte o seu operador."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Código PUK do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar permanentemente inutilizável.</item>
-      <item quantity="one">Código PUK do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER_0">%d</xliff:g> tentativa antes de o cartão SIM ficar permanentemente inutilizável.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Código PUK do SIM incorreto. Tem mais # tentativa antes de o SIM ficar permanentemente inutilizável.}other{Código PUK do SIM incorreto. Tem mais # tentativas antes de o SIM ficar permanentemente inutilizável.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Falha ao introduzir o PIN do cartão SIM!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Falha ao introduzir o PUK do cartão SIM!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Alternar o método de introdução"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"O dispositivo foi bloqueado manualmente"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Não reconhecido."</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Ative acesso à câmara nas Def. p/ usar Desbl. facial"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Introduza o PIN do cartão SIM. Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas.</item>
-      <item quantity="one">Introduza o PIN do cartão SIM. Tem mais <xliff:g id="NUMBER_0">%d</xliff:g> tentativa antes de ser necessário contactar o operador para desbloquear o dispositivo.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">O SIM encontra-se desativado. Introduza o código PUK para continuar. Tem mais <xliff:g id="_NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar permanentemente inutilizável. Contacte o operador para obter mais detalhes.</item>
-      <item quantity="one">O SIM encontra-se desativado. Introduza o código PUK para continuar. Tem mais <xliff:g id="_NUMBER_0">%d</xliff:g> tentativa antes de o cartão SIM ficar permanentemente inutilizável. Contacte o operador para obter mais detalhes.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Introduza o PIN do SIM. Tem mais # tentativa antes de ser necessário contactar o operador para desbloquear o dispositivo.}other{Introduza o PIN do SIM. Tem mais # tentativas.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{O SIM está desativado. Introduza o código PUK para continuar. Tem mais # tentativa antes de o SIM ficar permanentemente inutilizável. Contacte o operador para obter mais detalhes.}other{O SIM está desativado. Introduza o código PUK para continuar. Tem mais # tentativas antes de o SIM ficar permanentemente inutilizável. Contacte o operador para obter mais detalhes.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Predefinido"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Balão"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analógico"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index 04206fd..863a419 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Código PIN do chip incorreto. Entre em contato com a operadora para desbloquear o dispositivo."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Código PIN do chip incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>.</item>
-      <item quantity="other">Código PIN do chip incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Código PIN do chip incorreto. Você tem # tentativa restante. Se o código correto não for digitado, será necessário entrar em contato com a operadora para desbloquear o dispositivo.}one{Código PIN do chip incorreto. Você tem # tentativa restante. }other{Código PIN do chip incorreto. Você tem # tentativas restantes. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"O chip não pode ser utilizado. Entre em contato com a operadora."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Código PUK do chip incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o chip se tornará permanentemente inutilizável.</item>
-      <item quantity="other">Código PUK do chip incorreto. Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o chip se tornará permanentemente inutilizável.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Código PUK do chip incorreto. Você tem # tentativa restante. Se o código correto não for digitado, o chip vai ficar permanentemente inutilizável.}one{Código PUK do chip incorreto. Você tem # tentativa restante. Se o código correto não for digitado, o chip vai ficar permanentemente inutilizável.}other{Código PUK do chip incorreto. Você tem # tentativas restantes. Se o código correto não for digitado, o chip vai ficar permanentemente inutilizável.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Falha na operação de PIN do chip."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Falha na operação de PUK do chip."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Alterar o método de entrada"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"O dispositivo foi bloqueado manualmente"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Não reconhecido"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Para usar o Desbloqueio facial, ative o acesso à câmera nas Configurações"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Informe o PIN do chip. Você tem <xliff:g id="NUMBER_1">%d</xliff:g> tentativa restante.</item>
-      <item quantity="other">Informe o PIN do chip. Você tem <xliff:g id="NUMBER_1">%d</xliff:g> tentativas restantes.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativa restante antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item>
-      <item quantity="other">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativas restantes antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Informe o PIN do chip. Você tem # tentativa restante antes de precisar entrar em contato com a operadora para desbloquear seu dispositivo.}one{Informe o PIN do chip. Você tem # tentativa restante.}other{Informe o PIN do chip. Você tem # tentativas restantes.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{O chip está desativado. Informe o código PUK para continuar. Você tem # tentativa restante antes que o chip fique permanentemente inutilizável. Consulte sua operadora para saber mais.}one{O chip está desativado. Informe o código PUK para continuar. Você tem # tentativa restante antes que o chip fique permanentemente inutilizável. Consulte sua operadora para saber mais.}other{O chip está desativado. Informe o código PUK para continuar. Você tem # tentativas restantes antes que o chip fique permanentemente inutilizável. Consulte sua operadora para saber mais.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Padrão"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bolha"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analógico"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index 884d8d2..5a0dfed 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -68,17 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Ați introdus incorect parola de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> secunde."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Ați desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. \n\nÎncercați din nou peste <xliff:g id="NUMBER_1">%2$d</xliff:g> secunde."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Codul PIN pentru cardul SIM este incorect. Contactați operatorul pentru a vă debloca dispozitivul."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="few">Codul PIN pentru cardul SIM este incorect. V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> încercări.</item>
-      <item quantity="other">Codul PIN pentru cardul SIM este incorect. V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> de încercări.</item>
-      <item quantity="one">Codul PIN pentru cardul SIM este incorect. V-a mai rămas <xliff:g id="NUMBER_0">%d</xliff:g> încercare, după care va trebui să contactați operatorul pentru a vă debloca dispozitivul.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Codul PIN pentru cardul SIM este incorect. V-a mai rămas # încercare, după care va trebui să contactați operatorul pentru a vă debloca dispozitivul.}few{Codul PIN pentru cardul SIM este incorect. V-au mai rămas # încercări. }other{Codul PIN pentru cardul SIM este incorect. V-au mai rămas # de încercări. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"Cardul SIM nu poate fi utilizat. Contactați operatorul."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="few">Codul PUK pentru cardul SIM este incorect. V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> încercări până când cardul SIM va deveni inutilizabil definitiv.</item>
-      <item quantity="other">Codul PUK pentru cardul SIM este incorect. V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> de încercări până când cardul SIM va deveni inutilizabil definitiv.</item>
-      <item quantity="one">Codul PUK pentru cardul SIM este incorect. V-a mai rămas <xliff:g id="NUMBER_0">%d</xliff:g> încercare până când cardul SIM va deveni inutilizabil definitiv.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Codul PUK pentru cardul SIM este incorect. V-a mai rămas # încercare până când cardul SIM va deveni inutilizabil definitiv.}few{Codul PUK pentru cardul SIM este incorect. V-au mai rămas # încercări până când cardul SIM va deveni inutilizabil definitiv.}other{Codul PUK pentru cardul SIM este incorect. V-au mai rămas # de încercări până când cardul SIM va deveni inutilizabil definitiv.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Deblocarea cu ajutorul codului PIN pentru cardul SIM nu a reușit!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Deblocarea cu ajutorul codului PUK pentru cardul SIM nu a reușit!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Comutați metoda de introducere"</string>
@@ -93,16 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Dispozitivul a fost blocat manual"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nu este recunoscut"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Pentru Deblocare facială, activați accesul la cameră"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="few">Introduceți codul PIN pentru cardul SIM. V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> încercări.</item>
-      <item quantity="other">Introduceți codul PIN pentru cardul SIM. V-au mai rămas <xliff:g id="NUMBER_1">%d</xliff:g> de încercări.</item>
-      <item quantity="one">Introduceți codul PIN pentru cardul SIM. V-a mai rămas <xliff:g id="NUMBER_0">%d</xliff:g> încercare, după care va trebui să contactați operatorul pentru a vă debloca dispozitivul.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="few">Cardul SIM este dezactivat acum. Introduceți codul PUK pentru a continua. V-au mai rămas <xliff:g id="_NUMBER_1">%d</xliff:g> încercări până când cardul SIM va deveni inutilizabil definitiv. Contactați operatorul pentru detalii.</item>
-      <item quantity="other">Cardul SIM este dezactivat acum. Introduceți codul PUK pentru a continua. V-au mai rămas <xliff:g id="_NUMBER_1">%d</xliff:g> de încercări până când cardul SIM va deveni inutilizabil definitiv. Contactați operatorul pentru detalii.</item>
-      <item quantity="one">Cardul SIM este dezactivat acum. Introduceți codul PUK pentru a continua. V-a mai rămas <xliff:g id="_NUMBER_0">%d</xliff:g> încercare până când cardul SIM va deveni inutilizabil definitiv. Contactați operatorul pentru detalii.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Introduceți codul PIN pentru cardul SIM. V-a mai rămas # încercare, după care va trebui să contactați operatorul pentru a vă debloca dispozitivul.}few{Introduceți codul PIN al cardului SIM. V-au rămas # încercări.}other{Introduceți codul PIN al cardului SIM. V-au rămas # de încercări.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Cardul SIM este dezactivat acum. Introduceți codul PUK pentru a continua. V-a mai rămas # încercare până când cardul SIM va deveni inutilizabil definitiv. Contactați operatorul pentru detalii.}few{Cardul SIM este dezactivat acum. Introduceți codul PUK pentru a continua. V-au mai rămas # încercări până când cardul SIM va deveni inutilizabil definitiv. Contactați operatorul pentru detalii.}other{Cardul SIM este dezactivat acum. Introduceți codul PUK pentru a continua. V-au mai rămas # de încercări până când cardul SIM va deveni inutilizabil definitiv. Contactați operatorul pentru detalii.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Prestabilit"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Balon"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogic"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index 435a40cf..a21dd6d 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -68,19 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Вы ввели неверный пароль несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>).\n\nПовторите попытку через <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Вы начертили неверный графический ключ несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>).\n\nПовторите попытку через <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Неверный PIN-код. Обратитесь к оператору связи, чтобы разблокировать SIM-карту."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Неверный PIN-код. Осталась <xliff:g id="NUMBER_1">%d</xliff:g> попытка.</item>
-      <item quantity="few">Неверный PIN-код. Осталось <xliff:g id="NUMBER_1">%d</xliff:g> попытки.</item>
-      <item quantity="many">Неверный PIN-код. Осталось <xliff:g id="NUMBER_1">%d</xliff:g> попыток.</item>
-      <item quantity="other">Неверный PIN-код. Осталось <xliff:g id="NUMBER_1">%d</xliff:g> попытки.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Неверный PIN-код. Осталась # попытка. Если ввести неправильный PIN-код ещё раз, SIM-карта будет заблокирована и вам придется обратиться к оператору связи.}one{Неверный PIN-код. Осталась # попытка. }few{Неверный PIN-код. Осталось # попытки. }many{Неверный PIN-код. Осталось # попыток. }other{Неверный PIN-код. Осталось # попытки. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-карта заблокирована навсегда. Обратитесь к оператору связи."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Неверный PUK-код. Осталась <xliff:g id="NUMBER_1">%d</xliff:g> попытка. После этого SIM-карта будет заблокирована навсегда.</item>
-      <item quantity="few">Неверный PUK-код. Осталось <xliff:g id="NUMBER_1">%d</xliff:g> попытки. После этого SIM-карта будет заблокирована навсегда.</item>
-      <item quantity="many">Неверный PUK-код. Осталось <xliff:g id="NUMBER_1">%d</xliff:g> попыток. После этого SIM-карта будет заблокирована навсегда.</item>
-      <item quantity="other">Неверный PUK-код. Осталось <xliff:g id="NUMBER_1">%d</xliff:g> попытки. После этого SIM-карта будет заблокирована навсегда.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Неверный PUK-код. Осталась # попытка. Если ввести неправильный PUK-код ещё раз, SIM-карта будет заблокирована навсегда.}one{Неверный PUK-код. Осталась # попытка. После того как попытки закончатся, SIM-карта будет заблокирована навсегда.}few{Неверный PUK-код. Осталось # попытки. После того как они закончатся, SIM-карта будет заблокирована навсегда.}many{Неверный PUK-код. Осталось # попыток. После того как они закончатся, SIM-карта будет заблокирована навсегда.}other{Неверный PUK-код. Осталось # попытки. После того как попытки закончатся, SIM-карта будет заблокирована навсегда.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Не удалось разблокировать SIM-карту"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Не удалось разблокировать SIM-карту"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Сменить способ ввода"</string>
@@ -95,18 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Устройство было заблокировано вручную"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Не распознано"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"В настройках разрешите фейсконтролю доступ к камере."</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Введите PIN-код. Осталась <xliff:g id="NUMBER_1">%d</xliff:g> попытка.</item>
-      <item quantity="few">Введите PIN-код. Осталось <xliff:g id="NUMBER_1">%d</xliff:g> попытки.</item>
-      <item quantity="many">Введите PIN-код. Осталось <xliff:g id="NUMBER_1">%d</xliff:g> попыток.</item>
-      <item quantity="other">Введите PIN-код. Осталось <xliff:g id="NUMBER_1">%d</xliff:g> попытки.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM-карта отключена. Чтобы продолжить, введите PUK-код. Осталась <xliff:g id="_NUMBER_1">%d</xliff:g> попытка. После этого SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.</item>
-      <item quantity="few">SIM-карта отключена. Чтобы продолжить, введите PUK-код. Осталось <xliff:g id="_NUMBER_1">%d</xliff:g> попытки. После этого SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.</item>
-      <item quantity="many">SIM-карта отключена. Чтобы продолжить, введите PUK-код. Осталось <xliff:g id="_NUMBER_1">%d</xliff:g> попыток. После этого SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.</item>
-      <item quantity="other">SIM-карта отключена. Чтобы продолжить, введите PUK-код. Осталось <xliff:g id="_NUMBER_1">%d</xliff:g> попытки. После этого SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Введите PIN-код. Осталась # попытка. Если указать неверный PIN-код ещё раз, SIM-карта будет заблокирована и вам придется обратиться к оператору связи.}one{Введите PIN-код SIM-карты. Осталась # попытка.}few{Введите PIN-код SIM-карты. Осталось # попытки.}many{Введите PIN-код SIM-карты. Осталось # попыток.}other{Введите PIN-код SIM-карты. Осталось # попытки.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-карта заблокирована. Чтобы продолжить, введите PUK-код. Осталась # попытка. Если ввести неверный PUK-код, SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.}one{SIM-карта заблокирована. Чтобы продолжить, введите PUK-код. Осталась # попытка. После того как попытки закончатся, SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.}few{SIM-карта заблокирована. Чтобы продолжить, введите PUK-код. Осталось # попытки. После того как они закончатся, SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.}many{SIM-карта заблокирована. Чтобы продолжить, введите PUK-код. Осталось # попыток. После того как они закончатся, SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.}other{SIM-карта заблокирована. Чтобы продолжить, введите PUK-код. Осталось # попытки. После того как попытки закончатся, SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"По умолчанию"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Пузырь"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Стрелки"</string>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index ada19dd4..0f828c1 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"ඔබ මුරපදය වාර <xliff:g id="NUMBER_0">%1$d</xliff:g> ක් වැරදියට ටයිප්කොට ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%2$d</xliff:g> කින් නැවත උත්සහ කරන්න."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"ඔබ <xliff:g id="NUMBER_0">%1$d</xliff:g> වාරයක් අගුළු ඇරීමේ රටාව වැරදියට ඇඳ ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%2$d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"වැරදී SIM PIN කේතයකි, ඔබගේ දුරකතනයේ අඟුල හැරීමට ඔබගේ වාහකයා ඔබ දැන් සම්බන්ධ කරගත යුතුය."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">වැරදී SIM PIN කේතයකි, ඔබගේ දුරකථනයේ අඟුල හැරීමට ඔබගේ වාහකයා සම්බන්ධ කරගැනීමට පෙර ඔබ සතුව තවත් උත්සාහයන් <xliff:g id="NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත.</item>
-      <item quantity="other">වැරදී SIM PIN කේතයකි, ඔබගේ දුරකථනයේ අගුල හැරීමට ඔබගේ වාහකයා සම්බන්ධ කරගැනීමට පෙර ඔබ සතුව තවත් උත්සාහයන් <xliff:g id="NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{වැරදි SIM PIN කේතයකි, ඔබේ උපාංගයේ අගුළු හැරීමට ඔබ ඔබේ වාහකයා සම්බන්ධ කර ගත යුතු වීමට පෙර ඔබ සතුව # උත්සාහයක් ඉතිරිව ඇත.}one{වැරදි SIM PIN කේතයකි, ඔබ සතුව උත්සාහයන් #ක් ඉතිරිව ඇත. }other{වැරදි SIM PIN කේතයකි, ඔබ සතුව උත්සාහයන් #ක් ඉතිරිව ඇත. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM කාඩ් පත භාවිතා කළ නොහැක. ඔබගේ වාහකය සම්බන්ධ කරගන්න."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">වැරදි SIM PUK කේතයකි, SIM කාඩ්පත ස්ථිරවම භාවිත කළ නොහැකි බවට පත්වීමට පෙර ඔබට තවත් උත්සාහයන් <xliff:g id="NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත.</item>
-      <item quantity="other">වැරදි SIM PUK කේතයකි, SIM කාඩ්පත ස්ථිරවම භාවිත කළ නොහැකි බවට පත්වීමට පෙර ඔබට තවත් උත්සාහයන් <xliff:g id="NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{වැරදි SIM PUK කේතයකි, SIM කාඩ්පත ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබට # උත්සාහයක් ඉතිරිව ඇත.}one{වැරදි SIM PUK කේතයකි, SIM කාඩ්පත ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබට උත්සාහයන් #ක් ඉතිරිව ඇත.}other{වැරදි SIM PUK කේතයකි, SIM කාඩ්පත ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබට උත්සාහයන් #ක් ඉතිරිව ඇත.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN මෙහෙයුම අසාර්ථක විය!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK මෙහෙයුම අසාර්ථක විය!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ආදාන ක්‍රමය මාරු කිරීම"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"උපාංගය හස්තීයව අගුලු දමන ලදී"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"හඳුනා නොගන්නා ලදී"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"මුහුණෙන් අගුලු හැරීමට, සැකසීම් තුළ කැමරා ප්‍රවේශය සක්‍රීය කරන්න"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">SIM PIN ඇතුළු කරන්න, ඔබ සතුව උත්සාහයන් <xliff:g id="NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත.</item>
-      <item quantity="other">SIM PIN ඇතුළු කරන්න, ඔබ සතුව උත්සාහයන් <xliff:g id="NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM දැන් අබල කර ඇත. දිගටම කරගෙන යාමට PUK කේතය ඇතුළු කරන්න. SIM ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබ සතුව උත්සාහයන් <xliff:g id="_NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත. විස්තර සඳහා වාහක සම්බන්ධ කර ගන්න.</item>
-      <item quantity="other">SIM දැන් අබල කර ඇත. දිගටම කරගෙන යාමට PUK කේතය ඇතුළු කරන්න. SIM ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබ සතුව උත්සාහයන් <xliff:g id="_NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත. විස්තර සඳහා වාහක සම්බන්ධ කර ගන්න.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM PIN ඇතුළු කරන්න, ඔබේ උපාංගය අගුළු හැරීමට ඔබේ වාහකය සම්බන්ධ කර ගැනීමට පෙර ඔබ සතුව # උත්සාහයක් ඉතිරිව ඇත.}one{SIM PIN ඇතුළු කරන්න. ඔබ සතුව උත්සාහයන් #ක් ඉතිරිව ඇත.}other{SIM PIN ඇතුළු කරන්න. ඔබ සතුව උත්සාහයන් #ක් ඉතිරිව ඇත.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM දැන් අබල කර ඇත. ඉදිරියට යාමට PUK කේතය ඇතුළු කරන්න. SIM ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබ සතුව # උත්සාහයක් ඉතිරිව ඇත. විස්තර සඳහා වාහකය සම්බන්ධ කර ගන්න.}one{SIM දැන් අබල කර ඇත. ඉදිරියට යාමට PUK කේතය ඇතුළු කරන්න. SIM ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබ සතුව උත්සාහයන් #ක් ඉතිරිව ඇත. විස්තර සඳහා වාහකය සම්බන්ධ කර ගන්න.}other{SIM දැන් අබල කර ඇත. ඉදිරියට යාමට PUK කේතය ඇතුළු කරන්න. SIM ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබ සතුව උත්සාහයන් #ක් ඉතිරිව ඇත. විස්තර සඳහා වාහකය සම්බන්ධ කර ගන්න.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"පෙරනිමි"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"බුබුළ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ප්‍රතිසමය"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index b1bff53..e98157c 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -68,19 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Už <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste zadali nesprávne heslo. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Už <xliff:g id="NUMBER_0">%1$d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Nesprávny kód PIN SIM karty. Teraz musíte kontaktovať svojho operátora, aby vám odomkol zariadenie."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="few">Nesprávny kód PIN SIM karty. Zostávajú vám <xliff:g id="NUMBER_1">%d</xliff:g> pokusy.</item>
-      <item quantity="many">Nesprávny kód PIN SIM karty. Zostáva vám <xliff:g id="NUMBER_1">%d</xliff:g> pokusu.</item>
-      <item quantity="other">Nesprávny kód PIN SIM karty. Zostáva vám <xliff:g id="NUMBER_1">%d</xliff:g> pokusov.</item>
-      <item quantity="one">Nesprávny kód PIN SIM karty. Zostáva vám <xliff:g id="NUMBER_0">%d</xliff:g> pokus. Potom budete musieť kontaktovať operátora, aby vám odomkol zariadenie.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Nesprávny kód PIN SIM karty. Zostáva vám # pokus, potom budete musieť kontaktovať svojho operátora, aby zariadenie odomkol.}few{Nesprávny kód PIN SIM karty. Zostávajú vám # pokusy. }many{Incorrect SIM PIN code, you have # remaining attempts. }other{Nesprávny kód PIN SIM karty. Zostáva vám # pokusov. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM karta je nepoužiteľná. Kontaktujte svojho operátora."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="few">Nesprávny kód PUK SIM karty. Zostávajú vám <xliff:g id="NUMBER_1">%d</xliff:g> pokusy. Potom sa SIM karta natrvalo zablokuje.</item>
-      <item quantity="many">Nesprávny kód PUK SIM karty. Zostáva vám <xliff:g id="NUMBER_1">%d</xliff:g> pokusu. Potom sa SIM karta natrvalo zablokuje.</item>
-      <item quantity="other">Nesprávny kód PUK SIM karty. Zostáva vám <xliff:g id="NUMBER_1">%d</xliff:g> pokusov. Potom sa SIM karta natrvalo zablokuje.</item>
-      <item quantity="one">Nesprávny kód PUK SIM karty. Zostáva vám <xliff:g id="NUMBER_0">%d</xliff:g> pokus. Potom sa vaša SIM karta natrvalo zablokuje.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Nesprávny kód PUK SIM karty. Zostáva vám # pokus, potom sa SIM karta natrvalo zablokuje.}few{Nesprávny kód PUK SIM karty. Zostávajú vám # pokusy, potom sa SIM karta natrvalo zablokuje.}many{Incorrect SIM PUK code, you have # remaining attempts before SIM becomes permanently unusable.}other{Nesprávny kód PUK SIM karty. Zostáva vám # pokusov, potom sa SIM karta natrvalo zablokuje.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Operácia kódu PIN SIM karty zlyhala!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Operácia kódu PUK SIM karty zlyhala!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Prepnúť metódu vstupu"</string>
@@ -95,18 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Zariadenie bolo uzamknuté ručne"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nerozpoznané"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"V nastaveniach zapnite prístup ku kamere"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="few">Zadajte kód PIN SIM karty. Zostávajú vám <xliff:g id="NUMBER_1">%d</xliff:g> pokusy.</item>
-      <item quantity="many">Enter SIM PIN. You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts.</item>
-      <item quantity="other">Zadajte kód PIN SIM karty. Zostáva vám <xliff:g id="NUMBER_1">%d</xliff:g> pokusov.</item>
-      <item quantity="one">Zadajte kód PIN SIM karty. Zostáva vám <xliff:g id="NUMBER_0">%d</xliff:g> pokus, potom budete musieť kontaktovať svojho operátora, aby zariadenie odomkol.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="few">SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostávajú vám <xliff:g id="_NUMBER_1">%d</xliff:g> pokusy, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.</item>
-      <item quantity="many">SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostáva vám <xliff:g id="_NUMBER_1">%d</xliff:g> pokusu, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.</item>
-      <item quantity="other">SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostáva vám <xliff:g id="_NUMBER_1">%d</xliff:g> pokusov, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.</item>
-      <item quantity="one">SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostáva vám <xliff:g id="_NUMBER_0">%d</xliff:g> pokus, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Zadajte kód PIN SIM karty. Zostáva vám # pokus, potom budete musieť kontaktovať svojho operátora, aby zariadenie odomkol.}few{Zadajte PIN SIM karty. Zostávajú vám # pokusy.}many{Enter SIM PIN. You have # remaining attempts.}other{Zadajte PIN SIM karty. Zostáva vám # pokusov.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostáva vám # pokus, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.}few{SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostávajú vám # pokusy, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.}many{SIM is now disabled. Enter PUK code to continue. You have # remaining attempts before SIM becomes permanently unusable. Contact carrier for details.}other{SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostáva vám # pokusov, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Predvolený"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bublina"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analógový"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index 274a24e..1ad1926 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -68,19 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Geslo ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat vnesli napačno. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat nepravilno narisali. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Napačna koda PIN kartice SIM. Zdaj se boste morali za odklenitev naprave obrniti na operaterja."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Napačna koda PIN kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskus.</item>
-      <item quantity="two">Napačna koda PIN kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskusa.</item>
-      <item quantity="few">Napačna koda PIN kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskuse.</item>
-      <item quantity="other">Napačna koda PIN kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskusov.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Napačna koda PIN kartice SIM. Na voljo imate še # poskus. Nato se boste morali za odklepanje naprave obrniti na operaterja.}one{Napačna koda PIN kartice SIM. Na voljo imate še # poskus. }two{Napačna koda PIN kartice SIM. Na voljo imate še # poskusa. }few{Napačna koda PIN kartice SIM. Na voljo imate še # poskuse. }other{Napačna koda PIN kartice SIM. Na voljo imate še # poskusov. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"Kartica SIM ni več uporabna. Obrnite se na operaterja."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Napačna koda PUK kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskus. Potem bo kartica SIM postala trajno neuporabna.</item>
-      <item quantity="two">Napačna koda PUK kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskusa. Potem bo kartica SIM postala trajno neuporabna.</item>
-      <item quantity="few">Napačna koda PUK kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskuse. Potem bo kartica SIM postala trajno neuporabna.</item>
-      <item quantity="other">Napačna koda PUK kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskusov. Potem bo kartica SIM postala trajno neuporabna.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Napačna koda PUK kartice SIM. Na voljo imate še # poskus. Nato bo kartica SIM postala trajno neuporabna.}one{Napačna koda PUK kartice SIM. Na voljo imate še # poskus. Nato bo kartica SIM postala trajno neuporabna.}two{Napačna koda PUK kartice SIM. Na voljo imate še # poskusa. Nato bo kartica SIM postala trajno neuporabna.}few{Napačna koda PUK kartice SIM. Na voljo imate še # poskuse. Nato bo kartica SIM postala trajno neuporabna.}other{Napačna koda PUK kartice SIM. Na voljo imate še # poskusov. Nato bo kartica SIM postala trajno neuporabna.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Postopek za odklepanje s kodo PIN kartice SIM ni uspel."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Postopek za odklepanje s kodo PUK kartice SIM ni uspel."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Preklop načina vnosa"</string>
@@ -95,18 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Naprava je bila ročno zaklenjena"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Ni prepoznano"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Odklepanje z obrazom potrebuje dostop do fotoaparata."</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Vnesite kodo PIN kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskus.</item>
-      <item quantity="two">Vnesite kodo PIN kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskusa.</item>
-      <item quantity="few">Vnesite kodo PIN kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskuse.</item>
-      <item quantity="other">Vnesite kodo PIN kartice SIM. Na voljo imate še <xliff:g id="NUMBER_1">%d</xliff:g> poskusov.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še <xliff:g id="_NUMBER_1">%d</xliff:g> poskus. Potem bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.</item>
-      <item quantity="two">Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še <xliff:g id="_NUMBER_1">%d</xliff:g> poskusa. Potem bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.</item>
-      <item quantity="few">Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še <xliff:g id="_NUMBER_1">%d</xliff:g> poskuse. Potem bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.</item>
-      <item quantity="other">Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še <xliff:g id="_NUMBER_1">%d</xliff:g> poskusov. Potem bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Vnesite kodo PIN kartice SIM. Na voljo imate še # poskus. Nato se boste morali za odklepanje naprave obrniti na operaterja.}one{Vnesite kodo PIN kartice SIM. Na voljo imate še # poskus.}two{Vnesite kodo PIN kartice SIM. Na voljo imate še # poskusa.}few{Vnesite kodo PIN kartice SIM. Na voljo imate še # poskuse.}other{Vnesite kodo PIN kartice SIM. Na voljo imate še # poskusov.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še # poskus. Nato bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.}one{Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še # poskus. Nato bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.}two{Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še # poskusa. Nato bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.}few{Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še # poskuse. Nato bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.}other{Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še # poskusov. Nato bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Privzeto"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Mehurček"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogno"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index 58773ae..7eb442c 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"E ke shkruar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë gabimisht fjalëkalimin.\n\nProvo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Ke tentuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses për të vizatuar motivin tënd. \n\nProvo sërish për <xliff:g id="NUMBER_1">%2$d</xliff:g> sekonda."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Kodi PIN i kartës SIM është i pasaktë. Tani duhet të kontaktosh me operatorin për ta shkyçur pajisjen tënde."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Kodi PIN i kartës SIM është i pasaktë. Të kanë mbetur edhe <xliff:g id="NUMBER_1">%d</xliff:g> tentativa.</item>
-      <item quantity="one">Kodi PIN i kartës SIM është i pasaktë. Të ka mbetur edhe <xliff:g id="NUMBER_0">%d</xliff:g> tentativë para se të duhet të kontaktosh me operatorin tënd celular për të shkyçur pajisjen.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Kodi PIN i kartës SIM është i pasaktë. Të ka mbetur edhe # përpjekje përpara se të të duhet të kontaktosh me operatorin celular për ta shkyçur pajisjen.}other{Kodi PIN i kartës SIM është i pasaktë. Të kanë mbetur edhe # përpjekje. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"Karta SIM është e papërdorshme. Kontakto me operatorin."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">PUK-u i kartës SIM është i pasaktë. Të kanë mbetur edhe <xliff:g id="NUMBER_1">%d</xliff:g> tentativa para se karta SIM të bëhet e papërdorshme përgjithmonë.</item>
-      <item quantity="one">PUK-u i kartës SIM është i pasaktë. Të ka mbetur edhe <xliff:g id="NUMBER_0">%d</xliff:g> tentativë para se karta SIM të bëhet e papërdorshme përgjithmonë.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Kodi PUK i kartës SIM është i pasaktë. Të ka mbetur edhe # përpjekje përpara se karta SIM të bëhet përgjithmonë e papërdorshme.}other{Kodi PUK i kartës SIM është i pasaktë. Të kanë mbetur edhe # përpjekje përpara se karta SIM të bëhet përgjithmonë e papërdorshme.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Operacioni i kodit PIN të kartës SIM dështoi!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Operacioni i kodit PUK të kartës SIM dështoi!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Ndërro metodën e hyrjes"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Pajisja është kyçur manualisht"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Nuk njihet"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Për \"Shkyçjen me fytyrë\", aktivizo qasjen te kamera te \"Cilësimet\""</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Fut kodin PIN të kartës SIM. Të kanë mbetur edhe <xliff:g id="NUMBER_1">%d</xliff:g> tentativa.</item>
-      <item quantity="one">Fut kodin PIN të kartës SIM. Të ka mbetur edhe <xliff:g id="NUMBER_0">%d</xliff:g> tentativë para se të duhet të kontaktosh me operatorin tënd celular për ta shkyçur pajisjen.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">Karta SIM tani është çaktivizuar. Fut kodin PUK për të vazhduar. Të kanë mbetur edhe <xliff:g id="_NUMBER_1">%d</xliff:g> përpjekje përpara se karta SIM të bëhet përgjithmonë e papërdorshme. Kontakto me operatorin për detaje.</item>
-      <item quantity="one">Karta SIM tani është çaktivizuar. Fut kodin PUK për të vazhduar. Të ka mbetur edhe <xliff:g id="_NUMBER_0">%d</xliff:g> përpjekje përpara se karta SIM të bëhet përgjithmonë e papërdorshme. Kontakto me operatorin për detaje.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Fut kodin PIN të kartës SIM. Të ka mbetur edhe # përpjekje përpara se të të duhet të kontaktosh me operatorin celular për ta shkyçur pajisjen.}other{Fut kodin PIN të kartës SIM. Të kanë mbetur edhe # përpjekje.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Karta SIM është çaktivizuar tani. Fut kodin PUK për të vazhduar. Të ka mbetur edhe # përpjekje përpara se karta SIM të bëhet përgjithmonë e papërdorshme. Kontakto me operatorin celular për detajet.}other{Karta SIM tani është çaktivizuar. Fut kodin PUK për të vazhduar. Të kanë mbetur edhe # përpjekje përpara se karta SIM të bëhet përgjithmonë e papërdorshme. Kontakto me operatorin celular për detajet.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"E parazgjedhur"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Flluskë"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analoge"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index 15c31a0..568be9f 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -68,17 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Унели сте погрешну лозинку <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Нацртали сте нетачан шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. \n\nПробајте поново за <xliff:g id="NUMBER_1">%2$d</xliff:g> сек."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Нетачан PIN кôд за SIM. Сада морате да контактирате мобилног оператера да бисте откључали уређај."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Нетачан PIN кôд за SIM. Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушај.</item>
-      <item quantity="few">Нетачан PIN кôд за SIM. Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушаја.</item>
-      <item quantity="other">Нетачан PIN кôд за SIM. Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушаја.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Нетачан PIN за SIM кôд. Имате још # покушај, а онда морате да се обратите мобилном оператеру да бисте откључали уређај.}one{Нетачан PIN за SIM кôд. Имате још # покушај. }few{Нетачан PIN за SIM кôд. Имате још # покушаја. }other{Нетачан PIN за SIM кôд. Имате још # покушаја. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM картица је неупотребљива. Контактирајте мобилног оператера."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Нетачан PUK кôд за SIM. Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушај пре него што SIM картица постане трајно неупотребљива.</item>
-      <item quantity="few">Нетачан PUK кôд за SIM. Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушаја пре него што SIM картица постане трајно неупотребљива.</item>
-      <item quantity="other">Нетачан PUK кôд за SIM. Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушаја пре него што SIM картица постане трајно неупотребљива.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Нетачан SIM PUK кôд. Имате још # покушај пре него што SIM картица постане трајно неупотребљива.}one{Нетачан PUK кôд за SIM. Имате још # покушај пре него што SIM картица постане трајно неупотребљива.}few{Нетачан PUK кôд за SIM. Имате још # покушаја пре него што SIM картица постане трајно неупотребљива.}other{Нетачан PUK кôд за SIM. Имате још # покушаја пре него што SIM картица постане трајно неупотребљива.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Радња са PIN кодом за SIM није успела!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Радња са PUK кодом за SIM није успела!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Промени метод уноса"</string>
@@ -93,16 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Уређај је ручно закључан"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Није препознат"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Откључавање лицем тражи приступ камери у Подешавањима"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Унесите PIN за SIM. Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушај.</item>
-      <item quantity="few">Унесите PIN за SIM. Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушаја.</item>
-      <item quantity="other">Унесите PIN за SIM. Имате још <xliff:g id="NUMBER_1">%d</xliff:g> покушаја.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још <xliff:g id="_NUMBER_1">%d</xliff:g> покушај пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.</item>
-      <item quantity="few">SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још <xliff:g id="_NUMBER_1">%d</xliff:g> покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.</item>
-      <item quantity="other">SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још <xliff:g id="_NUMBER_1">%d</xliff:g> покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Унесите PIN за SIM. Још # покушај и мораћете да се обратите мобилном оператеру да бисте откључали уређај.}one{Унесите PIN за SIM. Имате још # покушај.}few{Унесите PIN за SIM. Имате још # покушаја.}other{Унесите PIN за SIM. Имате још # покушаја.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушај пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}one{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушај пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}few{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}other{SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још # покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Подразумевани"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Мехурићи"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Аналогни"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index 8f8bdde..e0414c8 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Du angav fel pinkod för SIM-kortet och måste nu kontakta operatören för att låsa upp enheten."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Du angav fel pinkod för SIM-kortet. <xliff:g id="NUMBER_1">%d</xliff:g> försök återstår.</item>
-      <item quantity="one">Du angav fel pinkod för SIM-kortet. <xliff:g id="NUMBER_0">%d</xliff:g> försök återstår innan du måste kontakta operatören för att låsa upp enheten.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Du angav fel pinkod för SIM-kortet. # försök återstår innan du måste kontakta operatören för att låsa upp enheten.}other{Du angav fel pinkod för SIM-kortet. # försök återstår. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-kortet är obrukbart. Kontakta operatören."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Du angav fel PUK-kod för SIM-kortet. <xliff:g id="NUMBER_1">%d</xliff:g> försök återstår innan SIM-kortet blir obrukbart.</item>
-      <item quantity="one">Du angav fel PUK-kod för SIM-kortet. <xliff:g id="NUMBER_0">%d</xliff:g> försök återstår innan SIM-kortet blir obrukbart.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Du angav fel PUK-kod för SIM-kortet. # försök återstår innan SIM-kortet blir obrukbart.}other{Du angav fel PUK-kod för SIM-kortet. # försök återstår innan SIM-kortet blir obrukbart.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Det gick inte att låsa upp med pinkoden för SIM-kortet."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Det gick inte att låsa upp med PUK-koden för SIM-kortet."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Byt inmatningsmetod"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Enheten har låsts manuellt"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Identifierades inte"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"För ansiktslås aktiverar du kameraåtkomst i Inställn."</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Ange pinkod för SIM-kortet. <xliff:g id="NUMBER_1">%d</xliff:g> försök återstår.</item>
-      <item quantity="one">Ange pinkod för SIM-kortet. <xliff:g id="NUMBER_0">%d</xliff:g> försök återstår innan du måste kontakta operatören för att låsa upp enheten.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM-kortet är inaktiverat. Ange PUK-koden om du vill fortsätta. <xliff:g id="_NUMBER_1">%d</xliff:g> försök återstår innan SIM-kortet blir obrukbart. Kontakta operatören för mer information.</item>
-      <item quantity="one">SIM-kortet är inaktiverat. Ange PUK-koden om du vill fortsätta. <xliff:g id="_NUMBER_0">%d</xliff:g> försök återstår innan SIM-kortet blir obrukbart. Kontakta operatören för mer information.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Ange pinkod för SIM-kortet. # försök återstår innan du måste kontakta operatören för att låsa upp enheten.}other{Ange pinkod för SIM-kortet. # försök återstår.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-kortet är inaktiverat. Ange PUK-koden om du vill fortsätta. # försök återstår innan SIM-kortet blir obrukbart. Kontakta operatören för mer information.}other{SIM-kortet är inaktiverat. Ange PUK-koden om du vill fortsätta. # försök återstår innan SIM-kortet blir obrukbart. Kontakta operatören för mer information.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Standard"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bubbla"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index 06d168b..7048364 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Umeandika vibaya nenosiri lako mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Umechora vibaya mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Nambari ya PIN ya SIM si sahihi, sasa lazima uwasiliane na mtoa huduma za mtandao ndipo ufungue kifaa chako."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Nambari ya PIN ya SIM si sahihi. Una nafasi zingine <xliff:g id="NUMBER_1">%d</xliff:g> za kujaribu.</item>
-      <item quantity="one">Nambari ya PIN ya SIM si sahihi. Una nafasi zingine <xliff:g id="NUMBER_0">%d</xliff:g> za kujaribu kabla ulazimike kuwasiliana na mtoa huduma wako ili akufungulie kifaa chako.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Nambari ya PIN ya SIM si sahihi, unaweza kujaribu mara # kabla ya kulazimika kuwasiliana na mtoa huduma wako ili afungue kifaa chako.}other{Nambari ya PIN ya SIM si sahihi, unaweza kujaribu mara #. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM haiwezi kutumika. Wasiliana na mtoa huduma wako."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Nambari ya PUK ya SIM si sahihi, bado unaweza kujaribu mara <xliff:g id="NUMBER_1">%d</xliff:g> kabla ya SIM kuacha kutumika kabisa.</item>
-      <item quantity="one">Nambari ya PUK ya SIM si sahihi, bado unaweza kujaribu mara <xliff:g id="NUMBER_0">%d</xliff:g> kabla ya SIM kuacha kutumika kabisa.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Nambari ya PUK ya SIM si sahihi, unaweza kujaribu mara # kabla ya SIM kuacha kutumika kabisa.}other{Nambari ya PUK ya SIM si sahihi, unaweza kujaribu mara # kabla ya SIM kuacha kutumika kabisa.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Utendakazi wa PIN ya SIM haujafanikiwa!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Utendakazi wa PUK ya SIM haujafanikiwa!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Kubadili mbinu ya kuingiza data"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Umefunga kifaa mwenyewe"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Haitambuliwi"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Ili ufungue kwa Uso, ruhusu kamera ifikiwe"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Weka PIN ya SIM. Zimesalia mara <xliff:g id="NUMBER_1">%d</xliff:g> za kujaribu.</item>
-      <item quantity="one">Weka PIN ya SIM. Ukijaribu tena mara <xliff:g id="NUMBER_0">%d</xliff:g> bila kufaulu, kifaa chako kitafungwa na utalazimika uwasiliane na mtoa huduma wako ili akifungue.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">Sasa SIM imefungwa. Weka msimbo wa PUK ili uendelee. Umesalia na majaribio <xliff:g id="_NUMBER_1">%d</xliff:g> kabla ya SIM kuacha kufanya kazi kabisa. Wasiliana na mtoa huduma kwa maelezo.</item>
-      <item quantity="one">Sasa SIM imefungwa. Weka msimbo wa PUK ili uendelee. Umesalia na jaribio <xliff:g id="_NUMBER_0">%d</xliff:g> kabla ya SIM kuacha kufanya kazi kabisa. Wasiliana na mtoa huduma kwa maelezo.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Weka PIN ya SIM. Unaweza kujaribu mara # kuweka PIN ya SIM kabla ya kulazimika kuwasiliana na mtoa huduma wako ili afungue kifaa chako endapo kitafungwa.}other{Weka PIN ya SIM. Unaweza kujaribu mara #.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Sasa SIM imefungwa. Weka msimbo wa PUK ili uendelee. Unaweza kujaribu mara # kabla ya SIM kuacha kutumika kabisa. Wasiliana na mtoa huduma kwa maelezo.}other{Sasa SIM imefungwa. Weka msimbo wa PUK ili uendelee. Unaweza kujaribu mara # kabla ya SIM kuacha kutumika kabisa. Wasiliana na mtoa huduma kwa maelezo.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Chaguomsingi"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Kiputo"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analogi"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 3531aa3..ca51935 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"உங்கள் கடவுச்சொல்லை <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக உள்ளிட்டுவிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"அன்லாக் பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"சிம்மின் பின் குறியீடு தவறானது. இனி சாதனத்தை அன்லாக் செய்ய, உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்புகொள்ள வேண்டும்."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">சிம்மின் பின் குறியீடு தவறானது, இன்னும் நீங்கள் <xliff:g id="NUMBER_1">%d</xliff:g> முறை முயலலாம்.</item>
-      <item quantity="one">சிம்மின் பின் குறியீடு தவறானது, மேலும் <xliff:g id="NUMBER_0">%d</xliff:g> முயற்சிகளுக்குப் பின்னர், உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்பு கொண்டு மட்டுமே சாதனத்தை அன்லாக் செய்ய முடியும்.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{சிம் பின் குறியீடு தவறானது. உங்கள் சாதனத்தை அன்லாக் செய்ய, உங்கள் மொபைல் நிறுவனத்தைத் தொடர்புகொள்வதற்கு முன்பு மேலும் # முறை முயலலாம்.}other{சிம் பின் குறியீடு தவறானது. இன்னும் # முறை மட்டுமே முயலலாம். }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"பயன்படுத்த முடியாத சிம். உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்புகொள்ளவும்."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">சிம்மின் PUK குறியீடு தவறானது, மேலும் <xliff:g id="NUMBER_1">%d</xliff:g> முறை முயலலாம். தொடர்ந்து தவறான குறியீடு உள்ளிடப்பட்டால், அதன் பிறகு சிம்மை நிரந்தரமாகப் பயன்படுத்த முடியாமல் போகும்.</item>
-      <item quantity="one">சிம்மின் PUK குறியீடு தவறானது, மேலும் <xliff:g id="NUMBER_0">%d</xliff:g> முறை முயலலாம். தொடர்ந்து தவறான குறியீடு உள்ளிடப்பட்டால், அதன் பிறகு சிம்மை நிரந்தரமாகப் பயன்படுத்த முடியாமல் போகும்.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{சிம் PUK குறியீடு தவறானது. சிம் நிரந்தரமாகப் பயன்படுத்த முடியாமல் போவதற்கு முன்பு நீங்கள் # முறை முயலலாம்.}other{சிம் PUK குறியீடு தவறானது. சிம் நிரந்தரமாகப் பயன்படுத்த முடியாமல் போவதற்கு முன்பு நீங்கள் # முறை முயலலாம்.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"சிம் பின் செயல்பாடு தோல்வியடைந்தது!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"சிம் PUK செயல்பாடு தோல்வியடைந்தது!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"உள்ளீட்டு முறையை மாற்றும்"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"பயனர் சாதனத்தைப் பூட்டியுள்ளார்"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"அடையாளங்காணபடவில்லை"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"முகம் காட்டித் திறத்தல் அம்சத்தைப் பயன்படுத்த, அமைப்புகளில் கேமரா அணுகலை இயக்கவும்"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">சிம் பின்னை உள்ளிடவும். மேலும், <xliff:g id="NUMBER_1">%d</xliff:g> வாய்ப்புகள் மீதமுள்ளன.</item>
-      <item quantity="one">சிம் பின்னை உள்ளிடவும். மீதமுள்ள <xliff:g id="NUMBER_0">%d</xliff:g> வாய்ப்பில் தவறுதலான பின் உள்ளிடப்பட்டால், உங்கள் தொலைத்தொடர்பு நிறுவனத்தைத் தொடர்பு கொண்டு மட்டுமே சாதனத்தை அன்லாக் செய்ய முடியும்.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு, PUK குறியீட்டை உள்ளிடவும். நீங்கள் <xliff:g id="_NUMBER_1">%d</xliff:g> முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு, மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.</item>
-      <item quantity="one">சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு, PUK குறியீட்டை உள்ளிடவும். நீங்கள் <xliff:g id="_NUMBER_0">%d</xliff:g> முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு, மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{சிம் பின்னை உள்ளிடவும். உங்கள் சாதனத்தை அன்லாக் செய்ய, உங்கள் மொபைல் நிறுவனத்தைத் தொடர்புகொள்வதற்கு முன்பு மேலும் # முறை முயலலாம்.}other{சிம் பின்னை உள்ளிடவும். இன்னும் # முறை மட்டுமே முயல முடியும்.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{சிம் இப்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு PUK குறியீட்டை உள்ளிடவும். நீங்கள் # முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.}other{சிம் இப்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு PUK குறியீட்டை உள்ளிடவும். நீங்கள் # முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"இயல்பு"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"பபிள்"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"அனலாக்"</string>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 9a9e803..b6ae96d 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"మీరు మీ పాస్‌వర్డ్‌ను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా టైప్ చేశారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"మీరు మీ అన్‌లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM పిన్ కోడ్ తప్పు, ఇప్పుడు మీ డివైజ్‌ను అన్‌లాక్ చేయాలంటే, మీరు తప్పనిసరిగా మీ క్యారియర్‌ను సంప్రదించాలి."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM పిన్ కోడ్ తప్పు, మీకు మరో <xliff:g id="NUMBER_1">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి.</item>
-      <item quantity="one">SIM పిన్ కోడ్ తప్పు, మీకు మరో <xliff:g id="NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది, ఆ తర్వాత మీ డివైజ్‌ను అన్‌లాక్ చేయాలంటే, మీరు తప్పనిసరిగా మీ క్యారియర్‌ని సంప్రదించాలి.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{తప్పు SIM PIN కోడ్, మీరు మీ డివైజ్‌ను అన్‌లాక్ చేయడానికి మీరు తప్పనిసరిగా మీ క్యారియర్‌ను కాంటాక్ట్ చేయడానికి ముందు మీకు # ప్రయత్నం మిగిలి ఉంది.}other{తప్పు SIM PIN కోడ్, మీకు # ప్రయత్నాలు మిగిలి ఉన్నాయి. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM నిరుపయోగకరంగా మారింది. మీ క్యారియర్‌ను సంప్రదించండి."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM PUK కోడ్ తప్పు, మీకు మరో <xliff:g id="NUMBER_1">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి, ఆ తర్వాత SIM శాశ్వతంగా నిరుపయోగకరంగా మారుతుంది.</item>
-      <item quantity="one">SIM PUK కోడ్ తప్పు, మీకు మరో <xliff:g id="NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది, ఆ తర్వాత SIM శాశ్వతంగా నిరుపయోగకరంగా మారుతుంది.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{తప్పు SIM PUK కోడ్, SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు # ప్రయత్నం మిగిలి ఉంది.}other{తప్పు SIM PUK కోడ్, SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు # ప్రయత్నాలు మిగిలి ఉన్నాయి.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM పిన్ చర్య విఫలమైంది!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK చర్య విఫలమైంది!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"ఇన్‌పుట్ పద్ధతిని మార్చు"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"పరికరం మాన్యువల్‌గా లాక్ చేయబడింది"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"గుర్తించలేదు"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"ఫేస్ అన్‌లాక్ వాడేందుకు కెమెరా యాక్సెస్ ఆన్‌లో ఉండాలి"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM పిన్‌ని నమోదు చేయండి. మీకు <xliff:g id="NUMBER_1">%d</xliff:g> ప్రయత్నలు మిగిలి ఉన్నాయి.</item>
-      <item quantity="one">SIM పిన్‌ని నమోదు చేయండి, మీరు మీ పరికరాన్ని అన్‌లాక్ చేయడానికి తప్పనిసరిగా మీ క్యారియర్‌ను సంప్రదించడానికి ముందు మీకు <xliff:g id="NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM ఇప్పుడు నిలిపివేయబడింది. PUK కోడ్‌ను నమోదు చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="_NUMBER_1">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి. వివరాల కోసం కారియర్‌ను సంప్రదించండి.</item>
-      <item quantity="one">SIM ఇప్పుడు నిలిపివేయబడింది. PUK కోడ్‌ను నమోదు చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="_NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది వివరాల కోసం కారియర్‌ను సంప్రదించండి.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM PINను ఎంటర్ చేయండి. మీరు మీ పరికరాన్ని అన్‌లాక్ చేయడానికి మీరు తప్పనిసరిగా మీ క్యారియర్‌ను కాంటాక్ట్ చేయడానికి ముందు మీకు # ప్రయత్నం మిగిలి ఉంది.}other{SIM PINను ఎంటర్ చేయండి. మీకు # ప్రయత్నాలు మిగిలి ఉన్నాయి.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM ఇప్పుడు డిజేబుల్ చేయబడింది. కొనసాగించడానికి PUK కోడ్‌ను ఎంటర్ చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు # ప్రయత్నం మిగిలి ఉంది. వివరాల కోసం క్యారియర్‌ను కాంటాక్ట్ చేయండి.}other{SIM ఇప్పుడు డిజేబుల్ చేయబడింది. కొనసాగించడానికి PUK కోడ్‌ను ఎంటర్ చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు # ప్రయత్నాలు మిగిలి ఉన్నాయి. వివరాల కోసం క్యారియర్‌ను కాంటాక్ట్ చేయండి.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ఆటోమేటిక్"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"బబుల్"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"ఎనలాగ్"</string>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index 6992054..00092bb 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"คุณพิมพ์รหัสผ่านไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%2$d</xliff:g> วินาที"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> วินาที"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"รหัส PIN ของซิมไม่ถูกต้อง ตอนนี้คุณต้องติดต่อผู้ให้บริการเพื่อปลดล็อกอุปกรณ์ของคุณ"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">รหัส PIN ของซิมไม่ถูกต้อง คุณพยายามได้อีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง</item>
-      <item quantity="one">รหัส PIN ของซิมไม่ถูกต้อง คุณพยายามได้อีก <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งก่อนที่จะต้องติดต่อผู้ให้บริการเพื่อปลดล็อกอุปกรณ์ของคุณ</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{รหัส PIN ของซิมไม่ถูกต้อง คุณพยายามได้อีก # ครั้งก่อนที่จะต้องติดต่อผู้ให้บริการเพื่อปลดล็อกอุปกรณ์}other{รหัส PIN ของซิมไม่ถูกต้อง คุณพยายามได้อีก # ครั้ง }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"ซิมไม่สามารถใช้งานได้ โปรดติดต่อผู้ให้บริการ"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">รหัส PUK ของซิมไม่ถูกต้อง คุณพยายามได้อีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้งก่อนที่ซิมจะไม่สามารถใช้งานได้อย่างถาวร</item>
-      <item quantity="one">รหัส PUK ของซิมไม่ถูกต้อง คุณพยายามได้อีก <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งก่อนที่ซิมจะไม่สามารถใช้งานได้อย่างถาวร</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{รหัส PUK ของซิมไม่ถูกต้อง คุณพยายามได้อีก # ครั้งก่อนที่ซิมจะใช้งานไม่ได้อย่างถาวร}other{รหัส PUK ของซิมไม่ถูกต้อง คุณพยายามได้อีก # ครั้งก่อนที่ซิมจะใช้งานไม่ได้อย่างถาวร}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"การปลดล็อกด้วย PIN ของซิมล้มเหลว!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"การปลดล็อกด้วย PUK ของซิมล้มเหลว!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"สลับวิธีการป้อนข้อมูล"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"มีการล็อกอุปกรณ์ด้วยตัวเอง"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"ไม่รู้จัก"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"เปิดการเข้าถึงกล้องในการตั้งค่าเพื่อใช้การปลดล็อกด้วยใบหน้า"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">โปรดป้อน PIN ของซิม คุณพยายามได้อีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง</item>
-      <item quantity="one">โปรดป้อน PIN ของซิม คุณพยายามได้อีก <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งก่อนที่จะต้องติดต่อผู้ให้บริการเพื่อปลดล็อกอุปกรณ์</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">ซิมถูกปิดใช้งานในขณะนี้ โปรดป้อนรหัส PUK เพื่อทำต่อ คุณพยายามได้อีก <xliff:g id="_NUMBER_1">%d</xliff:g> ครั้งก่อนที่ซิมจะไม่สามารถใช้งานได้อย่างถาวร โปรดติดต่อสอบถามรายละเอียดจากผู้ให้บริการ</item>
-      <item quantity="one">ซิมถูกปิดใช้งานในขณะนี้ โปรดป้อนรหัส PUK เพื่อทำต่อ คุณพยายามได้อีก <xliff:g id="_NUMBER_0">%d</xliff:g> ครั้งก่อนที่ซิมจะไม่สามารถใช้งานได้อย่างถาวร โปรดติดต่อสอบถามรายละเอียดจากผู้ให้บริการ</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{ป้อน PIN ของซิม คุณพยายามได้อีก # ครั้งก่อนที่จะต้องติดต่อผู้ให้บริการเพื่อปลดล็อกอุปกรณ์}other{ป้อน PIN ของซิม คุณลองได้อีก # ครั้ง}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{ตอนนี้ซิมถูกปิดใช้แล้ว ป้อนรหัส PUK เพื่อดำเนินการต่อ คุณพยายามได้อีก # ครั้งก่อนที่ซิมจะใช้งานไม่ได้อย่างถาวร โปรดติดต่อสอบถามรายละเอียดจากผู้ให้บริการ}other{ตอนนี้ซิมถูกปิดใช้แล้ว ป้อนรหัส PUK เพื่อดำเนินการต่อ คุณพยายามได้อีก # ครั้งก่อนที่ซิมจะใช้งานไม่ได้อย่างถาวร โปรดติดต่อสอบถามรายละเอียดจากผู้ให้บริการ}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ค่าเริ่มต้น"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"บับเบิล"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"แอนะล็อก"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index 12b7635..7b07251 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Na-type mo nang hindi tama ang iyong password nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%2$d</xliff:g> (na) segundo."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Mali ang PIN code ng SIM, dapat ka nang makipag-ugnayan sa iyong carrier upang i-unlock ang iyong device."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Mali ang PIN code ng SIM, mayroon kang <xliff:g id="NUMBER_1">%d</xliff:g> natitirang pagsubok.</item>
-      <item quantity="other">Mali ang PIN code ng SIM, mayroon kang <xliff:g id="NUMBER_1">%d</xliff:g> na natitirang pagsubok.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Mali ang PIN code ng SIM, mayroon kang # natitirang pagsubok bago mo kailanganing makipag-ugnayan sa iyong carrier para ma-unlock ang device mo.}one{Mali ang PIN code ng SIM, mayroon kang # natitirang pagsubok. }other{Mali ang PIN code ng SIM, mayroon kang # na natitirang pagsubok. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"Hindi magagamit ang SIM. Makipag-ugnayan sa iyong carrier."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Mali ang PUK code ng SIM, mayroon kang <xliff:g id="NUMBER_1">%d</xliff:g> natitirang pagsubok bago tuluyang hindi magamit ang SIM.</item>
-      <item quantity="other">Mali ang PUK code ng SIM, mayroon kang <xliff:g id="NUMBER_1">%d</xliff:g> na natitirang pagsubok bago tuluyang hindi magamit ang SIM.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Mali ang PUK code ng SIM, mayroon kang # natitirang pagsubok bago tuluyang hindi magamit ang SIM.}one{Mali ang PUK code ng SIM, mayroon kang # natitirang pagsubok bago tuluyang hindi magamit ang SIM.}other{Mali ang PUK code ng SIM, mayroon kang # na natitirang pagsubok bago tuluyang hindi magamit ang SIM.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Nabigo ang operasyon ng PIN ng SIM!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Nabigo ang operasyon ng PUK ng SIM!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Magpalit ng pamamaraan ng pag-input"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Manual na na-lock ang device"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Hindi nakilala"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Para sa Pag-unlock Gamit ang Mukha, i-on ang access ng camera sa Mga Setting"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Ilagay ang PIN ng SIM. Mayroon kang <xliff:g id="NUMBER_1">%d</xliff:g> natitirang pagsubok.</item>
-      <item quantity="other">Ilagay ang PIN ng SIM. Mayroon kang <xliff:g id="NUMBER_1">%d</xliff:g> na natitirang pagsubok.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">Naka-disable na ang SIM. Ilagay ang PUK code upang magpatuloy. Mayroon kang <xliff:g id="_NUMBER_1">%d</xliff:g> natitirang pagsubok bago tuluyang hindi magamit ang SIM. Makipag-ugnayan sa carrier para sa mga detalye.</item>
-      <item quantity="other">Naka-disable na ang SIM. Ilagay ang PUK code upang magpatuloy. Mayroon kang <xliff:g id="_NUMBER_1">%d</xliff:g> na natitirang pagsubok bago tuluyang hindi magamit ang SIM. Makipag-ugnayan sa carrier para sa mga detalye.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Ilagay ang PIN ng SIM. Mayroon kang # natitirang pagsubok bago mo kailanganing makipag-ugnayan sa iyong carrier para ma-unlock ang device mo.}one{Ilagay ang PIN ng SIM. Mayroon kang # natitirang pagsubok.}other{Ilagay ang PIN ng SIM. Mayroon kang # na natitirang pagsubok.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Na-disable na ang SIM. Ilagay ang PUK code para magpatuloy. Mayroon kang # natitirang pagsubok bago tuluyang hindi magamit ang SIM. Makipag-ugnayan sa carrier para sa mga detalye.}one{Na-disable na ang SIM. Ilagay ang PUK code para magpatuloy. Mayroon kang # natitirang pagsubok bago tuluyang hindi magamit ang SIM. Makipag-ugnayan sa carrier para sa mga detalye.}other{Na-disable na ang SIM. Ilagay ang PUK code para magpatuloy. Mayroon kang # na natitirang pagsubok bago tuluyang hindi magamit ang SIM. Makipag-ugnayan sa carrier para sa mga detalye.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Default"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index fb08042..7ec5642 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Şifrenizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış yazdınız. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> saniye içinde tekrar deneyin."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Yanlış SIM PIN kodu. Cihazınızın kilidini açmak için artık operatörünüzle bağlantı kurmanız gerekiyor."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Yanlış SIM PIN kodu, <xliff:g id="NUMBER_1">%d</xliff:g> deneme hakkınız kaldı.</item>
-      <item quantity="one">Yanlış SIM PIN kodu. Cihazının kilidini açmak için operatörünüzle bağlantı kurmak zorunda kalmadan önce <xliff:g id="NUMBER_0">%d</xliff:g> deneme hakkınız kaldı.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Yanlış SIM PIN kodu. Cihazınızın kilidini açması için operatörünüzle bağlantı kurmak zorunda kalmadan önce # deneme hakkınız kaldı.}other{Yanlış SIM PIN kodu. # deneme hakkınız kaldı. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM kullanılamaz. Operatörünüzle bağlantı kurun."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Yanlış SIM PUK kodu, SIM kalıcı olarak kullanılmaz hale gelmeden önce <xliff:g id="NUMBER_1">%d</xliff:g> deneme hakkınız kaldı.</item>
-      <item quantity="one">Yanlış SIM PUK kodu. SIM kalıcı olarak kullanılmaz hale gelmeden önce <xliff:g id="NUMBER_0">%d</xliff:g> deneme hakkınız kaldı.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Yanlış SIM PUK kodu. SIM kalıcı olarak kullanılmaz hale gelmeden önce # deneme hakkınız kaldı.}other{Yanlış SIM PUK kodu. SIM kalıcı olarak kullanılmaz hale gelmeden önce # deneme hakkınız kaldı.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM PIN işlemi başarısız oldu!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM PUK işlemi başarısız oldu!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Giriş yöntemini değiştir"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Cihazın manuel olarak kilitlendi"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Tanınmadı"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Yüz Tanıma Kilidi için Ayarlar\'da kamera erişimini açın"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM PIN\'inizi girin. <xliff:g id="NUMBER_1">%d</xliff:g> deneme hakkınız kaldı.</item>
-      <item quantity="one">SIM PIN\'inizi girin. Cihazınızın kilidini açmak için operatörünüzle bağlantı kurmak zorunda kalmadan önce <xliff:g id="NUMBER_0">%d</xliff:g> deneme hakkınız kaldı.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM artık devre dışı. Devam etmek için PUK kodunu girin. SIM kalıcı olarak kullanım dışı kalmadan önce <xliff:g id="_NUMBER_1">%d</xliff:g> deneme hakkınız kaldı. Ayrıntılı bilgi için operatörünüzle iletişim kurun.</item>
-      <item quantity="one">SIM artık devre dışı. Devam etmek için PUK kodunu girin. SIM kalıcı olarak kullanım dışı kalmadan önce <xliff:g id="_NUMBER_0">%d</xliff:g> deneme hakkınız kaldı. Ayrıntılı bilgi için operatörünüzle iletişim kurun.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM PIN\'inizi girin. Cihazınızın kilidini açmak için operatörünüzle bağlantı kurmak zorunda kalmadan önce # deneme hakkınız kaldı.}other{SIM PIN kodunu girin. # deneme hakkınız kaldı.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM artık devre dışı. Devam etmek için PUK kodunu girin. SIM kalıcı olarak kullanım dışı kalmadan önce # deneme hakkınız kaldı. Ayrıntılı bilgi için operatörünüzle iletişim kurun.}other{SIM artık devre dışı. Devam etmek için PUK kodunu girin. SIM kalıcı olarak kullanım dışı kalmadan önce # deneme hakkınız kaldı. Ayrıntılı bilgi için operatörünüzle iletişim kurun.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Varsayılan"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Baloncuk"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index 2aa4efc..096adb7f 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -68,19 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Пароль неправильно введено стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%2$d</xliff:g> с."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%2$d</xliff:g> с."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Неправильний PIN-код SIM-карти. Зв’яжіться зі своїм оператором, щоб розблокувати пристрій."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Неправильний PIN-код SIM-карти. У вас залишилася <xliff:g id="NUMBER_1">%d</xliff:g> спроба.</item>
-      <item quantity="few">Неправильний PIN-код SIM-карти. У вас залишилося <xliff:g id="NUMBER_1">%d</xliff:g> спроби.</item>
-      <item quantity="many">Неправильний PIN-код SIM-карти. У вас залишилося <xliff:g id="NUMBER_1">%d</xliff:g> спроб.</item>
-      <item quantity="other">Неправильний PIN-код SIM-карти. У вас залишилося <xliff:g id="NUMBER_1">%d</xliff:g> спроби.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Неправильний PIN-код SIM-карти. У вас залишилась # спроба. Після цього, щоб розблокувати пристрій, потрібно буде зв’язатися з оператором.}one{Неправильний PIN-код SIM-карти. У вас залишилася # спроба. }few{Неправильний PIN-код SIM-карти. У вас залишилося # спроби. }many{Неправильний PIN-код SIM-карти. У вас залишилося # спроб. }other{Неправильний PIN-код SIM-карти. У вас залишилося # спроби. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM-карту заблоковано. Зв’яжіться з оператором."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Неправильний PUK-код SIM-карти. У вас залишилася <xliff:g id="NUMBER_1">%d</xliff:g> спроба. Після цього SIM-карту буде назавжди заблоковано.</item>
-      <item quantity="few">Неправильний PUK-код SIM-карти. У вас залишилося <xliff:g id="NUMBER_1">%d</xliff:g> спроби. Після цього SIM-карту буде назавжди заблоковано.</item>
-      <item quantity="many">Неправильний PUK-код SIM-карти. У вас залишилося <xliff:g id="NUMBER_1">%d</xliff:g> спроб. Після цього SIM-карту буде назавжди заблоковано.</item>
-      <item quantity="other">Неправильний PUK-код SIM-карти. У вас залишилося <xliff:g id="NUMBER_1">%d</xliff:g> спроби. Після цього SIM-карту буде назавжди заблоковано.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Неправильний PUK-код SIM-карти. У вас залишилась # спроба. Після цього SIM-карту буде назавжди заблоковано.}one{Неправильний PUK-код SIM-карти. У вас залишилася # спроба. Після цього SIM-карту буде назавжди заблоковано.}few{Неправильний PUK-код SIM-карти. У вас залишилося # спроби. Після цього SIM-карту буде назавжди заблоковано.}many{Неправильний PUK-код SIM-карти. У вас залишилося # спроб. Після цього SIM-карту буде назавжди заблоковано.}other{Неправильний PUK-код SIM-карти. У вас залишилося # спроби. Після цього SIM-карту буде назавжди заблоковано.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Помилка введення PIN-коду SIM-карти."</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Помилка введення PUK-коду SIM-карти."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Змінити метод введення"</string>
@@ -95,18 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Пристрій заблоковано вручну"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Не розпізнано"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Для фейсконтролю надайте доступ до камери"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Введіть PIN-код SIM-карти. Залишилася <xliff:g id="NUMBER_1">%d</xliff:g> спроба.</item>
-      <item quantity="few">Введіть PIN-код SIM-карти. Залишилося <xliff:g id="NUMBER_1">%d</xliff:g> спроби.</item>
-      <item quantity="many">Введіть PIN-код SIM-карти. Залишилося <xliff:g id="NUMBER_1">%d</xliff:g> спроб.</item>
-      <item quantity="other">Введіть PIN-код SIM-карти. Залишилося <xliff:g id="NUMBER_1">%d</xliff:g> спроби.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. Залишилася <xliff:g id="_NUMBER_1">%d</xliff:g> спроба. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.</item>
-      <item quantity="few">SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. Залишилося <xliff:g id="_NUMBER_1">%d</xliff:g> спроби. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.</item>
-      <item quantity="many">SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. Залишилося <xliff:g id="_NUMBER_1">%d</xliff:g> спроб. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.</item>
-      <item quantity="other">SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. Залишилося <xliff:g id="_NUMBER_1">%d</xliff:g> спроби. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Введіть PIN-код SIM-карти. У вас залишилась # спроба. Після цього, щоб розблокувати пристрій, потрібно буде зв’язатися з оператором.}one{Введіть PIN-код SIM-карти. У вас залишилася # спроба.}few{Введіть PIN-код SIM-карти. У вас залишилося # спроби.}many{Введіть PIN-код SIM-карти. У вас залишилося # спроб.}other{Введіть PIN-код SIM-карти. У вас залишилося # спроби.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. У вас залишилась # спроба. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.}one{SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. У вас залишилася # спроба. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.}few{SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. У вас залишилося # спроби. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.}many{SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. У вас залишилося # спроб. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.}other{SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. У вас залишилося # спроби. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"За умовчанням"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Бульбашковий"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Аналоговий"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index dafa2f6..c30dbfc 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"آپ نے اپنا پاس ورڈ <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ٹائپ کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"‏غلط SIM PIN کوڈ، اب آپ کو اپنا آلہ غیر مقفل کرنے کیلئے اپنے کیریئر سے رابطہ کرنا ہوگا۔"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">‏غلط SIM PIN کوڈ، آپ کے پاس <xliff:g id="NUMBER_1">%d</xliff:g> کوششیں بچی ہیں۔</item>
-      <item quantity="one">‏غلط SIM PIN کوڈ، آپ کے پاس <xliff:g id="NUMBER_0">%d</xliff:g> کوشش بچی ہے، اس کے بعد آپ کو اپنا آلہ غیر مقفل کرنے کیلئے اپنے کیریئر سے رابطہ کرنا ہوگا۔</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{‏SIM کا غلط PIN کوڈ، اس سے پہلے کہ آپ اپنا آلہ غیر مقفل کرنے کیلئے لازمی طور پر اپنے کیریئر سے رابطہ کریں آپ کے پاس # کوشش بچی ہے۔}other{‏SIM کا غلط PIN کوڈ، آپ کے پاس # کوششیں بچی ہیں۔ }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"‏SIM ناقابل استعمال ہے۔ اپنے کیریئر سے رابطہ کریں۔"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">‏غلط SIM PUK کوڈ، آپ کے پاس <xliff:g id="NUMBER_1">%d</xliff:g> کوششیں بچی ہیں، اس کے بعد SIM مستقل طور پر ناقابل استعمال ہو جائے گا۔</item>
-      <item quantity="one">‏غلط SIM PUK کوڈ، آپ کے پاس <xliff:g id="NUMBER_0">%d</xliff:g> کوشش بچی ہے، اس کے بعد SIM مستقل طور پر ناقابل استعمال ہو جائے گا۔</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{‏SIM کا غلط PUK کوڈ، SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس # کوشش بچی ہے۔}other{‏SIM کا غلط PUK کوڈ، SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس # کوششیں بچی ہیں۔}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"‏SIM PIN کی کارروائی ناکام ہوگئی!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"‏SIM PUK کارروائی ناکام ہو گئی!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"اندراج کا طریقہ سوئچ کریں"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"آلہ کو دستی طور پر مقفل کیا گیا تھا"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"تسلیم شدہ نہیں ہے"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"فیس اَنلاک استعمال کرنے کیلئے، ترتیبات میں کیمرا تک رسائی کو آن کریں"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">‏SIM کا PIN درج کریں، آپ کے پاس <xliff:g id="NUMBER_1">%d</xliff:g> کوششیں بچی ہیں۔</item>
-      <item quantity="one">‏SIM کا PIN درج کریں، آپ کے پاس <xliff:g id="NUMBER_0">%d</xliff:g> کوشش بچی ہے، اس کے بعد آپ کو اپنا آلہ غیر مقفل کرنے کے لیے اپنے کیریئر سے رابطہ کرنا ہوگا۔</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">‏SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس <xliff:g id="_NUMBER_1">%d</xliff:g> کوششیں بچی ہیں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔</item>
-      <item quantity="one">‏SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس <xliff:g id="_NUMBER_0">%d</xliff:g> کوشش بچی ہے۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{‏SIM کا PIN درج کریں۔ اس سے پہلے کہ آپ اپنا آلہ غیر مقفل کرنے کیلئے لازمی طور پر اپنے کیریئر سے رابطہ کریں آپ کے پاس # کوشش بچی ہے۔}other{‏SIM کا PIN درج کریں۔ آپ کے پاس # کوششیں بچی ہیں۔}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{‏SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس # کوشش بچی ہے۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔}other{‏SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس # کوششیں بچی ہیں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"ڈیفالٹ"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"بلبلہ"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"اینالاگ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index df537ab6..dedf432 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Parol <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato kiritildi. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan keyin qaytadan urining."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Grafik kalit <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato kiritildi. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> soniyadan keyin qayta urining."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM kartaning PIN kodi xato. Qurilma qulfini ochish uchun operatoringizga murojaat qiling."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM kartaning PIN kodi noto‘g‘ri. Sizda yana <xliff:g id="NUMBER_1">%d</xliff:g> ta urinish qoldi.</item>
-      <item quantity="one">SIM karta PIN kodi noto‘g‘ri terildi, yana <xliff:g id="NUMBER_0">%d</xliff:g> marta uirinib ko‘rishingiz mumkin, urinishlar tugagandan keyin qurilmangizni qulfdan chiqarish uchun aloqa operatoringiz bilan bog‘lanishingiz kerak.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM karta PIN kodi xato kiritildi, yana # marta urinishingiz mumkin, urinishlar tugagandan keyin qurilmangizni qulfdan chiqarish uchun aloqa operatoringizga murojaat qilishingiz kerak.}other{SIM karta PIN kodi xato kiritildi, yana # marta urinishingiz mumkin. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM kartadan foydalanib bo‘lmaydi. Operatoringizga murojaat qiling."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM kartaning PUK kodi noto‘g‘ri kiritildi. Yana <xliff:g id="NUMBER_1">%d</xliff:g> ta muvaffaqiyatsiz urinishdan keyin SIM karta butunlay ishdan chiqadi.</item>
-      <item quantity="one">SIM karta PUK kodi noto‘g‘ri terildi, yana <xliff:g id="NUMBER_0">%d</xliff:g> marta urinib ko‘rganingizdan keyin SIM kartadan umuman foydalanib bo‘lmaydi.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM karta PUK kodi xato kiritildi, yana # marta urinishdan keyin SIM kartadan umuman foydalanib boʻlmay qoladi.}other{SIM karta PUK kodi xato kiritildi, yana # marta urinishdan keyin SIM kartadan umuman foydalanib boʻlmay qoladi.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM kartani qulfdan chiqarib bo‘lmadi!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM kartani qulfdan chiqarib bo‘lmadi!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Matn kiritish usulini almashtirish"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Qurilma qo‘lda qulflangan"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Aniqlanmadi"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Yuz bilan ochish uchun kamera ruxsatini bering"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">SIM PIN kodini kiriting, sizda <xliff:g id="NUMBER_1">%d</xliff:g> ta urinish bor.</item>
-      <item quantity="one">SIM PIN kodini kiriting, qurilmani qulfdan chiqarish uchun sizda <xliff:g id="NUMBER_0">%d</xliff:g> ta urinish bor.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana <xliff:g id="_NUMBER_1">%d</xliff:g> marta xato qilsangiz, SIM kartangiz butunlay qulflanadi. Batafsil axborot olish uchun tarmoq operatoriga murojaat qiling.</item>
-      <item quantity="one">SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana <xliff:g id="_NUMBER_0">%d</xliff:g> marta xato qilsangiz, SIM kartangiz butunlay qulflanadi. Batafsil axborot olish uchun tarmoq operatoriga murojaat qiling.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{SIM PIN kodini kiriting, qurilmani qulfdan chiqarish uchun sizda # ta urinish bor.}other{SIM karta PIN kodini kiriting. Sizda # ta urinish qoldi.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana # marta xato qilsangiz, SIM kartangiz butunlay qulflanadi. Batafsil axborot olish uchun aloqa operatoriga murojaat qiling.}other{SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana # marta xato qilsangiz, SIM kartangiz butunlay qulflanadi. Batafsil axborot olish uchun aloqa operatoriga murojaat qiling.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Odatiy"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Pufaklar"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index 5d6fc50..9a0eb44 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Bạn đã nhập sai mật khẩu <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Bạn đã vẽ không chính xác hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%2$d</xliff:g> giây."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Mã PIN của SIM không chính xác, bây giờ bạn phải liên hệ với nhà cung cấp dịch vụ để mở khóa thiết bị của mình."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">Mã PIN của SIM không chính xác, bạn còn <xliff:g id="NUMBER_1">%d</xliff:g> lần thử.</item>
-      <item quantity="one">Mã PIN của SIM không chính xác, bạn còn <xliff:g id="NUMBER_0">%d</xliff:g> lần thử trước khi bạn phải liên hệ với nhà cung cấp dịch vụ để mở khóa thiết bị của mình.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Mã PIN của SIM không chính xác. Bạn còn # lần thử trước khi phải liên hệ với nhà cung cấp dịch vụ để mở khóa thiết bị của mình.}other{Mã PIN của SIM không chính xác, bạn còn # lần thử. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM không thể sử dụng được. Hãy liên hệ với nhà cung cấp dịch vụ của bạn."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">Mã PUK của SIM không chính xác, bạn còn <xliff:g id="NUMBER_1">%d</xliff:g> lần thử trước khi SIM vĩnh viễn không thể sử dụng được.</item>
-      <item quantity="one">Mã PUK của SIM không chính xác, bạn còn <xliff:g id="NUMBER_0">%d</xliff:g> lần thử trước khi SIM vĩnh viễn không thể sử dụng được.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Mã PUK của SIM không chính xác, bạn còn # lần thử trước khi SIM vĩnh viễn không thể sử dụng được.}other{Mã PUK của SIM không chính xác, bạn còn # lần thử trước khi SIM vĩnh viễn không thể sử dụng được.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Thao tác mã PIN của SIM không thành công!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Thao tác mã PUK của SIM không thành công!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Chuyển phương thức nhập"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Thiết bị đã bị khóa theo cách thủ công"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Không nhận dạng được"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Cho phép truy cập máy ảnh để dùng Mở khóa bằng khuôn mặt"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">Hãy nhập mã PIN của SIM. Bạn còn <xliff:g id="NUMBER_1">%d</xliff:g> lần thử.</item>
-      <item quantity="one">Hãy nhập mã PIN của SIM. Bạn còn <xliff:g id="NUMBER_0">%d</xliff:g> lần thử trước khi phải liên hệ với nhà mạng để mở khóa thiết bị của mình.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM hiện đã bị tắt. Hãy nhập mã PUK để tiếp tục. Bạn còn <xliff:g id="_NUMBER_1">%d</xliff:g> lần thử trước khi SIM vĩnh viễn không sử dụng được. Hãy liên hệ với nhà cung cấp dịch vụ để biết chi tiết.</item>
-      <item quantity="one">SIM hiện đã bị tắt. Hãy nhập mã PUK để tiếp tục. Bạn còn <xliff:g id="_NUMBER_0">%d</xliff:g> lần thử trước khi SIM vĩnh viễn không thể sử dụng được. Hãy liên hệ với nhà cung cấp dịch vụ để biết chi tiết.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Hãy nhập mã PIN của SIM. Bạn còn # lần thử trước khi phải liên hệ với nhà cung cấp dịch vụ để mở khóa thiết bị của mình.}other{Nhập mã PIN của SIM. Bạn còn # lần thử.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM hiện đã bị tắt. Hãy nhập mã PUK để tiếp tục. Bạn còn # lần thử trước khi SIM vĩnh viễn không thể sử dụng được. Hãy liên hệ với nhà cung cấp dịch vụ để biết thông tin chi tiết.}other{SIM hiện đã bị tắt. Hãy nhập mã PUK để tiếp tục. Bạn còn # lần thử trước khi SIM vĩnh viễn không thể sử dụng được. Hãy liên hệ với nhà cung cấp dịch vụ để biết thông tin chi tiết.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Mặc định"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bong bóng"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Đồng hồ kim"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index e74fa75..26e3db7 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"您已经 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次输错密码。\n\n请在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒后重试。"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"您已经 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次画错解锁图案。\n\n请在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒后重试。"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM 卡 PIN 码不正确,您现在必须联系运营商为您解锁设备。"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM 卡 PIN 码不正确,您还有 <xliff:g id="NUMBER_1">%d</xliff:g> 次尝试机会。</item>
-      <item quantity="one">SIM 卡 PIN 码不正确,您还有 <xliff:g id="NUMBER_0">%d</xliff:g> 次尝试机会。如果仍不正确,则需要联系运营商帮您解锁设备。</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM 卡 PIN 码不正确,您还可以尝试 # 次,如果仍不正确,则必须联系运营商帮您解锁设备。}other{SIM 卡 PIN 码不正确,您还可以尝试 # 次。}}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM 卡无法使用,请与您的运营商联系。"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM 卡 PUK 码不正确,您还有 <xliff:g id="NUMBER_1">%d</xliff:g> 次尝试机会。如果仍不正确,SIM 卡将永远无法使用。</item>
-      <item quantity="one">SIM 卡 PUK 码不正确,您还有 <xliff:g id="NUMBER_0">%d</xliff:g> 次尝试机会。如果仍不正确,SIM 卡将永远无法使用。</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM 卡 PUK 码不正确,您还可以尝试 # 次,如果仍不正确,SIM 卡将永远无法使用。}other{SIM 卡 PUK 码不正确,您还可以尝试 # 次,如果仍不正确,SIM 卡将永远无法使用。}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM 卡 PIN 码操作失败!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM 卡 PUK 码操作失败!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"切换输入法"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"此设备已手动锁定"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"无法识别"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"如需使用人脸解锁功能,请在“设置”中开启摄像头使用权限"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">请输入 SIM 卡 PIN 码,您还可以尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次。</item>
-      <item quantity="one">请输入 SIM 卡 PIN 码,您还可以尝试 <xliff:g id="NUMBER_0">%d</xliff:g> 次。如果仍不正确,则需要联系运营商帮您解锁设备。</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM 卡现已停用,请输入 PUK 码继续使用。您还可以尝试 <xliff:g id="_NUMBER_1">%d</xliff:g> 次。如果仍不正确,该 SIM 卡将永远无法使用。有关详情,请联系您的运营商。</item>
-      <item quantity="one">SIM 卡现已停用,请输入 PUK 码继续使用。您还可以尝试 <xliff:g id="_NUMBER_0">%d</xliff:g> 次。如果仍不正确,该 SIM 卡将永远无法使用。有关详情,请联系您的运营商。</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{请输入 SIM 卡 PIN 码。您还可以尝试 # 次,如果仍不正确,则必须联系运营商帮您解锁设备。}other{请输入 SIM 卡 PIN 码。您还可以尝试 # 次。}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM 卡现已停用,请输入 PUK 码继续使用。您还可以尝试 # 次,如果仍不正确,SIM 卡将永远无法使用。有关详情,请联系运营商。}other{SIM 卡现已停用,请输入 PUK 码继续使用。您还可以尝试 # 次,如果仍不正确,SIM 卡将永远无法使用。有关详情,请联系运营商。}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"默认"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"泡泡"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"指针"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index c22ecdc..2bd2105 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM 卡 PIN 碼不正確,您現在必須聯絡流動網絡供應商為您的裝置解鎖。"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM 卡的 PIN 碼不正確,您還有 <xliff:g id="NUMBER_1">%d</xliff:g> 次輸入機會。</item>
-      <item quantity="one">SIM 卡的 PIN 碼不正確,您還有 <xliff:g id="NUMBER_0">%d</xliff:g> 次輸入機會。如果仍然輸入錯誤,您必須聯絡流動網絡供應商為您的裝置解鎖。</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM 卡的 PIN 碼不正確,您還可以再試 # 次。如果仍然輸入錯誤,您必須聯絡流動網絡供應商解鎖您的裝置。}other{SIM 卡的 PIN 碼不正確,您還可以再試 # 次。}}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM 卡無法使用,請聯絡您的流動網絡供應商。"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM 卡的 PUK 碼不正確,您還有 <xliff:g id="NUMBER_1">%d</xliff:g> 次輸入機會。如果仍然輸入錯誤,SIM 卡將永久無法使用。</item>
-      <item quantity="one">SIM 卡的 PUK 碼不正確,您還有 <xliff:g id="NUMBER_0">%d</xliff:g> 次輸入機會。如果仍然輸入錯誤,SIM 卡將永久無法使用。</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM 卡的 PUK 碼不正確,您還可以再試 # 次。如果仍然輪入錯誤,SIM 卡將永久無法使用。}other{SIM 卡的 PUK 碼不正確,您還可以再試 # 次。如果仍然輪入錯誤,SIM 卡將永久無法使用。}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"無法使用 SIM 卡 PIN 碼解鎖!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"無法使用 SIM 卡 PUK 碼解鎖!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"轉換輸入方法"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"使用者已手動將裝置上鎖"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"未能識別"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"如要使用「面孔解鎖」,請在「設定」開啟相機存取權"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">輸入 SIM 卡的 PIN,您還可以再試 <xliff:g id="NUMBER_1">%d</xliff:g> 次。</item>
-      <item quantity="one">輸入 SIM 卡的 PIN,您還可以再試 <xliff:g id="NUMBER_0">%d</xliff:g> 次。如果仍然輸入錯誤,您必須聯絡流動網絡供應商解鎖您的裝置。</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM 卡已停用。請輸入 PUK 碼以繼續進行。您還可以再試 <xliff:g id="_NUMBER_1">%d</xliff:g> 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請與流動網絡供應商聯絡。</item>
-      <item quantity="one">SIM 卡已停用。請輸入 PUK 碼以繼續進行。您還可以再試 <xliff:g id="_NUMBER_0">%d</xliff:g> 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請與流動網絡供應商聯絡。</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{輸入 SIM 卡的 PIN,您還可以再試 # 次。如果仍然輸入錯誤,您必須聯絡流動網絡供應商解鎖您的裝置。}other{輸入 SIM 卡的 PIN。您還可以再試 # 次。}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM 卡已停用。請輸入 PUK 碼以繼續進行。您還可以再試 # 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請向流動網絡供應商查詢。}other{SIM 卡已停用。請輸入 PUK 碼以繼續進行。您還可以再試 # 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請向流動網絡供應商查詢。}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"預設"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"泡泡"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"指針"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index 498f748..a662553 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"你已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"你已畫出錯誤的解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"SIM 卡的 PIN 碼輸入錯誤,你現在必須請電信業者為裝置解鎖。"</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="other">SIM 卡的 PIN 碼輸入錯誤,你還可以再試 <xliff:g id="NUMBER_1">%d</xliff:g> 次。</item>
-      <item quantity="one">SIM 卡的 PIN 碼輸入錯誤,你還可以再試 <xliff:g id="NUMBER_0">%d</xliff:g> 次。如果仍然失敗,就必須請電信業者為裝置解鎖。</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{SIM 卡 PIN 碼輸入錯誤,您還可以再試 # 次。如果仍然失敗,就必須聯絡電信業者為裝置解鎖。}other{SIM 卡 PIN 碼輸入錯誤,您還可以再試 # 次。}}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"SIM 卡無法使用,請與你的電信業者聯絡。"</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="other">SIM 卡的 PUK 碼輸入錯誤,你還可以再試 <xliff:g id="NUMBER_1">%d</xliff:g> 次。如果仍然失敗,SIM 卡將永久無法使用。</item>
-      <item quantity="one">SIM 卡的 PUK 碼輸入錯誤,你還可以再試 <xliff:g id="NUMBER_0">%d</xliff:g> 次。如果仍然失敗,SIM 卡將永久無法使用。</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{SIM 卡 PUK 碼輸入錯誤,您還可以再試 # 次,如果仍然失敗,SIM 卡將永久無法使用。}other{SIM 卡 PUK 碼輸入錯誤,您還可以再試 # 次,如果仍然失敗,SIM 卡將永久無法使用。}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"SIM 卡 PIN 碼解鎖失敗!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"SIM 卡 PUK 碼解鎖失敗!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"切換輸入法"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"裝置已手動鎖定"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"無法識別"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"如要使用人臉解鎖功能,請在「設定」中開啟相機存取權。"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="other">請輸入 SIM 卡的 PIN 碼,你還可以再試 <xliff:g id="NUMBER_1">%d</xliff:g> 次。</item>
-      <item quantity="one">請輸入 SIM 卡的 PIN 碼,你還可以再試 <xliff:g id="NUMBER_0">%d</xliff:g> 次。如果仍然失敗,就必須請電信業者為裝置解鎖。</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="other">SIM 卡現在已遭停用。請輸入 PUK 碼以繼續進行。你還可以再試 <xliff:g id="_NUMBER_1">%d</xliff:g> 次,如果仍然失敗,SIM 卡將永久無法使用。詳情請與電信業者聯絡。</item>
-      <item quantity="one">SIM 卡現在已遭停用。請輸入 PUK 碼以繼續進行。你還可以再試 <xliff:g id="_NUMBER_0">%d</xliff:g> 次,如果仍然失敗,SIM 卡將永久無法使用。詳情請與電信業者聯絡。</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{請輸入 SIM 卡 PIN 碼,您還可以再試 # 次,如果仍然失敗,就必須聯絡電信業者為裝置解鎖。}other{輸入 SIM 卡 PIN 碼您還可以再試 # 次}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM 卡現在已遭停用。請輸入 PUK 碼以繼續。您還可以再試 # 次,如果仍然失敗,SIM 卡將永久無法使用。詳情請洽詢電信業者。}other{SIM 卡現在已遭停用。請輸入 PUK 碼以繼續。您還可以再試 # 次,如果仍然失敗,SIM 卡將永久無法使用。詳情請洽詢電信業者。}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"預設"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"泡泡"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"類比"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index 70bed32..8c7f8309 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -68,15 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%1$d</xliff:g> izikhathi. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Udwebe iphathini yakho yokuvula ngendlela engafanele-<xliff:g id="NUMBER_0">%1$d</xliff:g>. \n\n Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"Ikhodi yephinikhodi ye-SIM engalungile manje kumele uxhumane nenkampini yenethiwekhi yakho ukuvula idivayisi yakho."</string>
-    <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="7030584350995485026">
-      <item quantity="one">Ikhodi engalungile yephinikhodi ye-SIM, unemizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g> esele.</item>
-      <item quantity="other">Ikhodi engalungile yephinikhodi ye-SIM, unemizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g> esele.</item>
-    </plurals>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{Ikhodi engalungile Yephinikhodi ye-SIM, unomzamo ongu-# osele ngaphambi kokuba uxhumane nenkampani yakho yenethiwekhi ukuvula idivayisi yakho.}one{Ikhodi engalungile Yephinikhodi ye-SIM, unemizamo engu-# esele. }other{Ikhodi engalungile Yephinikhodi ye-SIM, unemizamo engu-# esele. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"I-SIM ayisebenziseki. Xhumana nemkampini yenethiwekhi yakho."</string>
-    <plurals name="kg_password_wrong_puk_code" formatted="false" msgid="3937306685604862886">
-      <item quantity="one">Ikhodi ye-PUK ye-SIM engalungile, unemizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g> esele ngaphambi kokuthi i-SIM ingasasebenziseki unaphakade.</item>
-      <item quantity="other">Ikhodi ye-PUK ye-SIM engalungile, unemizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g> esele ngaphambi kokuthi i-SIM ingasasebenziseki unaphakade.</item>
-    </plurals>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{Ikhodi ye-PUK ye-SIM engalungile, unemizamo engu-# esele ngaphambi kokuba i-SIM ibe engasasebenziseki unomphela.}one{Ikhodi ye-PUK ye-SIM engalungile, unemizamo engu-# esele ngaphambi kokuthi i-SIM ibe engasasebenziseki unomphela.}other{Ikhodi ye-PUK ye-SIM engalungile, unemizamo engu-# esele ngaphambi kokuthi i-SIM ibe engasasebenziseki unomphela.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Umsebenzi wephinikhodi ye-SIM wehlulekile!"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"Umsebenzi we-PUK ye-SIM wehlulekile!"</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Shintsha indlela yokufaka"</string>
@@ -91,14 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Idivayisi ikhiywe ngokwenza"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Akwaziwa"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Ukuze usebenzise Ukuvula Ngobuso, vula ukufinyelela kwekhamera Kumasethingi"</string>
-    <plurals name="kg_password_default_pin_message" formatted="false" msgid="7730152526369857818">
-      <item quantity="one">Faka i-PIN ye-SIM, unemizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g> esele.</item>
-      <item quantity="other">Faka i-PIN ye-SIM, unemizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g> esele.</item>
-    </plurals>
-    <plurals name="kg_password_default_puk_message" formatted="false" msgid="571308542462946935">
-      <item quantity="one">I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Unemizamo engu-<xliff:g id="_NUMBER_1">%d</xliff:g> esele ngaphambi kokuthi i-SIM ingasebenziseki unaphakade. Xhumana nenkampani yenethiwekhi ngemininingwane.</item>
-      <item quantity="other">I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Unemizamo engu-<xliff:g id="_NUMBER_1">%d</xliff:g> esele ngaphambi kokuthi i-SIM ingasebenziseki unaphakade. Xhumana nenkampani yenethiwekhi ngemininingwane.</item>
-    </plurals>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Faka Iphinikhodi ye-SIM. Unemizamo engu-# esele ngaphambi kokuthi uxhumane nenkampani yakho yenethiwekhi ukuze uvule idivayisi yakho.}one{Faka Iphinikhodi ye-SIM Unemizamo engu-# esele.}other{Faka Iphinikhodi ye-SIM Unemizamo engu-# esele.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Unomzamo ongu-# osele ngaphambi kokuthi i-SIM ingasasebenziseki unomphela. Xhumana nenkampani yenethiwekhi ngemininingwane.}one{I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Unemizamo engu-# esele ngaphambi kokuthi i-SIM ingasasebenziseki unomphela. Xhumana nenkampani yenethiwekhi ngemininingwane.}other{I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Unemizamo engu-# esele ngaphambi kokuthi i-SIM ingasasebenziseki unomphela. Xhumana nenkampani yenethiwekhi ngemininingwane.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Okuzenzekelayo"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Ibhamuza"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"I-Analog"</string>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 77f1803..acf3e4d 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -102,12 +102,13 @@
          screen. -->
     <item name="half_opened_bouncer_height_ratio" type="dimen" format="float">0.0</item>
 
-    <!-- The actual amount of translation that is applied to the bouncer when it animates from one
-         side of the screen to the other in one-handed mode. Note that it will always translate from
-         the side of the screen to the other (it will "jump" closer to the destination while the
-         opacity is zero), but this controls how much motion will actually be applied to it while
-         animating. Larger values will cause it to move "faster" while fading out/in. -->
-    <dimen name="one_handed_bouncer_move_animation_translation">120dp</dimen>
+    <!-- The actual amount of translation that is applied to the security when it animates from one
+         side of the screen to the other in one-handed or user switcher mode. Note that it will
+         always translate from the side of the screen to the other (it will "jump" closer to the
+         destination while the opacity is zero), but this controls how much motion will actually be
+         applied to it while animating. Larger values will cause it to move "faster" while
+         fading out/in. -->
+    <dimen name="security_shift_animation_translation">120dp</dimen>
 
 
     <dimen name="bouncer_user_switcher_header_text_size">20sp</dimen>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 1be2d99..babe924 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -164,21 +164,21 @@
          Displayed in a dialog box.  -->
     <string name="kg_password_wrong_pin_code_pukked">Incorrect SIM PIN code you must now contact your carrier to unlock your device.</string>
     <!-- Instructions telling the user that they entered the wrong SIM PIN while trying
-         to unlock the keyguard.  Displayed in a dialog box.  -->
-    <plurals name="kg_password_wrong_pin_code">
-        <item quantity="one">Incorrect SIM PIN code, you have <xliff:g id="number">%d</xliff:g> remaining attempt before you must contact your carrier to unlock your device.</item>
-        <item quantity="other">Incorrect SIM PIN code, you have <xliff:g id="number">%d</xliff:g> remaining attempts.</item>
-    </plurals>
+         to unlock the keyguard.  Displayed in a dialog box.  [CHAR LIMIT=NONE] -->
+    <string name="kg_password_wrong_pin_code"> {count, plural,
+        =1 {Incorrect SIM PIN code, you have # remaining attempt before you must contact your carrier to unlock your device.}
+        other {Incorrect SIM PIN code, you have # remaining attempts. }
+    }</string>
 
     <!-- Instructions telling the user that they have exhausted SIM PUK retries and the SIM is now unusable.
          Displayed in a dialog box.  -->
     <string name="kg_password_wrong_puk_code_dead">SIM is unusable. Contact your carrier.</string>
     <!-- Instructions telling the user that they entered the wrong puk while trying
-         to unlock the keyguard.  Displayed in a dialog box.  -->
-    <plurals name="kg_password_wrong_puk_code">
-        <item quantity="one">Incorrect SIM PUK code, you have <xliff:g id="number">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.</item>
-        <item quantity="other">Incorrect SIM PUK code, you have <xliff:g id="number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item>
-    </plurals>
+         to unlock the keyguard.  Displayed in a dialog box.  [CHAR LIMIT=NONE] -->
+    <string name="kg_password_wrong_puk_code">{count, plural,
+        =1 {Incorrect SIM PUK code, you have # remaining attempt before SIM becomes permanently unusable.}
+        other {Incorrect SIM PUK code, you have # remaining attempts before SIM becomes permanently unusable.}
+    }</string>
     <!-- Instructions telling the user that the operation to unlock the keyguard
          with SIM PIN failed. Displayed in one line in a large font.  -->
     <string name="kg_password_pin_failed">SIM PIN operation failed!</string>
@@ -223,21 +223,17 @@
      <!-- Error message indicating that the camera privacy sensor has been turned on [CHAR LIMIT=53] -->
     <string name="kg_face_sensor_privacy_enabled">To use Face Unlock, turn on camera access in Settings</string>
 
-    <!-- Instructions telling the user remaining times when enter SIM PIN view.  -->
-    <plurals name="kg_password_default_pin_message">
-        <item quantity="one">Enter SIM PIN. You have <xliff:g id="number">%d</xliff:g> remaining
-attempt before you must contact your carrier to unlock your device.</item>
-        <item quantity="other">Enter SIM PIN. You have <xliff:g id="number">%d</xliff:g> remaining
-attempts.</item>
-    </plurals>
+    <!-- Instructions telling the user remaining times when enter SIM PIN view.  [CHAR LIMIT=NONE] -->
+    <string name="kg_password_default_pin_message">{count, plural,
+        =1 {Enter SIM PIN. You have # remaining attempt before you must contact your carrier to unlock your device.}
+        other {Enter SIM PIN. You have # remaining attempts.}
+    }</string>
 
-    <!-- Instructions telling the user remaining times when enter SIM PUK view.  -->
-    <plurals name="kg_password_default_puk_message">
-        <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="
-number">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact carrier for details.</item>
-        <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="
-number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact carrier for details.</item>
-    </plurals>
+    <!-- Instructions telling the user remaining times when enter SIM PUK view. [CHAR LIMIT=NONE] -->
+    <string name="kg_password_default_puk_message">{count, plural,
+        =1 {SIM is now disabled. Enter PUK code to continue. You have # remaining attempt before SIM becomes permanently unusable. Contact carrier for details.}
+        other {SIM is now disabled. Enter PUK code to continue. You have # remaining attempts before SIM becomes permanently unusable. Contact carrier for details.}
+    }</string>
 
     <!-- Name of the "Default" clock face, which is the clock face that will be shown by default. [CHAR LIMIT=15]-->
     <string name="clock_title_default">Default</string>
diff --git a/libs/WindowManager/Shell/res/color/unfold_transition_background.xml b/packages/SystemUI/res/drawable/broadcast_dialog_btn_bg.xml
similarity index 61%
copy from libs/WindowManager/Shell/res/color/unfold_transition_background.xml
copy to packages/SystemUI/res/drawable/broadcast_dialog_btn_bg.xml
index 63289a3..5fd7ee29 100644
--- a/libs/WindowManager/Shell/res/color/unfold_transition_background.xml
+++ b/packages/SystemUI/res/drawable/broadcast_dialog_btn_bg.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
+<!--
+     Copyright (C) 2022 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,7 +14,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- Matches taskbar color -->
-    <item android:color="@android:color/system_neutral2_500" android:lStar="35" />
-</selector>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+       android:shape="rectangle">
+    <solid android:color="?androidprv:attr/colorAccentPrimary" />
+    <corners android:radius="@dimen/broadcast_dialog_btn_radius" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/dream_aqi_badge_bg.xml b/packages/SystemUI/res/drawable/dream_aqi_badge_bg.xml
new file mode 100644
index 0000000..1992c77
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dream_aqi_badge_bg.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/dream_overlay_aqi_unknown" />
+    <corners android:radius="@dimen/dream_aqi_badge_corner_radius" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_screen_saver.xml b/packages/SystemUI/res/drawable/ic_qs_screen_saver.xml
new file mode 100644
index 0000000..263a3d1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_screen_saver.xml
@@ -0,0 +1,24 @@
+<!--
+    Copyright (C) 2022 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:tint="?android:attr/colorControlNormal">
+    <path android:fillColor="@android:color/white"
+          android:pathData="M5,15H19L14.5,9L11,13.5L8.5,10.5ZM6,21Q5.575,21 5.287,20.712Q5,20.425 5,20V19H3Q2.175,19 1.588,18.413Q1,17.825 1,17V6Q1,5.175 1.588,4.588Q2.175,4 3,4H21Q21.825,4 22.413,4.588Q23,5.175 23,6V17Q23,17.825 22.413,18.413Q21.825,19 21,19H19V20Q19,20.425 18.712,20.712Q18.425,21 18,21ZM3,17H21Q21,17 21,17Q21,17 21,17V6Q21,6 21,6Q21,6 21,6H3Q3,6 3,6Q3,6 3,6V17Q3,17 3,17Q3,17 3,17ZM3,17Q3,17 3,17Q3,17 3,17V6Q3,6 3,6Q3,6 3,6Q3,6 3,6Q3,6 3,6V17Q3,17 3,17Q3,17 3,17Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_screen_saver_undocked.xml b/packages/SystemUI/res/drawable/ic_qs_screen_saver_undocked.xml
new file mode 100644
index 0000000..1d1b4f5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_screen_saver_undocked.xml
@@ -0,0 +1,30 @@
+<!--
+    Copyright (C) 2022 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M14.5,9l-3.5,4.51l-2.5,-3.01l-3.5,4.5l14,0z"
+        />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M21,4H3C1.9,4 1,4.9 1,6V17C1,18.1 1.9,19 3,19H5H19H21C22.1,19 23,18.1 23,17V6C23,4.9 22.1,4 21,4ZM21,17H3V6H21V17Z"
+        />
+</vector>
diff --git a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
index 3a08a71..41123c8 100644
--- a/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
+++ b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
@@ -16,19 +16,13 @@
 * limitations under the License.
 */
 -->
-<ripple
+<shape
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    android:color="?android:attr/textColorPrimary">
-  <item>
-    <shape
-        android:shape="rectangle">
-      <solid android:color="?androidprv:attr/colorSurface"/>
-      <size
-          android:width="@dimen/keyguard_affordance_width"
-          android:height="@dimen/keyguard_affordance_height"/>
-      <corners android:radius="@dimen/keyguard_affordance_fixed_radius"/>
-    </shape>
-  </item>
-</ripple>
-
+    android:shape="rectangle">
+  <solid android:color="?androidprv:attr/colorSurface"/>
+  <size
+      android:width="@dimen/keyguard_affordance_width"
+      android:height="@dimen/keyguard_affordance_height"/>
+  <corners android:radius="@dimen/keyguard_affordance_fixed_radius"/>
+</shape>
diff --git a/packages/SystemUI/res/drawable/settings_input_antenna.xml b/packages/SystemUI/res/drawable/settings_input_antenna.xml
new file mode 100644
index 0000000..f2adcaf
--- /dev/null
+++ b/packages/SystemUI/res/drawable/settings_input_antenna.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2022 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp"
+        android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"
+        android:tint="?android:attr/textColorSecondary">
+    <path android:fillColor="#FF000000"
+          android:pathData="M9,22.4 L7.6,21 11,17.6V14.3Q10.325,14 9.913,13.375Q9.5,12.75 9.5,12Q9.5,10.95 10.225,10.225Q10.95,9.5 12,9.5Q13.05,9.5 13.775,10.225Q14.5,10.95 14.5,12Q14.5,12.75 14.088,13.375Q13.675,14 13,14.3V17.6L16.4,21L15,22.4L12,19.4ZM5,12Q5,9.05 7.05,7.025Q9.1,5 12,5Q14.9,5 16.95,7.025Q19,9.05 19,12H17Q17,9.925 15.538,8.462Q14.075,7 12,7Q9.925,7 8.463,8.462Q7,9.925 7,12ZM1,12Q1,9.7 1.863,7.7Q2.725,5.7 4.225,4.212Q5.725,2.725 7.725,1.862Q9.725,1 12,1Q14.275,1 16.275,1.862Q18.275,2.725 19.775,4.212Q21.275,5.7 22.138,7.7Q23,9.7 23,12H21Q21,10.125 20.288,8.487Q19.575,6.85 18.35,5.625Q17.125,4.4 15.488,3.7Q13.85,3 12,3Q10.15,3 8.512,3.7Q6.875,4.4 5.65,5.625Q4.425,6.85 3.712,8.487Q3,10.125 3,12Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/broadcast_dialog.xml b/packages/SystemUI/res/layout/broadcast_dialog.xml
new file mode 100644
index 0000000..5ba2afe
--- /dev/null
+++ b/packages/SystemUI/res/layout/broadcast_dialog.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/dialog_bg"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/broadcast_dialog_margin"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/dialog_icon"
+            android:layout_width="@dimen/broadcast_dialog_icon_size"
+            android:layout_height="@dimen/broadcast_dialog_icon_size"
+            android:layout_marginTop="@dimen/broadcast_dialog_icon_margin_top"
+            android:layout_marginBottom="@dimen/broadcast_dialog_title_img_margin_top"
+            android:layout_gravity="center"
+            android:src="@drawable/settings_input_antenna"/>
+
+        <TextView
+            style="@style/BroadcastDialogTitleStyle"
+            android:id="@+id/dialog_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_gravity="center"/>
+
+        <TextView
+            style="@style/BroadcastDialogBodyStyle"
+            android:id="@+id/dialog_subtitle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_gravity="center"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="@dimen/broadcast_dialog_margin"
+        android:layout_marginBottom="@dimen/broadcast_dialog_margin"
+        android:orientation="vertical">
+
+        <Button
+            android:layout_marginBottom="@dimen/broadcast_dialog_btn_margin_bottom"
+            android:id="@+id/switch_broadcast"
+            style="@style/BroadcastDialogButtonStyle"/>
+
+        <Button
+            android:layout_marginBottom="@dimen/broadcast_dialog_btn_margin_bottom"
+            android:id="@+id/change_output"
+            android:text="@string/bt_le_audio_broadcast_dialog_different_output"
+            style="@style/BroadcastDialogButtonStyle"/>
+
+        <Button
+            android:id="@+id/cancel"
+            android:text="@android:string/cancel"
+            style="@style/BroadcastDialogButtonStyle"/>
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/dream_overlay_complication_aqi.xml b/packages/SystemUI/res/layout/dream_overlay_complication_aqi.xml
new file mode 100644
index 0000000..fcebb8d
--- /dev/null
+++ b/packages/SystemUI/res/layout/dream_overlay_complication_aqi.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/aqi_view"
+    style="@style/clock_subtitle"
+    android:visibility="gone"
+    android:background="@drawable/dream_aqi_badge_bg"
+    android:paddingHorizontal="@dimen/dream_aqi_badge_padding_horizontal"
+    android:paddingVertical="@dimen/dream_aqi_badge_padding_vertical"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml b/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml
index 3f56baf..efbdd1a 100644
--- a/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_complication_clock_date.xml
@@ -20,5 +20,5 @@
     style="@style/clock_subtitle"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:format12Hour="EEE, MMM d"
-    android:format24Hour="EEE, MMM d"/>
+    android:format12Hour="@string/dream_date_complication_date_format"
+    android:format24Hour="@string/dream_date_complication_date_format"/>
diff --git a/packages/SystemUI/res/layout/dream_overlay_complication_clock_time.xml b/packages/SystemUI/res/layout/dream_overlay_complication_clock_time.xml
index e066d38..7a57293 100644
--- a/packages/SystemUI/res/layout/dream_overlay_complication_clock_time.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_complication_clock_time.xml
@@ -22,8 +22,8 @@
     android:fontFamily="@font/clock"
     android:includeFontPadding="false"
     android:textColor="@android:color/white"
-    android:format12Hour="h:mm"
-    android:format24Hour="kk:mm"
+    android:format12Hour="@string/dream_time_complication_12_hr_time_format"
+    android:format24Hour="@string/dream_time_complication_24_hr_time_format"
     android:shadowColor="@color/keyguard_shadow_color"
     android:shadowRadius="?attr/shadowRadius"
     android:textSize="@dimen/dream_overlay_complication_clock_time_text_size"/>
diff --git a/packages/SystemUI/res/layout/hybrid_conversation_notification.xml b/packages/SystemUI/res/layout/hybrid_conversation_notification.xml
index 43b1661..a313833 100644
--- a/packages/SystemUI/res/layout/hybrid_conversation_notification.xml
+++ b/packages/SystemUI/res/layout/hybrid_conversation_notification.xml
@@ -57,7 +57,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:singleLine="true"
-        style="?attr/hybridNotificationTextStyle"
+        android:paddingEnd="4dp"
+        style="@*android:style/Widget.DeviceDefault.Notification.Text"
     />
 
     <TextView
@@ -65,6 +66,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:singleLine="true"
-        style="?attr/hybridNotificationTextStyle"
+        android:paddingEnd="4dp"
+        style="@*android:style/Widget.DeviceDefault.Notification.Text"
     />
 </com.android.systemui.statusbar.notification.row.HybridConversationNotificationView>
diff --git a/packages/SystemUI/res/layout/hybrid_notification.xml b/packages/SystemUI/res/layout/hybrid_notification.xml
index e8d7751..9ea7be5 100644
--- a/packages/SystemUI/res/layout/hybrid_notification.xml
+++ b/packages/SystemUI/res/layout/hybrid_notification.xml
@@ -20,19 +20,22 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:gravity="bottom|start"
-    style="?attr/hybridNotificationStyle">
+    android:paddingStart="@*android:dimen/notification_content_margin_start"
+    android:paddingEnd="12dp">
     <TextView
         android:id="@+id/notification_title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:singleLine="true"
-        style="?attr/hybridNotificationTitleStyle"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
+        android:paddingEnd="4dp"
     />
     <TextView
         android:id="@+id/notification_text"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:singleLine="true"
-        style="?attr/hybridNotificationTextStyle"
+        android:paddingEnd="4dp"
+        style="@*android:style/Widget.DeviceDefault.Notification.Text"
     />
 </com.android.systemui.statusbar.notification.row.HybridNotificationView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/large_screen_shade_header.xml b/packages/SystemUI/res/layout/large_screen_shade_header.xml
index 250eabd..3029a27 100644
--- a/packages/SystemUI/res/layout/large_screen_shade_header.xml
+++ b/packages/SystemUI/res/layout/large_screen_shade_header.xml
@@ -22,7 +22,7 @@
     android:minHeight="@dimen/large_screen_shade_header_min_height"
     android:clickable="false"
     android:focusable="true"
-    android:paddingLeft="@dimen/qs_panel_padding"
+    android:paddingLeft="@dimen/large_screen_shade_header_left_padding"
     android:paddingRight="@dimen/qs_panel_padding"
     android:visibility="gone"
     android:theme="@style/Theme.SystemUI.QuickSettings.Header">
diff --git a/packages/SystemUI/res/layout/media_ttt_chip.xml b/packages/SystemUI/res/layout/media_ttt_chip.xml
index 4d24140..d886806 100644
--- a/packages/SystemUI/res/layout/media_ttt_chip.xml
+++ b/packages/SystemUI/res/layout/media_ttt_chip.xml
@@ -31,6 +31,8 @@
         android:padding="@dimen/media_ttt_chip_outer_padding"
         android:background="@drawable/media_ttt_chip_background"
         android:layout_marginTop="20dp"
+        android:layout_marginStart="@dimen/notification_side_paddings"
+        android:layout_marginEnd="@dimen/notification_side_paddings"
         android:clipToPadding="false"
         android:gravity="center_vertical"
         android:alpha="0.0"
@@ -46,8 +48,9 @@
 
         <TextView
             android:id="@+id/text"
-            android:layout_width="wrap_content"
+            android:layout_width="0dp"
             android:layout_height="wrap_content"
+            android:layout_weight="1"
             android:textSize="@dimen/media_ttt_text_size"
             android:textColor="?android:attr/textColorPrimary"
             android:alpha="0.0"
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index 77523ec9..c124aea 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -28,7 +28,7 @@
     android:importantForAccessibility="no"
     android:layout_gravity="center_vertical | start">
 
-    <com.android.systemui.util.SafeMarqueeTextView
+    <com.android.systemui.util.DelayableMarqueeTextView
         android:id="@+id/tile_label"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
@@ -41,7 +41,7 @@
         android:importantForAccessibility="no"
         android:textAppearance="@style/TextAppearance.QS.TileLabel"/>
 
-    <com.android.systemui.util.SafeMarqueeTextView
+    <com.android.systemui.util.DelayableMarqueeTextView
         android:id="@+id/app_label"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 3eb73e0..5b2edbc 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensors Af is aktief"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Verwyder alle kennisgewings."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">nog <xliff:g id="NUMBER_1">%s</xliff:g> kennisgewings binne.</item>
-      <item quantity="one">nog <xliff:g id="NUMBER_0">%s</xliff:g> kennisgewing binne.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{nog # kennisgewing binne.}other{nog # kennisgewings binne.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Skerm is in landskapsoriëntasie gesluit."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Skerm is in portretoriëntasie gesluit."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Nageregkas"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Outo-draai"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Outodraai skerm"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Ligging"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Sluimerskerm"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameratoegang"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofoontoegang"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Beskikbaar"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Warmkol"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Skakel tans aan …"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Databespaarder is aan"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d toestelle</item>
-      <item quantity="one">%d toestel</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# toestel}other{# toestelle}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Flitslig"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera in gebruik"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobiele data"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Wiil jy jou sessie voortsit?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Begin van voor af"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, gaan voort"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gasmodus"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Jy is in gasmodus"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"As ’n nuwe gebruiker bygevoeg word, sal gasmodus verlaat word en sal alle programme en data in die huidige gastesessie uitgevee word."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Gebruikerlimiet is bereik"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Jy kan tot <xliff:g id="COUNT">%d</xliff:g> gebruikers byvoeg.</item>
-      <item quantity="one">Net een gebruiker kan geskep word.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Jy kan net een gebruiker skep.}other{Jy kan tot # gebruikers byvoeg.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Verwyder gebruiker?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Alle programme en data van hierdie gebruiker sal uitgevee word."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Verwyder"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Herinner my"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Ontdoen"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Sluimer vir <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d uur</item>
-      <item quantity="one">%d uur</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minute</item>
-      <item quantity="one">%d minuut</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# uur}=2{# uur}other{# uur}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuut}other{# minute}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Batterybespaarder"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Opletberigte"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Battery"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skermkiekies"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Algemene boodskappe"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Kitsprogramme"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Opstelling"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Berging"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Wenke"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Kitsprogramme"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"wissel"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Toestelkontroles"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Kies program om kontroles by te voeg"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontroles bygevoeg.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontrole bygevoeg.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrole bygevoeg.}other{# kontroles bygevoeg.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Verwyder"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"As gunsteling gemerk"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"As gunsteling gemerk; posisie <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Voeg teël by"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Moenie teël byvoeg nie"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Kies gebruiker"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> programme is aktief</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> program is aktief</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app is aktief}other{# apps is aktief}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nuwe inligting"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiewe programme"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Hierdie programme is aktief en werk, selfs wanneer jy hulle nie gebruik nie. Dit verbeter hul funksies, maar beïnvloed dalk ook batterylewe."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gestel"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera en mikrofoon is af"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# kennisgewing}other{# kennisgewings}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitsaai"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hou op om <xliff:g id="APP_NAME">%1$s</xliff:g> uit te saai?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"As jy <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitsaai of die uitvoer verander, sal jou huidige uitsending stop"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Saai <xliff:g id="SWITCHAPP">%1$s</xliff:g> uit"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Verander uitvoer"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Onbekend"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml
index 93d26e8..e60f233 100644
--- a/packages/SystemUI/res/values-af/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Af"</item>
     <item msgid="460891964396502657">"Aan"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Onbeskikbaar"</item>
+    <item msgid="8014986104355098744">"Af"</item>
+    <item msgid="5966994759929723339">"Aan"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index b74dbc1..7214ec7 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"ዳሳሾች ጠፍተዋል ገቢር"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">ከውስጥ ተጨማሪ <xliff:g id="NUMBER_1">%s</xliff:g> ማሳወቂያዎች።</item>
-      <item quantity="other">ከውስጥ ተጨማሪ <xliff:g id="NUMBER_1">%s</xliff:g> ማሳወቂያዎች።</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# ተጨማሪ ማሳወቂያ ከውስጥ አለ።}one{# ተጨማሪ ማሳወቂያ ከውስጥ አለ።}other{# ተጨማሪ ማሳወቂያዎች ከውስጥ አሉ።}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ማያ ገጽ በወርድ ገፅ አቀማመጥ ተቆልፏል።"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ማያ ገጽ በቁም ገፅ አቀማመጥ ተቆልፏል።"</string>
     <string name="dessert_case" msgid="9104973640704357717">"የማወራረጃ ምግቦች መያዣ"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"በራስ ሰር አሽከርክር"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ማያ ገጽን በራስ-አሽከርክር"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"አካባቢ"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"የማያ ገጽ ማቆያ"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"የካሜራ መዳረሻ"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"የማይክሮፎን መዳረሻ"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ይገኛል"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"መገናኛ ነጥብ"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"በማብራት ላይ..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ውሂብ ቆጣቢ በርቷል"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d መሣሪያዎች</item>
-      <item quantity="other">%d መሣሪያዎች</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# መሣሪያ}one{# መሣሪያዎች}other{# መሣሪያዎች}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"የባትሪ ብርሃን"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"ካሜራ ስራ ላይ ነው"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"የተንቀሳቃሽ ስልክ ውሂብ"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ክፍለ-ጊዜዎን መቀጠል ይፈልጋሉ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"እንደገና ጀምር"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"አዎ፣ ቀጥል"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"የእንግዳ ሁነታ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"በእንግዳ ሁኔታ ውስጥ ነዎት"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"አዲስ ተጠቃሚ ማከል ከእንግዳ ሁነታ ወጥቶ ሁሉንም መተግበሪያዎች እና ውሂብ አሁን ካለው የእንግዳ ክፍለ ጊዜ ይሰርዛል።"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"የተጠቃሚ ገደብ ላይ ተደርሷል"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ተጠቃሚዎች ብቻ ናቸው ሊፈጠሩ የሚችሉት።</item>
-      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> ተጠቃሚዎች ብቻ ናቸው ሊፈጠሩ የሚችሉት።</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{ሊፈጠር የሚችለው አንድ ተጠቃሚ ብቻ ነው።}one{እስከ # ተጠቃሚ ድረስ ማከል ይችላሉ።}other{እስከ # ተጠቃሚዎች ድረስ ማከል ይችላሉ።}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"ተጠቃሚ ይወገድ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ሁሉም የዚህ ተጠቃሚ መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"አስወግድ"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"አስታውሰኝ"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"ቀልብስ"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"ለ<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> አሸልቧል"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one"> %d ሰዓቶች</item>
-      <item quantity="other"> %d ሰዓቶች</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one"> %d ደቂቃዎች</item>
-      <item quantity="other"> %d ደቂቃዎች</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ሰዓት}=2{# ሰዓታት}one{# ሰዓት}other{# ሰዓታት}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# ደቂቃ}one{# ደቂቃ}other{# ደቂቃዎች}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"ባትሪ ቆጣቢ"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"ማንቂያዎች"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ባትሪ"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"ቅጽበታዊ ገጽ እይታዎች"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"አጠቃላይ መልዕክቶች"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"ቅጽበታዊ መተግበሪያዎች"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"ውቅረት"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ማከማቻ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"ፍንጮች"</string>
     <string name="instant_apps" msgid="8337185853050247304">"የቅጽበት መተግበሪያዎች"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ቀያይር"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"የመሣሪያ መቆጣጠሪያዎች"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"መቆጣጠሪያዎችን ለማከል መተግበሪያ ይምረጡ"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> ቁጥጥሮች ታክለዋል።</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ቁጥጥሮች ታክለዋል።</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ቁጥጥር ታክሏል።}one{# ቁጥጥር ታክሏል።}other{# ቁጥጥሮች ታክለዋል።}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ተወግዷል"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ተወዳጅ የተደረገ"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ተወዳጅ ተደርጓል፣ አቋም <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ሰቅ አክል"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ሰቅ አታክል"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ተጠቃሚን ይምረጡ"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> መተግበሪያዎች ንቁ ናቸው</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> መተግበሪያዎች ንቁ ናቸው</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# መተግበሪያ ገቢር ሆኗል}one{# መተግበሪያ ገቢር ሆኗል}other{# መተግበሪያዎች ገቢር ሆነዋል}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"አዲስ መረጃ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ገቢር መተግበሪያዎች"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"እነዚህ መተግበሪያዎች ንቁ እና እያሄዱ ናቸው፣ እርስዎ እየተጠቀሙባቸው ባይሆንም እንኳ። ይህ ተግባራዊነታቸውን ቢያሻሽልም በባትሪ ዕድሜያቸው ላይ ተጽዕኖ ሊኖረው ይችላል።"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ማንቂያ ተቀናብሯል"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ካሜራ እና ማይክሮፎን ጠፍተዋል"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ማሳወቂያ}one{# ማሳወቂያዎች}other{# ማሳወቂያዎች}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"በማሰራጨት ላይ"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ማሰራጨት ይቁም?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>ን ካሰራጩ ወይም ውፅዓትን ከቀየሩ የአሁኑ ስርጭትዎ ይቆማል"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ያሰራጩ"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ውፅዓትን ይቀይሩ"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ያልታወቀ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml
index 12be1ae..bbf2d23 100644
--- a/packages/SystemUI/res/values-am/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"አጥፋ"</item>
     <item msgid="460891964396502657">"አብራ"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"አይገኝም"</item>
+    <item msgid="8014986104355098744">"ጠፍቷል"</item>
+    <item msgid="5966994759929723339">"በርቷል"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index fdb89271..3138bf9 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -205,14 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"أجهزة الاستشعار غير مفعّلة"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"محو جميع الإشعارات."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="zero"><xliff:g id="NUMBER_1">%s</xliff:g> إشعار آخر بداخل المجموعة.</item>
-      <item quantity="two">إشعاران (<xliff:g id="NUMBER_1">%s</xliff:g>) آخران بداخل المجموعة.</item>
-      <item quantity="few"><xliff:g id="NUMBER_1">%s</xliff:g> إشعارات أخرى بداخل المجموعة.</item>
-      <item quantity="many"><xliff:g id="NUMBER_1">%s</xliff:g> إشعارًا آخر بداخل المجموعة.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> إشعار آخر بداخل المجموعة.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> إشعار آخر بداخل المجموعة.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{إشعار واحد آخر بداخل المجموعة.}zero{# إشعار آخر بداخل المجموعة.}two{إشعاران آخران بداخل المجموعة.}few{# إشعارات أخرى بداخل المجموعة.}many{# إشعارًا آخر بداخل المجموعة.}other{# إشعار آخر بداخل المجموعة.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"تم قفل الشاشة في الاتجاه الأفقي."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"تم قفل الشاشة في الاتجاه العمودي."</string>
     <string name="dessert_case" msgid="9104973640704357717">"حالة الحلويات"</string>
@@ -230,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"التدوير التلقائي"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"التدوير التلقائي للشاشة"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"الموقع الجغرافي"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"شاشة الاستراحة"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"الوصول إلى الكاميرا"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"الوصول إلى الميكروفون"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"متاح"</string>
@@ -259,14 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"نقطة اتصال"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"جارٍ التفعيل…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"توفير البيانات مفعّل"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="zero">‏%d جهاز</item>
-      <item quantity="two">‏جهازان (%d)</item>
-      <item quantity="few">‏%d أجهزة</item>
-      <item quantity="many">‏%d جهازًا</item>
-      <item quantity="other">‏%d جهاز</item>
-      <item quantity="one">‏جهاز واحد (%d)</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{جهاز واحد}zero{# جهاز}two{جهازان}few{# أجهزة}many{# جهازًا}other{# جهاز}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"الفلاش"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"الكاميرا قيد الاستخدام"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"بيانات الجوّال"</string>
@@ -359,15 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"هل تريد متابعة جلستك؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"البدء من جديد"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"نعم، متابعة"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"وضع الضيف"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"أنت تستخدِم وضع الضيف."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ستؤدي إضافة مُستخدِم جديد إلى الخروج من وضع الضيف وحذف كل التطبيقات والبيانات من جلسة الضيف الحالية."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"تم الوصول إلى أقصى عدد للمستخدمين"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="zero">يمكنك إضافة ما يصل إلى <xliff:g id="COUNT">%d</xliff:g> مستخدم.</item>
-      <item quantity="two">يمكنك إضافة ما يصل إلى مستخدمينِ (<xliff:g id="COUNT">%d</xliff:g>).</item>
-      <item quantity="few">يمكنك إضافة ما يصل إلى <xliff:g id="COUNT">%d</xliff:g> مستخدمين.</item>
-      <item quantity="many">يمكنك إضافة ما يصل إلى <xliff:g id="COUNT">%d</xliff:g> مستخدمًا.</item>
-      <item quantity="other">يمكنك إضافة ما يصل إلى <xliff:g id="COUNT">%d</xliff:g> مستخدم.</item>
-      <item quantity="one">يمكن إنشاء مستخدم واحد فقط.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{يمكن إنشاء مستخدم واحد فقط.}zero{يمكنك إضافة ما يصل إلى # مستخدم}two{يمكنك إضافة ما يصل إلى مستخدمَين}few{يمكنك إضافة ما يصل إلى # مستخدمِين}many{يمكنك إضافة ما يصل إلى # مستخدمًا}other{يمكنك إضافة ما يصل إلى # مستخدم}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"هل تريد إزالة المستخدم؟"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"سيتم حذف جميع تطبيقات وبيانات هذا المستخدم."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"إزالة"</string>
@@ -553,22 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"تذكيري"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"تراجع"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"تم تأجيل الإشعار لمدة <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="zero">‏%d ساعة</item>
-      <item quantity="two">‏ساعتان (%d)</item>
-      <item quantity="few">‏%d ساعات</item>
-      <item quantity="many">‏%d ساعة</item>
-      <item quantity="other">‏%d ساعة</item>
-      <item quantity="one">ساعة واحدة</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="zero">‏%d دقيقة</item>
-      <item quantity="two">‏دقيقتان (%d)</item>
-      <item quantity="few">‏%d دقائق</item>
-      <item quantity="many">‏%d دقيقة</item>
-      <item quantity="other">‏%d دقيقة</item>
-      <item quantity="one">دقيقة واحدة</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{ساعة واحدة}=2{ساعتان}zero{# ساعة}few{# ساعات}many{# ساعةً}other{# ساعة}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{دقيقة واحدة}zero{# دقيقة}two{دقيقتان}few{# دقائق}many{# دقيقةً}other{# دقيقة}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"توفير شحن البطارية"</string>
     <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>
@@ -717,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"التنبيهات"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"البطارية"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"لقطات الشاشة"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"رسائل عامة"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"التطبيقات الفورية"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"عملية الإعداد"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"مساحة التخزين"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"تلميحات"</string>
     <string name="instant_apps" msgid="8337185853050247304">"التطبيقات الفورية"</string>
@@ -791,14 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"إيقاف/تفعيل"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"التحكم بالجهاز"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"اختيار تطبيق لإضافة عناصر التحكّم"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="zero">تمت إضافة <xliff:g id="NUMBER_1">%s</xliff:g> عنصر تحكّم.</item>
-      <item quantity="two">تمت إضافة عنصرَي تحكّم (<xliff:g id="NUMBER_1">%s</xliff:g>).</item>
-      <item quantity="few">تمت إضافة <xliff:g id="NUMBER_1">%s</xliff:g> عناصر تحكّم.</item>
-      <item quantity="many">تمت إضافة <xliff:g id="NUMBER_1">%s</xliff:g> عنصر تحكّم.</item>
-      <item quantity="other">تمت إضافة <xliff:g id="NUMBER_1">%s</xliff:g> عنصر تحكّم.</item>
-      <item quantity="one">تمت إضافة عنصر تحكّم واحد (<xliff:g id="NUMBER_0">%s</xliff:g>).</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{تمت إضافة عنصر تحكّم واحد.}zero{تمت إضافة # عنصر تحكّم.}two{تمت إضافة عنصرَي تحكّم.}few{تمت إضافة # عناصر تحكّم.}many{تمت إضافة # عنصر تحكّم.}other{تمت إضافة # عنصر تحكّم.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"تمت الإزالة"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"تمت الإضافة إلى المفضّلة"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"تمت الإضافة إلى المفضّلة، الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -955,14 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"إضافة المربّع"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"عدم إضافة المربّع"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"اختيار المستخدم"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="zero"><xliff:g id="COUNT_1">%s</xliff:g> تطبيق نشط</item>
-      <item quantity="two">تطبيقَان نشطَان (<xliff:g id="COUNT_1">%s</xliff:g>)</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> تطبيقات نشطة</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> تطبيقًا نشطًا</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> تطبيق نشط</item>
-      <item quantity="one">تطبيق واحد نشط (<xliff:g id="COUNT_0">%s</xliff:g>)</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{تطبيق واحد نشط}zero{# تطبيق نشط}two{تطبيقَان نشطَان}few{# تطبيقات نشطة}many{# تطبيقًا نشطًا}other{# تطبيق نشط}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"معلومات جديدة"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"التطبيقات النشطة"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"هذه التطبيقات نشطة وقيد التشغيل، حتى في حال عدم استخدامها. يؤدي ذلك إلى تحسين وظائفها، ولكنه قد يؤثّر أيضًا على عمر البطارية."</string>
@@ -991,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"تم ضبط المنبه."</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"الكاميرا والميكروفون غير مفعّلين."</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{إشعار واحد}zero{# إشعار}two{إشعاران}few{# إشعارات}many{# إشعارًا}other{# إشعار}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"البث"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"هل تريد إيقاف بث تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>؟"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"إذا أجريت بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g> أو غيَّرت جهاز الإخراج، سيتوقَف البث الحالي."</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"تغيير جهاز الإخراج"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"غير معروف"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
index b4fb760..44b58f9 100644
--- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"غير مفعّل"</item>
     <item msgid="460891964396502657">"مفعّل"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"غير متوفّرة"</item>
+    <item msgid="8014986104355098744">"غير مفعّلة"</item>
+    <item msgid="5966994759929723339">"مفعَّلة"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 73166e9..fdb27ff 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"ছেন্সৰ অফ সক্ৰিয় কৰা আছে"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"আটাইবোৰ জাননী মচক৷"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one"> ভিতৰত আৰু <xliff:g id="NUMBER_1">%s</xliff:g>টা জাননী আছে।</item>
-      <item quantity="other"> ভিতৰত আৰু <xliff:g id="NUMBER_1">%s</xliff:g>টা জাননী আছে।</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{ভিতৰত আৰু # টা জাননী আছে।}one{ভিতৰত আৰু # টা জাননী আছে।}other{ভিতৰত আৰু # টা জাননী আছে।}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"স্ক্ৰীন লেণ্ডস্কে\'প দিশত লক কৰা হ’ল।"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"স্ক্ৰীন প\'ৰ্ট্ৰেইট দিশত লক কৰা হ’ল।"</string>
     <string name="dessert_case" msgid="9104973640704357717">"মিষ্টান্ন ভাণ্ডাৰ"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"স্বয়ং-ঘূৰ্ণন"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"স্বয়ং-ঘূৰ্ণন স্ক্ৰীন"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"অৱস্থান"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"স্ক্ৰীন ছেভাৰ"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"কেমেৰাৰ এক্সেছ"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"মাইকৰ এক্সেছ"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"উপলব্ধ"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"হটস্পট"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"অন কৰি থকা হৈছে…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ডেটা সঞ্চয়কাৰী অন হৈ আছে"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d ডিভাইচ</item>
-      <item quantity="other">%d ডিভাইচ</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# টা ডিভাইচ}one{# টা ডিভাইচ}other{# টা ডিভাইচ}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ফ্লাশ্বলাইট"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"কেমেৰা ব্যৱহাৰ হৈ আছে"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"ম’বাইল ডেটা"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপুনি আপোনাৰ ছেশ্বন অব্যাহত ৰাখিব বিচাৰেনে?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আকৌ আৰম্ভ কৰক"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হয়, অব্যাহত ৰাখক"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"অতিথি ম’ড"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"আপুনি অতিথি ম’ডত আছে"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"এগৰাকী নতুন ব্যৱহাৰকাৰীক যোগ দিয়াটোৱে অতিথি ম’ডৰ পৰা বাহিৰ কৰিব আৰু বৰ্তমানৰ অতিথিৰ ছেশ্বনটোৰ পৰা আটাইবোৰ এপ্ আৰু ডেটা মচিব।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"অধিকতম ব্যৱহাৰকাৰী সৃষ্টি কৰা হ’ল"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">আপুনি <xliff:g id="COUNT">%d</xliff:g> জনলৈকে ব্যৱহাৰকাৰী যোগ কৰিব পাৰে।</item>
-      <item quantity="other">আপুনি <xliff:g id="COUNT">%d</xliff:g> জনলৈকে ব্যৱহাৰকাৰী যোগ কৰিব পাৰে।</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{মাত্ৰ এগৰাকী ব্যৱহাৰকাৰী সৃষ্টি কৰিব পাৰি।}one{আপুনি # গৰাকী পৰ্যন্ত ব্যৱহাৰকাৰী যোগ দিব পাৰে।}other{আপুনি # গৰাকী পৰ্যন্ত ব্যৱহাৰকাৰী যোগ দিব পাৰে।}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"ব্যৱহাৰকাৰীক আঁতৰাবনে?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"এই ব্যৱহাৰকাৰীৰ আটাইবোৰ এপ্ আৰু ডেটা মচা হ\'ব।"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"আঁতৰাওক"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"মোক মনত পেলাই দিব"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"আনডু কৰক"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ৰ বাবে স্নুজ কৰক"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one"> %d ঘণ্টা</item>
-      <item quantity="other"> %d ঘণ্টা</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one"> %d মিনিট</item>
-      <item quantity="other"> %d মিনিট</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ঘণ্টা}=2{# ঘণ্টা}one{# ঘণ্টা}other{# ঘণ্টা}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# মিনিট}one{# মিনিট}other{# মিনিট}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"বেটাৰী সঞ্চয়কাৰী"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"সতৰ্কবার্তাসমূহ"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"বেটাৰী"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"স্ক্ৰীণশ্বটসমূহ"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"সাধাৰণ বার্তাসমূহ"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"তাৎক্ষণিক এপ্"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"ছেটআপ"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ষ্ট\'ৰেজ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"ইংগিতবোৰ"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ট’গল কৰক"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ডিভাইচৰ নিয়ন্ত্ৰণসমূহ"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"নিয়ন্ত্ৰণসমূহ যোগ কৰিবলৈ এপ্‌ বাছনি কৰক"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> টা নিয়ন্ত্ৰণ যোগ কৰা হ’ল।</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> টা নিয়ন্ত্ৰণ যোগ কৰা হ’ল।</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}one{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}other{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"আঁতৰোৱা হ’ল"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল, স্থান <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"টাইল যোগ দিয়ক"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"টাইল যোগ নিদিব"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ব্যৱহাৰকাৰী বাছনি কৰক"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> টা এপ্‌ সক্ৰিয় হৈ আছে</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> টা এপ্‌ সক্ৰিয় হৈ আছে</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# টা এপ্‌ সক্ৰিয় হৈ আছে}one{# টা এপ্‌ সক্ৰিয় হৈ আছে}other{# টা এপ্‌ সক্ৰিয় হৈ আছে}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"নতুন তথ্য"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"সক্ৰিয় এপ্‌"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"এই এপ্‌সমূহ সক্ৰিয় আৰু আনকি আপুনি এইসমূহ ব্যৱহাৰ নকৰাৰ সময়তো চলি থাকে। ই সেইসমূহৰ কাৰ্য্যক্ষমতা উন্নত কৰে, কিন্তু ই বেটাৰীৰ জীৱনকালতো প্ৰভাৱ পেলাব পাৰে।"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"এলাৰ্ম ছেট কৰা হ’ল"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"কেমেৰা আৰু মাইক অফ হৈ আছে"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# টা জাননী}one{# টা জাননী}other{# টা জাননী}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"সম্প্ৰচাৰণ"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰা বন্ধ কৰিবনে?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"যদি আপুনি <xliff:g id="SWITCHAPP">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰে অথবা আউটপুট সলনি কৰে, তেন্তে, আপোনাৰ বৰ্তমানৰ সম্প্ৰচাৰ বন্ধ হৈ যাব"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্ৰচাৰ কৰক"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"আউটপুট সলনি কৰক"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"অজ্ঞাত"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml
index 7767cfc..3145341 100644
--- a/packages/SystemUI/res/values-as/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"অফ"</item>
     <item msgid="460891964396502657">"অন"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"উপলব্ধ নহয়"</item>
+    <item msgid="8014986104355098744">"অফ আছে"</item>
+    <item msgid="5966994759929723339">"অন আছে"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 5bc2895..e747282 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"\"Deaktiv sensorlar\" aktivdir"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Bütün bildirişləri sil."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Daxilində daha <xliff:g id="NUMBER_1">%s</xliff:g> bildiriş.</item>
-      <item quantity="one">Daxilində daha <xliff:g id="NUMBER_0">%s</xliff:g> bildiriş.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Daha # bildiriş daxildir.}other{Daha # bildiriş daxildir.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekran landşaft orientasiyasında kilidlənib."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekran portret orientasiyasında kilidlənib."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Desert Qabı"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avtodönüş"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranın avtomatik dönməsi"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Məkan"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Ekran qoruyucu"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameraya giriş"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofona giriş"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Əlçatan"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Aktiv edilir..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Trafikə qənaət edilir"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d cihaz</item>
-      <item quantity="one">%d cihaz</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# cihaz}other{# cihaz}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Fənər"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera istifadə olunur"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobil data"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Sessiya davam etsin?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Yenidən başlayın"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Bəli, davam edin"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Qonaq rejimi"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Qonaq rejimindəsiniz"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Yeni istifadəçi əlavə edildikdə qonaq rejimindən çıxılacaq və cari qonaq sessiyasındakı bütün tətbiqlər və data silinəcək."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"İstifadəçi limitinə çatmısınız"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Maksimum <xliff:g id="COUNT">%d</xliff:g> istifadəçi əlavə edə bilərsiniz.</item>
-      <item quantity="one">Yalnız bir istifadəçi yaradıla bilər.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Yalnız bir istifadəçi yaradıla bilər.}other{Maksimum # istifadəçi əlavə edə bilərsiniz.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"İstifadəçi silinsin?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Bu istifadəçinin bütün tətbiqləri və datası silinəcək."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Silin"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Mənə xatırladın"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Geri qaytarın"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> üçün təxirə salınıb"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other"> %d saat</item>
-      <item quantity="one">%d saat</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d dəqiqə</item>
-      <item quantity="one">%d dəqiqə</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# saat}=2{# saat}other{# saat}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# dəqiqə}other{# dəqiqə}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Enerjiyə qənaət"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Xəbərdarlıqlar"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batareya"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skrinşotlar"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Ümumi Mesajlar"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Ani Tətbiqlər"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Ayarlama"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Yaddaş"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Məsləhətlər"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Ani Tətbiqlər"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"keçirin"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Cihaz kontrolları"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Kontrol əlavə etmək üçün tətbiq seçin"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> nizamlayıcı əlavə edilib.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> nizamlayıcı əlavə edilib.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# nizamlayıcı əlavə edilib.}other{# nizamlayıcı əlavə edilib.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Silinib"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Sevimlilərə əlavə edilib"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Sevimlilərə əlavə edilib, sıra: <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Mozaik əlavə edin"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Mozaik əlavə etməyin"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"İstifadəçi seçin"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> tətbiq aktivdir</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> tətbiq aktivdir</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# tətbiq aktivdir}other{# tətbiq aktivdir}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Yeni məlumat"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiv tətbiqlər"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"İstifadə etmədiyiniz zaman belə bu tətbiqlər aktiv olur və işləyir. Bu, onların funksionallığını yaxşılaşdırır, lakin bu, batareyanın ömrünə də təsir edə bilər."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Siqnal ayarlanıb"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera və mikrofon deaktivdir"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildiriş}other{# bildiriş}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayım"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinin yayımlanması dayandırılsın?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlasanız və ya nəticəni dəyişsəniz, cari yayımınız dayandırılacaq"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlayın"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Nəticəni dəyişdirin"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Naməlum"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml
index 0311794..fb745b25 100644
--- a/packages/SystemUI/res/values-az/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Deaktiv"</item>
     <item msgid="460891964396502657">"Aktiv"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Əlçatmazdır"</item>
+    <item msgid="8014986104355098744">"Deaktiv"</item>
+    <item msgid="5966994759929723339">"Aktiv"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 9437fb1..2b6bd9a 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -205,11 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Senzori su isključeni"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Obriši sva obaveštenja."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"i još <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Još <xliff:g id="NUMBER_1">%s</xliff:g> obaveštenje u grupi.</item>
-      <item quantity="few">Još <xliff:g id="NUMBER_1">%s</xliff:g> obaveštenja u grupi.</item>
-      <item quantity="other">Još <xliff:g id="NUMBER_1">%s</xliff:g> obaveštenja u grupi.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Unutra je još # obaveštenje.}one{Unutra je još # obaveštenje.}few{Unutra su još # obaveštenja.}other{Unutra je još # obaveštenja.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekran je zaključan u horizontalnom položaju."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekran je zaključan u vertikalnom položaju."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Vitrina sa poslasticama"</string>
@@ -227,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatska rotacija"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Čuvar ekrana"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pristup kameri"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pristup mikrofonu"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupno"</string>
@@ -256,11 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Uključuje se..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Ušteda podataka je uključena"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d uređaj</item>
-      <item quantity="few">%d uređaja</item>
-      <item quantity="other">%d uređaja</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# uređaj}one{# uređaj}few{# uređaja}other{# uređaja}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampa"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Koristi se kamera"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobilni podaci"</string>
@@ -353,12 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li da nastavite sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni iz početka"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Režim gosta"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Koristite režim gosta"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dodavanjem novog korisnika izaći ćete iz režima gosta i izbrisaćete sve aplikacije i podatke iz aktuelne sesije gosta."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut maksimalni broj korisnika"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Možete da dodate najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
-      <item quantity="few">Možete da dodate najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
-      <item quantity="other">Možete da dodate najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Možete da napravite samo jednog korisnika.}one{Možete da dodate najviše # korisnika.}few{Možete da dodate najviše # korisnika.}other{Možete da dodate najviše # korisnika.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Želite li da uklonite korisnika?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Sve aplikacije i podaci ovog korisnika će biti izbrisani."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Ukloni"</string>
@@ -544,16 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Podseti me"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Opozovi"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Odloženo je za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d sat</item>
-      <item quantity="few">%d sata</item>
-      <item quantity="other">%d sati</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minut</item>
-      <item quantity="few">%d minuta</item>
-      <item quantity="other">%d minuta</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# sat}=2{# sata}one{# sat}few{# sata}other{# sati}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minut}one{# minut}few{# minuta}other{# minuta}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Ušteda baterije"</string>
     <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>
@@ -702,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Obaveštenja"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Baterija"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Snimci ekrana"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Opšte poruke"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant aplikacije"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Podešavanje"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Memorijski prostor"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Saveti"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant aplikacije"</string>
@@ -776,11 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"uključite/isključite"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Odaberite aplikaciju za dodavanje kontrola"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> kontrola je dodata.</item>
-      <item quantity="few"><xliff:g id="NUMBER_1">%s</xliff:g> kontrole su dodate.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontrola je dodato.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrola je dodata.}one{# kontrola je dodata.}few{# kontrole su dodate.}other{# kontrola je dodato.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Označeno je kao omiljeno"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Označeno je kao omiljeno, <xliff:g id="NUMBER">%d</xliff:g>. pozicija"</string>
@@ -937,11 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj pločicu"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne dodaj pločicu"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Izaberite korisnika"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivna</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikacije su aktivne</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivno</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikacija je aktivna}one{# aplikacija je aktivna}few{# aplikacije su aktivne}other{# aplikacija je aktivno}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ove aplikacije su aktivne i rade čak i kada ih ne koristite. To im poboljšava funkcionalnost, ali može da utiče i na trajanje baterije."</string>
@@ -970,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je podešen"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obaveštenje}one{# obaveštenje}few{# obaveštenja}other{# obaveštenja}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitovanje"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite da zaustavite emitovanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitujete aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promenite izlaz, aktuelno emitovanje će se zaustaviti"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitujte aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promenite izlaz"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index a057c48..b69b064 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Isključeno"</item>
     <item msgid="460891964396502657">"Uključeno"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Nedostupno"</item>
+    <item msgid="8014986104355098744">"Isključeno"</item>
+    <item msgid="5966994759929723339">"Uključeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index d159693..f7fabb7 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -205,12 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Датчыкі выключаны"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Выдалiць усе апавяшчэннi."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Яшчэ <xliff:g id="NUMBER_1">%s</xliff:g> апавяшчэнне ўнутры.</item>
-      <item quantity="few">Яшчэ <xliff:g id="NUMBER_1">%s</xliff:g> апавяшчэнні ўнутры.</item>
-      <item quantity="many">Яшчэ <xliff:g id="NUMBER_1">%s</xliff:g> апавяшчэнняў унутры.</item>
-      <item quantity="other">Яшчэ <xliff:g id="NUMBER_1">%s</xliff:g> апавяшчэння ўнутры.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Яшчэ # апавяшчэнне ўнутры.}one{Яшчэ # апавяшчэнне ўнутры.}few{Яшчэ # апавяшчэнні ўнутры.}many{Яшчэ # апавяшчэнняў унутры.}other{Яшчэ # апавяшчэння ўнутры.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Экран заблакiраваны ў альбомнай арыентацыі."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Экран заблакiраваны ў партрэтнай арыентацыі."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Вітрына з дэсертамі"</string>
@@ -228,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аўтапаварот"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аўтаматычны паварот экрана"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Месцазнаходжанне"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Экранная застаўка"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ да камеры"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Доступ да мікрафона"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Доступ дазволены"</string>
@@ -257,12 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Хот-спот"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Уключэнне…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Эканомія трафіка ўкл"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d прылада</item>
-      <item quantity="few">%d прылады</item>
-      <item quantity="many">%d прылад</item>
-      <item quantity="other">%d прылады</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# прылада}one{# прылада}few{# прылады}many{# прылад}other{# прылады}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Ліхтарык"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Камера выкарыстоўваецца"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мабільная перадача даных"</string>
@@ -355,13 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Хочаце працягнуць сеанс?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Пачаць зноў"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Так, працягнуць"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Гасцявы рэжым"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Вы знаходзіцеся ў гасцявым рэжыме"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Дадаванне новага карыстальніка закрые гасцявы рэжым. Будуць выдалены ўсе праграмы і даныя бягучага гасцявога сеанса."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Дасягнуты ліміт карыстальнікаў"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Можна дадаць <xliff:g id="COUNT">%d</xliff:g> карыстальніка.</item>
-      <item quantity="few">Можна дадаць <xliff:g id="COUNT">%d</xliff:g> карыстальнікаў.</item>
-      <item quantity="many">Можна дадаць <xliff:g id="COUNT">%d</xliff:g> карыстальнікаў.</item>
-      <item quantity="other">Можна дадаць <xliff:g id="COUNT">%d</xliff:g> карыстальніка.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Можна стварыць толькі аднаго карыстальніка.}one{Вы можаце дадаць толькі # карыстальніка.}few{Вы можаце дадаць толькі # карыстальнікаў.}many{Вы можаце дадаць толькі # карыстальнікаў.}other{Вы можаце дадаць толькі # карыстальніка.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Выдаліць карыстальніка?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Усе праграмы і даныя гэтага карыстальніка будуць выдалены."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Выдаліць"</string>
@@ -385,7 +374,7 @@
     <string name="quick_settings_disclosure_named_management_monitoring" msgid="2831423806103479812">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
     <string name="quick_settings_financed_disclosure_named_management" msgid="2307703784594859524">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management_named_vpn" msgid="4137564460025113168">"Гэта прылада належыць вашай арганізацыі і падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%1$s</xliff:g>\""</string>
-    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да інтэрнэту праз \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
+    <string name="quick_settings_disclosure_named_management_named_vpn" msgid="2169227918166358741">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\" і падключана да інтэрнэту праз праграму \"<xliff:g id="VPN_APP">%2$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management" msgid="5515296598440684962">"Гэта прылада належыць вашай арганізацыі"</string>
     <string name="quick_settings_disclosure_named_management" msgid="3476472755775165827">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>\""</string>
     <string name="quick_settings_disclosure_management_vpns" msgid="929181757984262902">"Гэта прылада належыць вашай арганізацыі і падключана да інтэрнэту праз сеткі VPN"</string>
@@ -547,18 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Нагадаць"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Адрабіць"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Адкладзена на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d гадзіна</item>
-      <item quantity="few">%d гадзіны</item>
-      <item quantity="many">%d гадзін</item>
-      <item quantity="other">%d гадзіны</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d хвіліна</item>
-      <item quantity="few">%d хвіліны</item>
-      <item quantity="many">%d хвілін</item>
-      <item quantity="other">%d хвіліны</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# гадз}=2{# гадзіны}one{# гадзіна}few{# гадзіны}many{# гадзін}other{# гадзіны}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# хвіліна}one{# хвіліна}few{# хвіліны}many{# хвілін}other{# хвіліны}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Рэжым энергазберажэння"</string>
     <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>
@@ -707,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Абвесткі"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Акумулятар"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Здымкі экрана"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Агульныя паведамленні"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Імгненныя праграмы"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Наладжванне"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Захоўванне"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Падказкі"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Імгненныя праграмы"</string>
@@ -781,12 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"уключыць/выключыць"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Элементы кіравання прыладай"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Выберыце праграму для дадавання элементаў кіравання"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one">Дададзены <xliff:g id="NUMBER_1">%s</xliff:g> элемент кіравання.</item>
-      <item quantity="few">Дададзена <xliff:g id="NUMBER_1">%s</xliff:g> элементы кіравання.</item>
-      <item quantity="many">Дададзена <xliff:g id="NUMBER_1">%s</xliff:g> элементаў кіравання.</item>
-      <item quantity="other">Дададзена <xliff:g id="NUMBER_1">%s</xliff:g> элемента кіравання.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Дададзены # элемент кіравання.}one{Дададзена # элемента кіравання.}few{Дададзена # элементы кіравання.}many{Дададзена # элементаў кіравання.}other{Дададзена # элемента кіравання.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Выдалена"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Дададзена ў абранае"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Дададзена ў абранае, пазіцыя <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -943,12 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Дадаць плітку"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Не дадаваць плітку"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Выбар карыстальніка"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> праграма актыўная</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> праграмы актыўныя</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> праграм актыўныя</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> праграмы актыўныя</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# праграма актыўная}one{# праграма актыўныя}few{# праграмы актыўныя}many{# праграм актыўныя}other{# праграмы актыўныя}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Новая інфармацыя"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Актыўныя праграмы"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Гэтыя праграмы працуюць, нават калі вы іх не выкарыстоўваеце. У выніку павышаецца іх функцыянальнасць, аднак можа знізіцца час працы ад акумулятара."</string>
@@ -977,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будзільнік зададзены"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера і мікрафон выключаны"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# апавяшчэнне}one{# апавяшчэнне}few{# апавяшчэнні}many{# апавяшчэнняў}other{# апавяшчэння}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Перадача даных"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Спыніць трансляцыю праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Пры пераключэнні на праграму \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" ці змяненні вываду бягучая трансляцыя спыняецца"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Трансляцыя праграмы \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Змяненне вываду"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Невядома"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml
index d258811..8fb2da2 100644
--- a/packages/SystemUI/res/values-be/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Выключана"</item>
     <item msgid="460891964396502657">"Уключана"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Недаступна"</item>
+    <item msgid="8014986104355098744">"Выключана"</item>
+    <item msgid="5966994759929723339">"Уключана"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 922ba8c..e6608f3 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Сензорите са изключени"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Изчистване на всички известия."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Съдържа още <xliff:g id="NUMBER_1">%s</xliff:g> известия.</item>
-      <item quantity="one">Съдържа още <xliff:g id="NUMBER_0">%s</xliff:g> известие.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Съдържа още # известие.}other{Съдържа още # известия.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Екранът е заключен в хоризонтална ориентация."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Екранът е заключен във вертикална ориентация."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Витрина с десерти"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматична ориентация"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично завъртане на екрана"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Местоположение"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Скрийнсейвър"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Достъп до камерата"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Достъп до микрофона"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Налице"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Точка за достъп"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Включва се..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Икономия на данни е вкл."</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d устройства</item>
-      <item quantity="one">%d устройство</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# устройство}other{# устройства}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Фенерче"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Камерата се използва"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мобилни данни"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Искате ли да продължите сесията си?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Започване отначало"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продължавам"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Режим на гост"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Вие сте в режим на гост"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"С добавянето на нов потребител ще излезете от режима на гост и ще изтриете всички приложения и данни от текущата сесия като гост."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнахте огранич. за потребители"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Можете да добавите до <xliff:g id="COUNT">%d</xliff:g> потребители.</item>
-      <item quantity="one">Може да бъде създаден само един потребител.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Може да бъде създаден само един потребител.}other{Можете да добавите до # потребители.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Да се премахне ли потребителят?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Всички приложения и данни на този потребител ще бъдат изтрити."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Премахване"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Напомняне"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Отмяна"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Отложено за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d часа</item>
-      <item quantity="one">%d час</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d минути</item>
-      <item quantity="one">%d минута</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# час}=2{# часа}other{# часа}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# минута}other{# минути}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Режим за запазване на батерията"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Сигнали"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Батерия"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Екранни снимки"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Общи съобщения"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Мигновени приложения"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Настройване"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Хранилище"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Съвети"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Мигновени приложения"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"превключване"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Контроли за устройството"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Изберете приложение, за да добавите контроли"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">Добавени са <xliff:g id="NUMBER_1">%s</xliff:g> контроли.</item>
-      <item quantity="one">Добавена е <xliff:g id="NUMBER_0">%s</xliff:g> контрола.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавена е # контрола.}other{Добавени са # контроли.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Премахнато"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено като любимо"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено като любимо – позиция <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Добавяне на панел"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Отмяна на добавянето"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Избор на потребител"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> приложения са активни</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> приложение е активно</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# приложение е активно}other{# приложения са активни}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нова информация"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активни приложения"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Дори когато не ги използвате, тези приложения са активни и работят. Това подобрява функционалността им, но може да окаже и влияние върху живота на батерията."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будилникът е зададен"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонът са изключени"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известие}other{# известия}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Излъчване"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се спре ли предаването на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако предавате <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените изхода, текущото ви предаване ще бъде прекратено"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Предаване на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промяна на изхода"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Неизвестно"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
index da5c325..b85133b 100644
--- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Изкл."</item>
     <item msgid="460891964396502657">"Вкл."</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Не е налице"</item>
+    <item msgid="8014986104355098744">"Изкл."</item>
+    <item msgid="5966994759929723339">"Вкл."</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index cc54762..8a89491 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"সেন্সর অফ অ্যাক্টিভ"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"সমস্ত বিজ্ঞপ্তি সাফ করুন৷"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>টি"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">ভিতরে আরও <xliff:g id="NUMBER_1">%s</xliff:g>টি বিজ্ঞপ্তি আছে।</item>
-      <item quantity="other">ভিতরে আরও <xliff:g id="NUMBER_1">%s</xliff:g>টি বিজ্ঞপ্তি আছে।</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{ভিতরে আরও #টি বিজ্ঞপ্তি আছে।}one{ভিতরে আরও #টি বিজ্ঞপ্তি আছে।}other{ভিতরে আরও #টি বিজ্ঞপ্তি আছে।}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ল্যান্ডস্কেপ সজ্জাতে স্ক্রিন লক করা আছে৷"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"পোর্ট্রেট অবস্থায় স্ক্রিন লক করা আছে৷"</string>
     <string name="dessert_case" msgid="9104973640704357717">"ডেজার্ট কেস"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"নিজে থেকে ঘুরবে"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"অটো-রোটেট স্ক্রিন"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"লোকেশন"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"স্ক্রিন সেভার"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"ক্যামেরা অ্যাক্সেস"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"মাইক্রোফোন অ্যাক্সেস"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"উপলভ্য"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"হটস্পট"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"চালু করা হচ্ছে…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ডেটা সেভার চালু আছে"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%dটি ডিভাইস</item>
-      <item quantity="other">%dটি ডিভাইস</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{#টি ডিভাইস}one{#টি ডিভাইস}other{#টি ডিভাইস}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ফ্ল্যাশলাইট"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"ক্যামেরা ব্যবহার করা হচ্ছে"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"মোবাইল ডেটা"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপনি কি আপনার সেশনটি চালিয়ে যেতে চান?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আবার শুরু করুন"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হ্যাঁ, চালিয়ে যান"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"অতিথি মোড"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"আপনি \'অতিথি মোড\' ব্যবহার করছেন"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"নতুন ব্যবহারকারী যোগ করার মাধ্যমে \'অতিথি মোড\' ছেড়ে বেরিয়ে আসতে পারবেন এবং বর্তমান অতিথি সেশন থেকে সব অ্যাপ ও ডেটা মুছে যাবে।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"আর কোনও প্রোফাইল যোগ করা যাবে না"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">আপনি <xliff:g id="COUNT">%d</xliff:g> জন পর্যন্ত ব্যবহারকারীর প্রোফাইল যোগ করতে পারেন।</item>
-      <item quantity="other">আপনি <xliff:g id="COUNT">%d</xliff:g> জন পর্যন্ত ব্যবহারকারীর প্রোফাইল যোগ করতে পারেন।</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{শুধুমাত্র একজন ব্যবহারকারী ডিভাইস ব্যবহার করতে পারবেন।}one{আপনি # জন পর্যন্ত ব্যবহারকারীকে যোগ করতে পারবেন।}other{আপনি # জন পর্যন্ত ব্যবহারকারীকে যোগ করতে পারবেন।}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"ব্যবহারকারী সরাবেন?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"এই ব্যবহারকারীর সমস্ত অ্যাপ্লিকেশান ও ডেটা মুছে ফেলা হবে।"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"সরান"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"আমাকে মনে করিয়ে দিও"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"আগের অবস্থায় ফিরুন"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> পরে আবার মনে করানো হবে"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d ঘণ্টা</item>
-      <item quantity="other">%d ঘণ্টা</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d মিনিট</item>
-      <item quantity="other">%d মিনিট</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ঘণ্টা}=2{# ঘণ্টা}one{# ঘণ্টা}other{# ঘণ্টা}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# মিনিট}one{# মিনিট}other{# মিনিট}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"ব্যাটারি সেভার"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"সতর্কতা"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ব্যাটারি"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"স্ক্রীনশটস"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"সাধারণ বার্তাগুলি"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"সেট-আপ"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"স্টোরেজ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"হিন্ট"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"টগল করুন"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ডিভাইস কন্ট্রোল"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"কন্ট্রোল যোগ করতে অ্যাপ বেছে নিন"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g>টি কন্ট্রোল যোগ করা হয়েছে।</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g>টি কন্ট্রোল যোগ করা হয়েছে।</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#টি কন্ট্রোল যোগ করা হয়েছে।}one{#টি কন্ট্রোল যোগ করা হয়েছে।}other{#টি কন্ট্রোল যোগ করা হয়েছে।}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"সরানো হয়েছে"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"পছন্দসই হিসেবে চিহ্নিত করেছেন"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"পছন্দসই হিসেবে চিহ্নিত করেছেন, অবস্থান <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"টাইল যোগ করুন"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"টাইল যোগ করবেন না"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ব্যবহারকারী বেছে নিন"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g>টি অ্যাপ চালু আছে</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g>টি অ্যাপ চালু আছে</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{#টি অ্যাপ চালু আছে}one{#টি অ্যাপ চালু আছে}other{#টি অ্যাপ চালু আছে}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"নতুন তথ্য"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"অ্যাক্টিভ অ্যাপ"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"আপনি এমনকি ব্যবহার না করলেও, এইসব অ্যাপ অ্যাক্টিভ থাকে ও চলে। এগুলির কার্যকারিতা এটি উন্নত করে, তবে ব্যাটারির আয়ুর উপর প্রভাব ফেলতেও পারে।"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"অ্যালার্ম সেট করা হয়েছে"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ক্যামেরা ও মাইক্রোফোন বন্ধ আছে"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#টি বিজ্ঞপ্তি}one{#টি বিজ্ঞপ্তি}other{#টি বিজ্ঞপ্তি}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ব্রডকাস্ট করা হচ্ছে"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> সম্প্রচার বন্ধ করবেন?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"আপনি <xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করলে বা আউটপুট পরিবর্তন করলে, আপনার বর্তমান সম্প্রচার বন্ধ হয়ে যাবে"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করুন"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"আউটপুট পরিবর্তন করুন"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"অজানা"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
index 784d974..d70afc0 100644
--- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"বন্ধ আছে"</item>
     <item msgid="460891964396502657">"চালু আছে"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"অনুপলভ্য"</item>
+    <item msgid="8014986104355098744">"বন্ধ আছে"</item>
+    <item msgid="5966994759929723339">"চালু আছে"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index f4916bd..ad7f10b 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -205,11 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Senzori su isključeni"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Uklanjanje svih obavještenja."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Još <xliff:g id="NUMBER_1">%s</xliff:g> obavještenje unutra.</item>
-      <item quantity="few">Još <xliff:g id="NUMBER_1">%s</xliff:g> obavještenja unutra.</item>
-      <item quantity="other">Još <xliff:g id="NUMBER_1">%s</xliff:g> obavještenja unutra.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Još # obavještenje unutra.}one{Još # obavještenje unutra.}few{Još # obavještenja unutra.}other{Još # obavještenja unutra.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekran je zaključan u vodoravnom prikazu."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekran je zaključan u uspravnom prikazu."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Slika sa desertima"</string>
@@ -227,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatsko rotiranje"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko rotiranje ekrana"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Čuvar ekrana"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pristup kameri"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pristup mikrofonu"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupno"</string>
@@ -256,11 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Pristupna tačka"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Uključivanje…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Ušteda podataka uklj."</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d uređaj</item>
-      <item quantity="few">%d uređaja</item>
-      <item quantity="other">%d uređaja</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# uređaj}one{# uređaj}few{# uređaja}other{# uređaja}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Svjetiljka"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera u upotrebi"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Prijenos podataka na mobilnoj mreži"</string>
@@ -353,12 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Način rada za gosta"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Nalazite se u načinu rada za gosta"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dodavanjem novog korisnika napustit ćete način rada za gosta i izbrisati sve aplikacije i podatke iz trenutne sesije gosta."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut limit za broj korisnika"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
-      <item quantity="few">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
-      <item quantity="other">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Moguće je kreirati samo jednog korisnika.}one{Možete dodati najviše # korisnika}few{Možete dodati najviše # korisnika}other{Možete dodati najviše # korisnika}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Zaista želite ukloniti korisnika?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Sve aplikacije i podaci ovog korisnika bit će izbrisani."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Ukloni"</string>
@@ -544,16 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Podsjeti me"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Poništi"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Odgođeno za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d sat</item>
-      <item quantity="few">%d sata</item>
-      <item quantity="other">%d sati</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minuta</item>
-      <item quantity="few">%d minute</item>
-      <item quantity="other">%d minuta</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# h}=2{# h}one{# h}few{# h}other{# h}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# min}one{# min}few{# min}other{# min}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Ušteda baterije"</string>
     <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>
@@ -702,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Obavještenja"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Baterija"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Snimci ekrana"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Opće poruke"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant aplikacije"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Postavljanje"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Pohrana"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Savjeti"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant aplikacije"</string>
@@ -776,11 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"aktiviranje/deaktiviranje"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Odaberite aplikaciju da dodate kontrole"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one">Dodana je <xliff:g id="NUMBER_1">%s</xliff:g> kontrola.</item>
-      <item quantity="few">Dodane su <xliff:g id="NUMBER_1">%s</xliff:g> kontrole.</item>
-      <item quantity="other">Dodano je <xliff:g id="NUMBER_1">%s</xliff:g> kontrola.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodana je # kontrola.}one{Dodana je # kontrola.}few{Dodane su # kontrole.}other{Dodano je # kontrola.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u omiljeno"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano u omiljeno, pozicija <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -937,11 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj karticu"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nemoj dodati karticu"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Odaberite korisnika"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivna</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikacije su aktivne</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivno</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikacija je aktivna}one{# aplikacija je aktivna}few{# aplikacije su aktivne}other{# aplikacija je aktivno}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ove aplikacije su aktivne i pokrenute, čak i kada ih ne koristite. Ovim se poboljšava njihova funkcionalnost, ali može uticati i na vijek trajanja baterije."</string>
@@ -970,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavještenje}one{# obavještenje}few{# obavještenja}other{# obavještenja}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, trenutno emitiranje će se zaustaviti"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitiraj aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promijeni izlaz"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
index a057c48..b69b064 100644
--- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Isključeno"</item>
     <item msgid="460891964396502657">"Uključeno"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Nedostupno"</item>
+    <item msgid="8014986104355098744">"Isključeno"</item>
+    <item msgid="5966994759929723339">"Uključeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 497c201..f7441f3 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensors desactivats"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Esborra totes les notificacions."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> notificacions més a l\'interior.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> notificació més a l\'interior.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# notificació més a l\'interior.}other{# notificacions més a l\'interior.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"La pantalla està bloquejada en orientació horitzontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"La pantalla està bloquejada en orientació vertical."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Capsa de postres"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Gira automàticament"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Gira la pantalla automàticament"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicació"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Estalvi de pantalla"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accés a la càmera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accés al micròfon"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponible"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Punt d\'accés Wi-Fi"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"S\'està activant…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Economitzador activat"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d dispositius</item>
-      <item quantity="one">%d dispositiu</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispositiu}other{# dispositius}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Llanterna"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Càmera en ús"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Dades mòbils"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vols continuar amb la sessió?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Torna a començar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continua"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mode de convidat"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Estàs en mode de convidat"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"En afegir un usuari nou, se sortirà del mode de convidat i se suprimiran totes les aplicacions i dades de la sessió de convidat actual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"S\'ha assolit el límit d\'usuaris"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Pots afegir fins a <xliff:g id="COUNT">%d</xliff:g> usuaris.</item>
-      <item quantity="one">Només es pot crear un usuari.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Només es pot crear 1 usuari.}other{Pots afegir fins a # usuaris.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Vols suprimir l\'usuari?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Totes les aplicacions i les dades d\'aquest usuari se suprimiran."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Suprimeix"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Recorda-m\'ho"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Desfés"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"S\'ha posposat <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d hores</item>
-      <item quantity="one">%d hora</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minuts</item>
-      <item quantity="one">%d minut</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hora}=2{# hores}other{# hores}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minut}other{# minuts}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Estalvi de bateria"</string>
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Botó <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Inici"</string>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertes"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Bateria"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Captures de pantalla"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Missatges generals"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Aplicacions instantànies"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configuració"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Emmagatzematge"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Suggeriments"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Aplicacions instantànies"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"commuta"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controls de dispositius"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Selecciona l\'aplicació per afegir controls"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">S\'han afegit <xliff:g id="NUMBER_1">%s</xliff:g> controls.</item>
-      <item quantity="one">S\'ha afegit <xliff:g id="NUMBER_0">%s</xliff:g> control.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S\'ha afegit # control.}other{S\'han afegit # controls.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Suprimit"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Afegit als preferits"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Afegit als preferits, posició <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Afegeix la icona"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"No afegeixis la icona"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Selecciona un usuari"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplicacions estan actives</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicació està activa</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplicació està activa}other{# aplicacions estan actives}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informació nova"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicacions actives"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Aquestes aplicacions estan actives i executant-se, fins i tot quan no les utilitzes. Això en millora la funcionalitat, però també pot afectar la durada de la bateria."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Càmera i micròfon desactivats"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificació}other{# notificacions}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"S\'està emetent"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vols deixar d\'emetre <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emets <xliff:g id="SWITCHAPP">%1$s</xliff:g> o canvies la sortida, l\'emissió actual s\'aturarà"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emet <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Canvia la sortida"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconeguda"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
index 2d13e568..aaf19c7 100644
--- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Desactivat"</item>
     <item msgid="460891964396502657">"Activat"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"No disponible"</item>
+    <item msgid="8014986104355098744">"Desactivat"</item>
+    <item msgid="5966994759929723339">"Activat"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index ba36f5b..bb2ec59 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -205,12 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Vypnutí senzorů je aktivní"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Vymazat všechna oznámení."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"a ještě <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="few">Skupina obsahuje ještě <xliff:g id="NUMBER_1">%s</xliff:g> oznámení.</item>
-      <item quantity="many">Skupina obsahuje ještě <xliff:g id="NUMBER_1">%s</xliff:g> oznámení.</item>
-      <item quantity="other">Skupina obsahuje ještě <xliff:g id="NUMBER_1">%s</xliff:g> oznámení.</item>
-      <item quantity="one">Skupina obsahuje ještě <xliff:g id="NUMBER_0">%s</xliff:g> oznámení.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Skupina obsahuje ještě # oznámení.}few{Skupina obsahuje ještě # oznámení.}many{Skupina obsahuje ještě # oznámení.}other{Skupina obsahuje ještě # oznámení.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Obrazovka je uzamčena v orientaci na šířku."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Obrazovka je uzamčena v orientaci na výšku."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Pult se sladkostmi"</string>
@@ -228,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatické otáčení"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatické otočení obrazovky"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Poloha"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Spořič obrazovky"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Přístup k fotoaparátu"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Přístup k mikrofonu"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupné"</string>
@@ -257,12 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Zapínání…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Spořič dat zapnut"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="few">%d zařízení</item>
-      <item quantity="many">%d zařízení</item>
-      <item quantity="other">%d zařízení</item>
-      <item quantity="one">%d zařízení</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# zařízení}few{# zařízení}many{# zařízení}other{# zařízení}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Svítilna"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Fotoaparát se používá"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobilní data"</string>
@@ -355,13 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relaci pokračovat?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začít znovu"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ano, pokračovat"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Režim hosta"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Jste v režimu hosta"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Přidáním nového uživatele ukončíte režim hosta a smažete všechny aplikace a data z aktuální relace hosta."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Bylo dosaženo limitu uživatelů"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="few">Lze přidat až <xliff:g id="COUNT">%d</xliff:g> uživatele.</item>
-      <item quantity="many">Lze přidat až <xliff:g id="COUNT">%d</xliff:g> uživatele.</item>
-      <item quantity="other">Lze přidat až <xliff:g id="COUNT">%d</xliff:g> uživatelů.</item>
-      <item quantity="one">Lze vytvořit jen jednoho uživatele.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Lze vytvořit jen jednoho uživatele.}few{Přidat můžete maximálně # uživatele.}many{Přidat můžete maximálně # uživatele.}other{Přidat můžete maximálně # uživatelů.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Odstranit uživatele?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Veškeré aplikace a data tohoto uživatele budou smazána."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Odstranit"</string>
@@ -547,18 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Připomenutí"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Zpět"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Odloženo o <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="few">%d hodiny</item>
-      <item quantity="many">%d hodiny</item>
-      <item quantity="other">%d hodin</item>
-      <item quantity="one">%d hodina</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="few">%d minuty</item>
-      <item quantity="many">%d minuty</item>
-      <item quantity="other">%d minut</item>
-      <item quantity="one">%d minuta</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hodina}=2{# hodiny}few{# hodiny}many{# hodiny}other{# hodin}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuta}few{# minuty}many{# minuty}other{# minut}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Spořič baterie"</string>
     <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>
@@ -707,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Upozornění"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Baterie"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Snímky obrazovek"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Všeobecné zprávy"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Okamžité aplikace"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Nastavit"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Úložiště"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Tipy"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Okamžité aplikace"</string>
@@ -781,12 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"přepnout"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Ovládání zařízení"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Vyberte aplikaci, pro kterou chcete přidat ovládací prvky"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="few">Byly přidány <xliff:g id="NUMBER_1">%s</xliff:g> ovládací prvky.</item>
-      <item quantity="many">Bylo přidáno <xliff:g id="NUMBER_1">%s</xliff:g> ovládacího prvku.</item>
-      <item quantity="other">Bylo přidáno <xliff:g id="NUMBER_1">%s</xliff:g> ovládacích prvků.</item>
-      <item quantity="one">Byl přidán <xliff:g id="NUMBER_0">%s</xliff:g> ovládací prvek.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Byl přidán # ovládací prvek.}few{Byly přidány # ovládací prvky.}many{Bylo přidáno # ovládacího prvku.}other{Bylo přidáno # ovládacích prvků.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Odstraněno"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Přidáno do oblíbených"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Přidáno do oblíbených na pozici <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -943,12 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Přidat dlaždici"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepřidávat dlaždici"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Zvolte uživatele"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikace jsou aktivní</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> aplikace je aktivních</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikací je aktivních</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikace je aktivní</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikace je aktivní}few{# aplikace jsou aktivní}many{# aplikace je aktivních}other{# aplikací je aktivních}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nové informace"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivní aplikace"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Tyto aplikace jsou spuštěné a aktivní, i když je nepoužíváte. Zlepšuje to jejich funkčnost, ale může to mít dopad na výdrž baterie."</string>
@@ -977,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Je nastaven budík"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparát a mikrofon jsou vypnuté"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# oznámení}few{# oznámení}many{# oznámení}other{# oznámení}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysílání"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zastavit vysílání v aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Pokud budete vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g> nebo změníte výstup, aktuální vysílání se zastaví"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Změna výstupu"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznámé"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index 2af84d9..64e83e0 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Vypnuto"</item>
     <item msgid="460891964396502657">"Zapnuto"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Nedostupné"</item>
+    <item msgid="8014986104355098744">"Vypnuto"</item>
+    <item msgid="5966994759929723339">"Zapnuto"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index fb9212a..c9722eb 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensorer er slået fra"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Ryd alle notifikationer."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"<xliff:g id="NUMBER">%s</xliff:g> mere"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> notifikation mere i gruppen.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> notifikationer mere i gruppen.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# notifikation mere i gruppen.}one{# notifikation mere i gruppen.}other{# notifikationer mere i gruppen.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Skærmen er nu låst i liggende retning."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Skærmen er nu låst i stående format."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessertcase"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Roter automatisk"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Roter skærmen automatisk"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokation"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Pauseskærm"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameraadgang"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonadgang"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tilgængelig"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Aktiverer…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Datasparefunktion er slået til"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d enhed</item>
-      <item quantity="other">%d enheder</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# enhed}one{# enhed}other{# enheder}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lommelygte"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kameraet er i brug"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobildata"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsætte din session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start forfra"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsæt"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gæstetilstand"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Gæstetilstand er aktiveret"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Hvis du tilføjer en ny bruger, deaktiveres gæstetilstanden, og alle apps og data slettes fra den aktuelle gæstesession."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Grænsen for antal brugere er nået"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Du kan tilføje op til <xliff:g id="COUNT">%d</xliff:g> bruger.</item>
-      <item quantity="other">Du kan tilføje op til <xliff:g id="COUNT">%d</xliff:g> brugere.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Der kan kun oprettes én bruger.}one{Du kan tilføje op til # bruger}other{Du kan tilføje op til # brugere}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Vil du fjerne brugeren?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Alle apps og data for denne bruger slettes."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Fjern"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Påmind mig"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Fortryd"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Udsat i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d time</item>
-      <item quantity="other">%d timer</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minut</item>
-      <item quantity="other">%d minutter</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# time}=2{# timer}one{# time}other{# timer}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minut}one{# minut}other{# minutter}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Batterisparefunktion"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Underretninger"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batteri"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Screenshots"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Generelle meddelelser"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Konfiguration"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Lagerplads"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Tips"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"slå til/fra"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Enhedsstyring"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Vælg en app for at tilføje styring"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> styring er tilføjet.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> styring er tilføjet.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# styringselement er tilføjet.}one{# styringselement er tilføjet.}other{# styringselementer er tilføjet.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Angivet som favorit"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Angivet som favorit. Position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tilføj handlingsfelt"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Tilføj ikke felt"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Vælg bruger"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app er aktiv</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps er aktive</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app er aktiv}one{# app er aktiv}other{# apps er aktive}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nye oplysninger"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive apps"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Disse apps er aktive og kører, også når du ikke bruger dem. Det forbedrer deres funktionalitet, men det kan også påvirke batteritiden."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er indstillet"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er slået fra"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikation}one{# notifikation}other{# notifikationer}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Udsender"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop udsendelsen <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du udsender <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller skifter output, stopper din aktuelle udsendelse"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Udsend <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Skift output"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ukendt"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml
index 0fe06b3..f0132dc 100644
--- a/packages/SystemUI/res/values-da/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Fra"</item>
     <item msgid="460891964396502657">"Til"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Ikke tilgængelig"</item>
+    <item msgid="8014986104355098744">"Fra"</item>
+    <item msgid="5966994759929723339">"Til"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 97e4038..169e475 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"\"Sensoren aus\" ist aktiv"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Alle Benachrichtigungen löschen"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> weitere Benachrichtigungen vorhanden.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> weitere Benachrichtigung vorhanden.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# weitere Benachrichtigung vorhanden.}other{# weitere Benachrichtigungen vorhanden.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Bildschirm bleibt im Querformat."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Bildschirm bleibt im Hochformat."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessertbehälter"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. drehen"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Bildschirm automatisch drehen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Standort"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Bildschirmschoner"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kamerazugriff"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonzugriff"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Verfügbar"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Wird aktiviert…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Datensparmodus an"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d Geräte</item>
-      <item quantity="one">%d Gerät</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# Gerät}other{# Geräte}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Taschenlampe"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera wird verwendet"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobile Daten"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Möchtest du deine Sitzung fortsetzen?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Neu starten"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, weiter"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gastmodus"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Du befindest dich im Gastmodus"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Durch Hinzufügen eines neuen Nutzers wird der Gastmodus beendet und alle Apps und Daten der aktuellen Gastsitzung werden gelöscht."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Nutzerlimit erreicht"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Du kannst bis zu <xliff:g id="COUNT">%d</xliff:g> Nutzer hinzufügen.</item>
-      <item quantity="one">Es kann nur ein Nutzer erstellt werden.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Es kann nur ein Nutzer erstellt werden.}other{Du kannst bis zu # Nutzer hinzufügen.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Nutzer entfernen?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Alle Apps und Daten dieses Nutzers werden gelöscht."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Entfernen"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Erinnern"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Rückgängig machen"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Erinnerung in <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d Stunden</item>
-      <item quantity="one">%d Stunde</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d Minuten</item>
-      <item quantity="one">%d Minute</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# Stunde}=2{# Stunden}other{# Stunden}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# Minute}other{# Minuten}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Energiesparmodus"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Benachrichtigungen"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Akku"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Screenshots"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Nachrichten"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Android Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Einrichtung"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Speicher"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Hinweise"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"Wechseln"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Gerätesteuerung"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"App zum Hinzufügen von Steuerelementen auswählen"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> Steuerelemente hinzugefügt.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> Steuerelement hinzugefügt.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# Steuerelement hinzugefügt.}other{# Steuerelemente hinzugefügt.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Entfernt"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Zu Favoriten hinzugefügt"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Zu Favoriten hinzugefügt, Position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Hinzufügen"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nicht hinzufügen"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Nutzer auswählen"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> Apps sind aktiv</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> App ist aktiv</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# App ist aktiv}other{# Apps sind aktiv}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Neue Informationen"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive Apps"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Diese Apps sind aktiv und werden auch dann ausgeführt, wenn du sie gerade nicht verwendest. Dies wird für einige ihrer Funktionen benötigt, kann aber auch die Akkulaufzeit beeinträchtigen."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wecker gestellt"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera und Mikrofon ausgeschaltet"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# Benachrichtigung}other{# Benachrichtigungen}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Übertragung läuft"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> nicht mehr streamen?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Wenn du <xliff:g id="SWITCHAPP">%1$s</xliff:g> streamst oder die Ausgabe änderst, wird dein aktueller Stream beendet"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> streamen"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ausgabe ändern"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unbekannt"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml
index ba610b3..bc50e16 100644
--- a/packages/SystemUI/res/values-de/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Aus"</item>
     <item msgid="460891964396502657">"An"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Nicht verfügbar"</item>
+    <item msgid="8014986104355098744">"Aus"</item>
+    <item msgid="5966994759929723339">"An"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 695d86f..fc03b57 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Απενεργοποίηση αισθητήρων ενεργή"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Διαγραφή όλων των ειδοποιήσεων."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> επιπλέον ειδοποιήσεις εντός της ομάδας.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> επιπλέον ειδοποίηση εντός της ομάδας.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# ακόμη ειδοποίηση μέσα στην ομάδα.}other{# ακόμη ειδοποιήσεις μέσα στην ομάδα.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Η οθόνη έχει κλειδωθεί σε οριζόντιο προσανατολισμό."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Η οθόνη έχει κλειδωθεί σε κατακόρυφο προσανατολισμό."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Επιδόρπιο"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Αυτόματη περιστροφή"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Αυτόματη περιστροφή οθόνης"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Τοποθεσία"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Προφύλαξη οθόνης"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Πρόσβαση κάμερας"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Πρόσβαση μικροφώνου"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Διαθέσιμη"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Σημείο πρόσβασης Wi-Fi"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Ενεργοποίηση…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Εξοικ. δεδομ. ενεργή"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d συσκευές</item>
-      <item quantity="one">%d συσκευή</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# συσκευή}other{# συσκευές}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Φακός"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Η κάμερα χρησιμοποιείται"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Δεδομένα κινητής τηλεφωνίας"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Θέλετε να συνεχίσετε την περίοδο σύνδεσής σας;"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Έναρξη από την αρχή"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ναι, συνέχεια"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Λειτουργία επισκέπτη"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Βρίσκεστε σε λειτουργία επισκέπτη"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Με την προσθήκη νέου χρήστη θα γίνει έξοδος από τη λειτουργία επισκέπτη και θα διαγραφούν όλες οι εφαρμογές και τα δεδομένα από την τρέχουσα περίοδο σύνδεσης επισκέπτη."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Συμπληρώθηκε το όριο χρηστών"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Μπορείτε να προσθέσετε έως <xliff:g id="COUNT">%d</xliff:g> χρήστες.</item>
-      <item quantity="one">Είναι δυνατή η δημιουργία μόνο ενός χρήστη.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Είναι δυνατή η δημιουργία μόνο ενός χρήστη.}other{Μπορείτε να προσθέσετε έως και # χρήστες}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Κατάργηση χρήστη;"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Όλες οι εφαρμογές και τα δεδομένα αυτού του χρήστη θα διαγραφούν."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Κατάργηση"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Να γίνει υπενθύμιση"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Αναίρεση"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Σε αναβολή για <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d ώρες</item>
-      <item quantity="one">%d ώρα</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d λεπτά</item>
-      <item quantity="one">%d λεπτό</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ώρα}=2{# ώρες}other{# ώρες}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# λεπτό}other{# λεπτά}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Εξοικονόμηση μπαταρίας"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Ειδοποιήσεις"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Μπαταρία"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Στιγμιότυπα οθόνης"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Γενικά μηνύματα"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Εφαρμογές"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Ρύθμιση"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Αποθηκευτικός χώρος"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Συμβουλές"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Εφαρμογές"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"εναλλαγή"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Στοιχεία ελέγχου συσκευής"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Επιλογή εφαρμογής για προσθήκη στοιχείων ελέγχου"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">Προστέθηκαν <xliff:g id="NUMBER_1">%s</xliff:g> στοιχεία ελέγχου.</item>
-      <item quantity="one">Προστέθηκε <xliff:g id="NUMBER_0">%s</xliff:g> στοιχείο ελέγχου.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Προστέθηκε # στοιχείο ελέγχου.}other{Προστέθηκαν # στοιχεία ελέγχου.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Καταργήθηκε"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Προστέθηκε στα αγαπημένα"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Προστέθηκε στα αγαπημένα, στη θέση <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Προσθήκη πλακιδίου"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Χωρίς προσθ. πλακιδ."</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Επιλογή χρήστη"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> εφαρμογές είναι ενεργές</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> εφαρμογή είναι ενεργή</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# εφαρμογή είναι ενεργή}other{# εφαρμογές είναι ενεργές}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Νέες πληροφορίες"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ενεργές εφαρμογές"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Αυτές οι εφαρμογές είναι ενεργές και εκτελούνται, ακόμη και αν δεν τις χρησιμοποιείτε. Αυτό βελτιώνει τη λειτουργικότητά τους, αλλά μπορεί να επηρεάσει τη διάρκεια ζωής της μπαταρίας."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Το ξυπνητήρι ρυθμίστηκε"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Η κάμερα και το μικρόφωνο έχουν απενεργοποιηθεί"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ειδοποίηση}other{# ειδοποιήσεις}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Μετάδοση"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Διακοπή μετάδοσης με την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Εάν κάνετε μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g> ή αλλάξετε την έξοδο, η τρέχουσα μετάδοση θα σταματήσει"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Αλλαγή εξόδου"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Άγνωστο"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml
index 74c091e..352af39 100644
--- a/packages/SystemUI/res/values-el/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Ανενεργή"</item>
     <item msgid="460891964396502657">"Ενεργή"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Μη διαθέσιμο"</item>
+    <item msgid="8014986104355098744">"Ανενεργό"</item>
+    <item msgid="5966994759929723339">"Ενεργό"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 58d0697..89b00b4 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensors off active"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Clear all notifications."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+<xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> more notifications inside.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> more notification inside.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# more notification inside.}other{# more notifications inside.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Screen is locked in landscape orientation."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Screen is locked in portrait orientation."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Camera access"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mic access"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Turning on…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Data Saver is on"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d devices</item>
-      <item quantity="one">%d device</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# device}other{# devices}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Torch"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Camera in use"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobile data"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
-      <item quantity="one">Only one user can be created.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Only one user can be created.}other{You can add up to # users.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Remove user?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"All apps and data of this user will be deleted."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Remove"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Remind me"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Undo"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d hours</item>
-      <item quantity="one">%d hour</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutes</item>
-      <item quantity="one">%d minute</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hour}=2{# hours}other{# hours}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minute}other{# minutes}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Battery Saver"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alerts"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Battery"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Screenshots"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"General Messages"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Setup"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Storage"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Hints"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"toggle"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Choose app to add controls"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> control added.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Select user"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps are active</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app is active</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app is active}other{# apps are active}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"These apps are active and running, even when you’re not using them. This improves their functionality, but it may also affect battery life."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
index 6f8cfb6..56cdbef 100644
--- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Off"</item>
     <item msgid="460891964396502657">"On"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Unavailable"</item>
+    <item msgid="8014986104355098744">"Off"</item>
+    <item msgid="5966994759929723339">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index b68d6eeb..0519c96 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensors off active"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Clear all notifications."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+<xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> more notifications inside.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> more notification inside.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# more notification inside.}other{# more notifications inside.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Screen is locked in landscape orientation."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Screen is locked in portrait orientation."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Camera access"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mic access"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Turning on…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Data Saver is on"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d devices</item>
-      <item quantity="one">%d device</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# device}other{# devices}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Flashlight"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Camera in use"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobile data"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
-      <item quantity="one">Only one user can be created.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Only one user can be created.}other{You can add up to # users.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Remove user?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"All apps and data of this user will be deleted."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Remove"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Remind me"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Undo"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d hours</item>
-      <item quantity="one">%d hour</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutes</item>
-      <item quantity="one">%d minute</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hour}=2{# hours}other{# hours}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minute}other{# minutes}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Battery Saver"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alerts"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Battery"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Screenshots"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"General Messages"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Setup"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Storage"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Hints"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"toggle"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Choose app to add controls"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> control added.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Select user"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps are active</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app is active</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app is active}other{# apps are active}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"These apps are active and running, even when you’re not using them. This improves their functionality, but it may also affect battery life."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
index 6f8cfb6..56cdbef 100644
--- a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Off"</item>
     <item msgid="460891964396502657">"On"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Unavailable"</item>
+    <item msgid="8014986104355098744">"Off"</item>
+    <item msgid="5966994759929723339">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 58d0697..89b00b4 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensors off active"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Clear all notifications."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+<xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> more notifications inside.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> more notification inside.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# more notification inside.}other{# more notifications inside.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Screen is locked in landscape orientation."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Screen is locked in portrait orientation."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Camera access"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mic access"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Turning on…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Data Saver is on"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d devices</item>
-      <item quantity="one">%d device</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# device}other{# devices}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Torch"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Camera in use"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobile data"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
-      <item quantity="one">Only one user can be created.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Only one user can be created.}other{You can add up to # users.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Remove user?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"All apps and data of this user will be deleted."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Remove"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Remind me"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Undo"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d hours</item>
-      <item quantity="one">%d hour</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutes</item>
-      <item quantity="one">%d minute</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hour}=2{# hours}other{# hours}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minute}other{# minutes}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Battery Saver"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alerts"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Battery"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Screenshots"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"General Messages"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Setup"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Storage"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Hints"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"toggle"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Choose app to add controls"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> control added.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Select user"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps are active</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app is active</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app is active}other{# apps are active}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"These apps are active and running, even when you’re not using them. This improves their functionality, but it may also affect battery life."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
index 6f8cfb6..56cdbef 100644
--- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Off"</item>
     <item msgid="460891964396502657">"On"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Unavailable"</item>
+    <item msgid="8014986104355098744">"Off"</item>
+    <item msgid="5966994759929723339">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 58d0697..89b00b4 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensors off active"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Clear all notifications."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+<xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> more notifications inside.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> more notification inside.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# more notification inside.}other{# more notifications inside.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Screen is locked in landscape orientation."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Screen is locked in portrait orientation."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Auto-rotate"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Auto-rotate screen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Location"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Camera access"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mic access"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Turning on…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Data Saver is on"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d devices</item>
-      <item quantity="one">%d device</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# device}other{# devices}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Torch"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Camera in use"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobile data"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
-      <item quantity="one">Only one user can be created.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Only one user can be created.}other{You can add up to # users.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Remove user?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"All apps and data of this user will be deleted."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Remove"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Remind me"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Undo"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d hours</item>
-      <item quantity="one">%d hour</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutes</item>
-      <item quantity="one">%d minute</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hour}=2{# hours}other{# hours}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minute}other{# minutes}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Battery Saver"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alerts"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Battery"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Screenshots"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"General Messages"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Setup"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Storage"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Hints"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"toggle"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Device controls"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Choose app to add controls"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> control added.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Add tile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Do not add tile"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Select user"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps are active</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app is active</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app is active}other{# apps are active}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"New information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Active apps"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"These apps are active and running, even when you’re not using them. This improves their functionality, but it may also affect battery life."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm set"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Change output"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
index 6f8cfb6..56cdbef 100644
--- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Off"</item>
     <item msgid="460891964396502657">"On"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Unavailable"</item>
+    <item msgid="8014986104355098744">"Off"</item>
+    <item msgid="5966994759929723339">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 7fde88c..a341d59 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‏‏‏‎Sensors off active‎‏‎‎‏‎"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‏‎‎‎‎‎Clear all notifications.‎‏‎‎‏‎"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎+ ‎‏‎‎‏‏‎<xliff:g id="NUMBER">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%s</xliff:g>‎‏‎‎‏‏‏‎ more notifications inside.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%s</xliff:g>‎‏‎‎‏‏‏‎ more notification inside.‎‏‎‎‏‎</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎# more notification inside.‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎# more notifications inside.‎‏‎‎‏‎}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎Screen is locked in landscape orientation.‎‏‎‎‏‎"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎Screen is locked in portrait orientation.‎‏‎‎‏‎"</string>
     <string name="dessert_case" msgid="9104973640704357717">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎Dessert Case‎‏‎‎‏‎"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‎Auto-rotate‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎Auto-rotate screen‎‏‎‎‏‎"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎Location‎‏‎‎‏‎"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎Screen saver‎‏‎‎‏‎"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎‏‏‎Camera access‎‏‎‎‏‎"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎Mic access‎‏‎‎‏‎"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‎‎Available‎‏‎‎‏‎"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎‎Hotspot‎‏‎‎‏‎"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎‎Turning on…‎‏‎‎‏‎"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‎‎Data Saver is on‎‏‎‎‏‎"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‎‎‎%d devices‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‎‎‎%d device‎‏‎‎‏‎</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‏‎‏‎‎‎‎‏‎# device‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‏‎‏‎‎‎‎‏‎# devices‎‏‎‎‏‎}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎Flashlight‎‏‎‎‏‎"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎Camera in use‎‏‎‎‏‎"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎Mobile data‎‏‎‎‏‎"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎Do you want to continue your session?‎‏‎‎‏‎"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‎Start over‎‏‎‎‏‎"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎Yes, continue‎‏‎‎‏‎"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎Guest mode‎‏‎‎‏‎"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎You are in guest mode‎‏‎‎‏‎"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Adding a new user will exit guest mode and delete all apps and data from the current guest session.‎‏‎‎‏‎"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎User limit reached‎‏‎‎‏‎"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎You can add up to ‎‏‎‎‏‏‎<xliff:g id="COUNT">%d</xliff:g>‎‏‎‎‏‏‏‎ users.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎Only one user can be created.‎‏‎‎‏‎</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎Only one user can be created.‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎You can add up to # users.‎‏‎‎‏‎}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎Remove user?‎‏‎‎‏‎"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‏‎‎‏‎All apps and data of this user will be deleted.‎‏‎‎‏‎"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎‎‎‎Remove‎‏‎‎‏‎"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‏‎‏‏‎Remind me‎‏‎‎‏‎"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎Undo‎‏‎‎‏‎"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎Snoozed for ‎‏‎‎‏‏‎<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎%d hours‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎%d hour‎‏‎‎‏‎</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎%d minutes‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎%d minute‎‏‎‎‏‎</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎# hour‎‏‎‎‏‎}=2{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎# hours‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎# hours‎‏‎‎‏‎}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎# minute‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎# minutes‎‏‎‎‏‎}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎Battery Saver‎‏‎‎‏‎"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎Alerts‎‏‎‎‏‎"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎Battery‎‏‎‎‏‎"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‎Screenshots‎‏‎‎‏‎"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‎‏‏‎‎‏‏‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎General Messages‎‏‎‎‏‎"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎‎Instant Apps‎‏‎‎‏‎"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎Setup‎‏‎‎‏‎"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎Storage‎‏‎‎‏‎"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‎Hints‎‏‎‎‏‎"</string>
     <string name="instant_apps" msgid="8337185853050247304">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎Instant Apps‎‏‎‎‏‎"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎toggle‎‏‎‎‏‎"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‎‎‎‎‏‎Device controls‎‏‎‎‏‎"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎Choose app to add controls‎‏‎‎‏‎"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%s</xliff:g>‎‏‎‎‏‏‏‎ controls added.‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%s</xliff:g>‎‏‎‎‏‏‏‎ control added.‎‏‎‎‏‎</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎# control added.‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎# controls added.‎‏‎‎‏‎}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎Removed‎‏‎‎‏‎"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎Favorited‎‏‎‎‏‎"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‎Favorited, position ‎‏‎‎‏‏‎<xliff:g id="NUMBER">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎Add tile‎‏‎‎‏‎"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎Do not add tile‎‏‎‎‏‎"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎Select user‎‏‎‎‏‎"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%s</xliff:g>‎‏‎‎‏‏‏‎ apps are active‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%s</xliff:g>‎‏‎‎‏‏‏‎ app is active‎‏‎‎‏‎</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎# app is active‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎# apps are active‎‏‎‎‏‎}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎New information‎‏‎‎‏‎"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎Active apps‎‏‎‎‏‎"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎These apps are active and running, even when you’re not using them. This improves their functionality, but it may also affect battery life.‎‏‎‎‏‎"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‎Alarm set‎‏‎‎‏‎"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎Camera and mic are off‎‏‎‎‏‎"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notification‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notifications‎‏‎‎‏‎}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‎Broadcasting‎‏‎‎‏‎"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎Stop broadcasting ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎If you broadcast ‎‏‎‎‏‏‎<xliff:g id="SWITCHAPP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ or change the output, your current broadcast will stop‎‏‎‎‏‎"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‏‎‏‎Broadcast ‎‏‎‎‏‏‎<xliff:g id="SWITCHAPP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎Change output‎‏‎‎‏‎"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎Unknown‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
index 99ef50c..3a8e34c 100644
--- a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎Off‎‏‎‎‏‎"</item>
     <item msgid="460891964396502657">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎On‎‏‎‎‏‎"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎Unavailable‎‏‎‎‏‎"</item>
+    <item msgid="8014986104355098744">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‎‎‎Off‎‏‎‎‏‎"</item>
+    <item msgid="5966994759929723339">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎On‎‏‎‎‏‎"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index e0fa6fd..c759542 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensores desactivados sí"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Eliminar todas las notificaciones"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"<xliff:g id="NUMBER">%s</xliff:g> más"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> notificaciones más en el grupo.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> notificación más en el grupo.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# notificación más en el grupo.}other{# notificaciones más en el grupo.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"La pantalla está bloqueada en modo horizontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"La pantalla está bloqueada en modo vertical."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Caja para postres"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Girar la pantalla automáticamente"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Protector de pantalla"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acceso a la cámara"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acceso al mic."</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponible"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Activando…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Ahorro de datos act."</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d dispositivos</item>
-      <item quantity="one">%d dispositivo</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispositivo}other{# dispositivos}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Linterna"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Cámara en uso"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Datos móviles"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres retomar la sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo de Invitado"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Estás en el modo de invitado"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si agregas un usuario nuevo, se desactivará el modo de invitado y se borrarán todas las apps y los datos de la sesión de invitado actual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Alcanzaste el límite de usuarios"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Puedes agregar hasta <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
-      <item quantity="one">Solo se puede crear un usuario.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Solo se puede crear un usuario.}other{Puedes agregar hasta # usuarios.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"¿Confirmas que quieres quitar el usuario?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Se borrarán todas las aplicaciones y los datos de este usuario."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Quitar"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Recuérdame"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Deshacer"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Posponer <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d horas</item>
-      <item quantity="one">%d hora</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutos</item>
-      <item quantity="one">%d minuto</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hora}=2{# horas}other{# horas}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuto}other{# minutos}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Ahorro de batería"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertas"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batería"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Capturas de pantalla"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mensajes generales"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Apps instantáneas"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configuración"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Almacenamiento"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Sugerencias"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Apps instantáneas"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activar o desactivar"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controles de dispositivos"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Elige la app para agregar los controles"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">Se agregaron <xliff:g id="NUMBER_1">%s</xliff:g> controles.</item>
-      <item quantity="one">Se agregó <xliff:g id="NUMBER_0">%s</xliff:g> control.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Se agregó # control.}other{Se agregaron # controles.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Quitados"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Está en favoritos"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Está en favoritos en la posición <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Agregar tarjeta"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"No agregar tarjeta"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Seleccionar usuario"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps están activas</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app está activa</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app está activa}other{# apps están activas}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nueva información"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps activas"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Estas apps están activas y en ejecución, incluso mientras no las usas. Esto mejora su funcionalidad, pero también afecta la duración de batería."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Se estableció la alarma"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están apagados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificaciones}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitiendo"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Quieres dejar de transmitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si transmites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu transmisión actual se detendrá"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia la salida"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconocido"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
index abcec7f..44e9cf2 100644
--- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Desactivado"</item>
     <item msgid="460891964396502657">"Sí"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"No disponible"</item>
+    <item msgid="8014986104355098744">"No"</item>
+    <item msgid="5966994759929723339">"Sí"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 098db7f..aff8998 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensores desactivados"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Borrar todas las notificaciones"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"<xliff:g id="NUMBER">%s</xliff:g> más"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> notificaciones más dentro.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> notificación más dentro.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# notificación más en el grupo.}other{# notificaciones más en el grupo.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"La pantalla está bloqueada en modo horizontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"La pantalla está bloqueada en modo vertical."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Caja para postres"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Girar pantalla automáticamente"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Salvapantallas"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acceso a cámara"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acceso al micro"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponible"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Compartir Internet"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Activando…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Ahorro de datos activado"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d dispositivos</item>
-      <item quantity="one">%d dispositivo</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispositivo}other{# dispositivos}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Linterna"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Cámara en uso"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Datos móviles"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres continuar con tu sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo Invitado"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Estás en modo Invitado"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si añades un nuevo usuario, saldrás del modo Invitado y se eliminarán todas las aplicaciones y datos de la sesión de invitado actual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Has alcanzado el límite de usuarios"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Puedes añadir hasta <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
-      <item quantity="one">Solo se puede crear un usuario.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Solo se puede crear un usuario.}other{Puedes añadir # usuarios como máximo.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"¿Quitar usuario?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Se eliminarán todas las aplicaciones y datos de este usuario."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Quitar"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Recordar"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Deshacer"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Volverá a mostrarse en <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d horas</item>
-      <item quantity="one">%d hora</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutos</item>
-      <item quantity="one">%d minuto</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hora}=2{# horas}other{# horas}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuto}other{# minutos}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Ahorro de batería"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertas"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batería"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Capturas de pantalla"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mensajes generales"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Aplicaciones Instantáneas"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configuración"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Almacenamiento"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Sugerencias"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Aplicaciones Instantáneas"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activar/desactivar"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Elige una aplicación para añadir controles"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">Se han añadido <xliff:g id="NUMBER_1">%s</xliff:g> controles.</item>
-      <item quantity="one">Se ha añadido <xliff:g id="NUMBER_0">%s</xliff:g> control.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control añadido.}other{# controles añadidos.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Quitado"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Añadido a favoritos"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Añadido a favoritos (posición <xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Añadir recuadro"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"No añadir recuadro"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Selecciona un usuario"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplicaciones activas</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicación activa</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplicación activa}other{# aplicaciones activas}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Información nueva"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicaciones activas"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Estas aplicaciones están activas y en funcionamiento, incluso aunque no las estés usando. Esto mejora su funcionalidad, pero también puede afectar a la duración de la batería."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma añadida"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están desactivados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificaciones}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiendo"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Dejar de emitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu emisión actual se detendrá"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambiar salida"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconocido"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index 78c7669..d3e7c8b 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Desactivado"</item>
     <item msgid="460891964396502657">"Activado"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"No disponible"</item>
+    <item msgid="8014986104355098744">"Desactivado"</item>
+    <item msgid="5966994759929723339">"Activado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index efad53fd..e11a165 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Valik Andurid on väljas on aktiivne"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Kustuta kõik teatised."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Sees on veel <xliff:g id="NUMBER_1">%s</xliff:g> märguannet.</item>
-      <item quantity="one">Sees on veel <xliff:g id="NUMBER_0">%s</xliff:g> märguanne.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Sees on veel # märguanne.}other{Sees on veel # märguannet.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekraan on lukustatud horisontaalsuunas."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekraan on lukustatud vertikaalsuunas."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Maiustusekorv"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. pööramine"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Kuva automaatne pööramine"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Asukoht"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Ekraanisäästja"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Juurdepääs kaamerale"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Juurdepääs mikrofonile"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Saadaval"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Kuumkoht"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Sisselülitamine …"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Andmem. säästja sees"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d seadet</item>
-      <item quantity="one">%d seade</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# seade}other{# seadet}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Taskulamp"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kasutusel olev kaamera"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobiilne andmeside"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Kas soovite seansiga jätkata?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Alusta uuesti"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Jah, jätka"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Külalisrežiim"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Olete külalisrežiimis"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Uue kasutaja lisamisel suletakse külalisrežiim ning praeguse külastajaseansi rakendused ja andmed kustutatakse."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Kasutajate limiit on täis"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Võite lisada kuni <xliff:g id="COUNT">%d</xliff:g> kasutajat.</item>
-      <item quantity="one">Luua saab ainult ühe kasutaja.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Luua saab ainult ühe kasutaja.}other{Saate lisada kuni # kasutajat}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Kas eemaldada kasutaja?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Kasutaja kõik rakendused ja andmed kustutatakse."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Eemalda"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Tuleta mulle meelde"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Võta tagasi"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Edasi lükatud <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d tundi</item>
-      <item quantity="one">%d tund</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutit</item>
-      <item quantity="one">%d minut</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# tund}=2{# tundi}other{# tundi}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minut}other{# minutit}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Akusäästja"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Hoiatused"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Aku"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Ekraanipildid"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Üldised sõnumid"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Installimata avatavad rakendused"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Seadistamine"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Salvestusruum"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Vihjed"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Installimata avatavad rakendused"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"lülita"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Seadmete juhikud"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Valige juhtelementide lisamiseks rakendus"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">Lisati <xliff:g id="NUMBER_1">%s</xliff:g> juhtnuppu.</item>
-      <item quantity="one">Lisati <xliff:g id="NUMBER_0">%s</xliff:g> juhtnupp.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Lisati # juhtnupp.}other{Lisati # juhtnuppu.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Eemaldatud"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisatud lemmikuks"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisatud lemmikuks, positsioon <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Lisa paan"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ära lisa paani"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Kasutaja valimine"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> rakendust on aktiivsed</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> rakendus on aktiivne</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# rakendus on aktiivne}other{# rakendust on aktiivsed}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Uus teave"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiivsed rakendused"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Need rakendused on aktiivsed ja neid käitatakse isegi siis, kui te neid ei kasuta. Tänu sellele toimivad need paremini, kuid see võib mõjutada aku tööiga."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm on määratud"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kaamera ja mikrofon on välja lülitatud"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# märguanne}other{# märguannet}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Edastamine"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Kas peatada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> ülekandmine?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kui kannate rakendust <xliff:g id="SWITCHAPP">%1$s</xliff:g> üle või muudate väljundit, peatatakse teie praegune ülekanne"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Rakenduse <xliff:g id="SWITCHAPP">%1$s</xliff:g> ülekandmine"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Väljundi muutmine"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tundmatu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml
index 29895d1..07eddef 100644
--- a/packages/SystemUI/res/values-et/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Väljas"</item>
     <item msgid="460891964396502657">"Sees"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Pole saadaval"</item>
+    <item msgid="8014986104355098744">"Väljas"</item>
+    <item msgid="5966994759929723339">"Sees"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index ce67b7d..35142b9 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Aktibo dago sentsore guztiak desaktibatzen dituen aukera"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Garbitu jakinarazpen guztiak."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Beste <xliff:g id="NUMBER_1">%s</xliff:g> jakinarazpen daude barnean.</item>
-      <item quantity="one">Beste <xliff:g id="NUMBER_0">%s</xliff:g> jakinarazpen daude barnean.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Beste # jakinarazpen dago barnean.}other{Beste # jakinarazpen daude barnean.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Pantaila horizontalki blokeatuta dago."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Pantaila bertikalki blokeatuta dago."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Postreen kutxa"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Biratze automatikoa"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Biratu pantaila automatikoki"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Kokapena"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Pantaila-babeslea"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kamera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonoa"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Baimenduta"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Wifi-gunea"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Aktibatzen…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Datu-aurrezlea aktibatuta"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d gailu</item>
-      <item quantity="one">%d gailu</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# gailu}other{# gailu}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Linterna"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera abian da"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Datu-konexioa"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Saioarekin jarraitu nahi duzu?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Hasi berriro"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Bai, jarraitu"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gonbidatu modua"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Gonbidatu moduan zaude"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Beste erabiltzaile bat gehituz gero, gonbidatu modua itxiko da eta oraingo gonbidatuentzako saioko aplikazio eta datu guztiak ezabatuko dira."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Erabiltzaile-mugara iritsi zara"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Gehienez, <xliff:g id="COUNT">%d</xliff:g> erabiltzaile gehi ditzakezu.</item>
-      <item quantity="one">Erabiltzaile bakarra sor daiteke.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Erabiltzaile bakarra sor daiteke.}other{# erabiltzaile gehi ditzakezu gehienez.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Erabiltzailea kendu nahi duzu?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Erabiltzailearen aplikazio eta datu guztiak ezabatuko dira."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Kendu"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Gogorarazi"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Desegin"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>z atzeratu da"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d ordu</item>
-      <item quantity="one">%d ordu</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutu</item>
-      <item quantity="one">%d minutu</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ordu}=2{# ordu}other{# ordu}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minutu}other{# minutu}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Bateria-aurrezlea"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertak"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Bateria"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Pantaila-argazkiak"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mezu orokorrak"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Zuzeneko aplikazioak"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Konfigurazioa"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Memoria"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Aholkuak"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Zuzeneko aplikazioak"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"aldatu"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Gailuak kontrolatzeko widgetak"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Aukeratu aplikazio bat kontrolatzeko aukerak gehitzeko"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontrol-aukera gehitu dira.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontrol-aukera gehitu da.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Kontrolatzeko # aukera gehitu da.}other{Kontrolatzeko # aukera gehitu dira.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Kenduta"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Gogokoetan dago"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>. gogokoa da"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Gehitu lauza"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ez gehitu lauza"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Hautatu erabiltzaile bat"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikazio aktibo daude</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikazio aktibo dago</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikazio aktibo dago}other{# aplikazio aktibo daude}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informazio berria"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktibo dauden aplikazioak"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Aplikazio hauek aktibo daude eta funtzionatzen ari dira, nahiz eta zu haiek erabiltzen ez aritu. Aukera honek haien funtzioa hobetzen du, baina baliteke bateriaren iraupenari ere eragitea."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma ezarrita dago"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera eta mikrofonoa desaktibatuta daude"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# jakinarazpen}other{# jakinarazpen}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Igortzen"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren audioa igortzeari utzi nahi diozu?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa igortzen baduzu, edo audio-irteera aldatzen baduzu, une hartako igorpena eten egingo da"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Igorri <xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Aldatu audio-irteera"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ezezaguna"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
index baddea1..3bf49c8 100644
--- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Desaktibatuta"</item>
     <item msgid="460891964396502657">"Aktibatuta"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Ez dago erabilgarri"</item>
+    <item msgid="8014986104355098744">"Desaktibatuta"</item>
+    <item msgid="5966994759929723339">"Aktibatuta"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 1d126c3..8719b00 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"«حسگرها خاموش» فعال است"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"پاک کردن تمام اعلان‌ها"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> اعلان دیگر در گروه.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> اعلان دیگر در گروه.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# اعلان دیگر در گروه وجود دارد.}one{# اعلان دیگر در گروه وجود دارد.}other{# اعلان دیگر در گروه وجود دارد.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"صفحه اکنون در حالت افقی قفل است."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"صفحه اکنون در جهت عمودی قفل است."</string>
     <string name="dessert_case" msgid="9104973640704357717">"ویترین دسر"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"چرخش خودکار"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"چرخش خودکار صفحه‌نمایش"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"مکان"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"محافظ صفحه"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"دسترسی به دوربین"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"دسترسی به میکروفون"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"دردسترس"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"نقطه اتصال"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"روشن کردن…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"صرفه‌جویی داده روشن است"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">‏%d دستگاه</item>
-      <item quantity="other">‏%d دستگاه</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# دستگاه}one{# دستگاه}other{# دستگاه}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"چراغ قوه"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"دوربین درحال استفاده"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"داده تلفن همراه"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"آیا می‌خواهید جلسه‌تان را ادامه دهید؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"شروع مجدد"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"بله، ادامه داده شود"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"حالت مهمان"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"در حالت مهمان هستید"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"با افزودن کاربر جدید، از حالت مهمان خارج خواهید شد و همه برنامه‌ها و داده‌ها از جلسه مهمان کنونی حذف خواهند شد."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"به تعداد مجاز تعداد کاربر رسیده‌اید"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">می‌توانید حداکثر <xliff:g id="COUNT">%d</xliff:g> کاربر اضافه کنید.</item>
-      <item quantity="other">می‌توانید حداکثر <xliff:g id="COUNT">%d</xliff:g> کاربر اضافه کنید.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{فقط یک کاربر می‌توان ایجاد کرد.}one{حداکثر # کاربر می‌توانید اضافه کنید.}other{حداکثر # کاربر می‌توانید اضافه کنید.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"کاربر حذف شود؟"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"همه برنامه‌ها و داده‌های این کاربر حذف می‌شود."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"حذف"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"به من یادآوری شود"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"واگرد"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> به تعویق افتاد"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">‏%d ساعت</item>
-      <item quantity="other">‏%d ساعت</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">‏%d دقیقه</item>
-      <item quantity="other">‏%d دقیقه</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ساعت}=2{# ساعت}one{# ساعت}other{# ساعت}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# دقیقه}one{# دقیقه}other{# دقیقه}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"بهینه‌سازی باتری"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"هشدارها"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"باتری"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"نماگرفت‌ها"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"پیام‌های عمومی"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"برنامه‌های فوری"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"راه‌اندازی"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"فضای ذخیره‌سازی"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"نکات"</string>
     <string name="instant_apps" msgid="8337185853050247304">"برنامه‌های فوری"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"روشن/ خاموش کردن"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"کنترل‌های دستگاه"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"انتخاب برنامه برای افزودن کنترل‌ها"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> کنترل اضافه شده است.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> کنترل اضافه شده است.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنترل اضافه شد.}one{# کنترل اضافه شد.}other{# کنترل اضافه شد.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"حذف شد"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"به موارد دلخواه اضافه شد"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"اضافه‌شده به موارد دلخواه، جایگاه <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"کاشی اضافه شود"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"کاشی اضافه نشود"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"انتخاب کاربر"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> برنامه فعال است</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> برنامه فعال است</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# برنامه فعال است}one{# برنامه فعال است}other{# برنامه فعال است}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"اطلاعات جدید"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"برنامه‌های فعال"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"این برنامه‌ها فعال هستند و اجرا می‌شوند، حتی وقتی که از آن‌ها استفاده نکنید. این کار باعث بهبود عملکرد برنامه‌ها می‌شود، اما بر عمر باتری نیز تأثیر می‌گذارد."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"زنگ ساعت تنظیم شد"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"دوربین و میکروفون خاموش هستند"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اعلان}one{# اعلان}other{# اعلان}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"همه‌فرستی"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"همه‌فرستی <xliff:g id="APP_NAME">%1$s</xliff:g> متوقف شود؟"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر <xliff:g id="SWITCHAPP">%1$s</xliff:g> را همه‌فرستی کنید یا خروجی را تغییر دهید، همه‌فرستی کنونی متوقف خواهد شد"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"همه‌فرستی <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"تغییر خروجی"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"نامشخص"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
index ecc8d1cc..85f0bfd 100644
--- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"خاموش"</item>
     <item msgid="460891964396502657">"روشن"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"دردسترس نیست"</item>
+    <item msgid="8014986104355098744">"خاموش"</item>
+    <item msgid="5966994759929723339">"روشن"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index b395aac..54be04f 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Anturit pois päältä aktiivinen"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Tyhjennä kaikki ilmoitukset."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">+<xliff:g id="NUMBER_1">%s</xliff:g> ilmoitusta ryhmässä</item>
-      <item quantity="one">+<xliff:g id="NUMBER_0">%s</xliff:g> ilmoitus ryhmässä</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{+# ilmoitus ryhmässä.}other{+# ilmoitusta ryhmässä.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ruutu on lukittu vaakasuuntaan."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ruutu on lukittu pystysuuntaan."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Jälkiruokavitriini"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automaattinen kääntö"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Käännä näyttöä automaattisesti."</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Sijainti"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Näytönsäästäjä"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pääsy kameraan"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pääsy mikrofoniin"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Käytettävissä"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Otetaan käyttöön…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Data Saver on käytössä"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d laitetta</item>
-      <item quantity="one">%d laite</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# laite}other{# laitetta}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Taskulamppu"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera käytössä"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobiilidata"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Haluatko jatkaa istuntoa?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Aloita alusta"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Kyllä, haluan jatkaa"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Vierastila"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Olet vierastilassa"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Uuden käyttäjän lisääminen poistaa sinut vierastilasta. Kaikki sovellukset ja data poistetaan myös samalla nykyisestä vierailija-käyttökerrasta."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Käyttäjäraja saavutettu"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Voit lisätä korkeintaan <xliff:g id="COUNT">%d</xliff:g> käyttäjää.</item>
-      <item quantity="one">Käyttäjiä voi olla vain yksi.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Voit luoda vain yhden käyttäjän.}other{Voit lisätä korkeintaan # käyttäjää.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Poistetaanko käyttäjä?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Kaikki käyttäjän tiedot ja sovellukset poistetaan."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Poista"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Muistuta minua"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Kumoa"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Torkku: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d tuntia</item>
-      <item quantity="one">%d tunti</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minuuttia</item>
-      <item quantity="one">%d minuutti</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# tunti}=2{# tuntia}other{# tuntia}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuutti}other{# minuuttia}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Virransäästö"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Ilmoitukset"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Akku"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Kuvakaappaukset"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Yleiset viestit"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Määritys"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Tallennustila"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Vihjeet"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"vaihda"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Laitehallinta"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Valitse sovellus lisätäksesi säätimiä"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> säädintä lisätty</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> säädin lisätty</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# säädin lisätty.}other{# säädintä lisätty.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Poistettu"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisätty suosikkeihin"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisätty suosikkeihin sijalle <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Lisää laatta"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Älä lisää laattaa"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Valitse käyttäjä"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> sovellusta on aktiivisia</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> sovellus on aktiivinen</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# sovellus on aktiivinen}other{# sovellusta aktiivisena}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Uutta tietoa"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiiviset sovellukset"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Nämä sovellukset ovat aktiivisia ja ne ovat käynnissä, vaikka et käyttäisi niitä. Näin sovellusten toimivuus paranee, mutta se voi vaikutta akunkestoon."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Hälytys asetettu"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ja mikrofoni ovat pois päältä"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ilmoitus}other{# ilmoitusta}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Lähettää"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Lopetetaanko <xliff:g id="APP_NAME">%1$s</xliff:g>-sovelluksen lähettäminen?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jos lähetät <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta tai muutat ulostuloa, nykyinen lähetyksesi loppuu"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Lähetä <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Muuta ulostuloa"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tuntematon"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
index 5844fb9..1505dc5 100644
--- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Poissa päältä"</item>
     <item msgid="460891964396502657">"Päällä"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Ei saatavilla"</item>
+    <item msgid="8014986104355098744">"Poissa päältä"</item>
+    <item msgid="5966994759929723339">"Päällä"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 469e86c..f9b1896 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Option « Capteurs désactivés » active"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Supprimer toutes les notifications"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> autre notification à l\'intérieur.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> autres notifications à l\'intérieur.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# autre notification à l\'intérieur.}one{# autre notification à l\'intérieur.}other{# autres notifications à l\'intérieur.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"L\'écran est verrouillé en mode paysage."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"L\'écran est verrouillé en mode portrait."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Vitrine des desserts"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotation automatique"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Écran de veille"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accès à l\'appareil photo"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accès au micro"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Accessible"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Point d\'accès sans fil"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Activation en cours…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Écon. données activé"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d appareil</item>
-      <item quantity="other">%d appareils</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# appareil}one{# appareil}other{# appareils}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampe de poche"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"L\'appareil photo est en cours d\'utilisation"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Données cellulaires"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recommencer"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oui, continuer"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mode Invité"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Vous êtes en mode Invité"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si vous ajoutez un nouvel utilisateur, vous quitterez le mode Invité, et toutes les applications et données de la session d\'invité en cours seront supprimées."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite d\'utilisateurs atteinte"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Vous pouvez ajouter jusqu\'à <xliff:g id="COUNT">%d</xliff:g> utilisateur.</item>
-      <item quantity="other">Vous pouvez ajouter jusqu\'à <xliff:g id="COUNT">%d</xliff:g> utilisateurs.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Vous ne pouvez créer qu\'un seul utilisateur.}one{Vous pouvez ajouter jusqu\'à # utilisateur.}other{Vous pouvez ajouter jusqu\'à # utilisateurs.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Supprimer l\'utilisateur?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Toutes les applications et les données de cet utilisateur seront supprimées."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Supprimer"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Me rappeler"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Annuler"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Reporté pour <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d heure</item>
-      <item quantity="other">%d heures</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minute</item>
-      <item quantity="other">%d minutes</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# heure}=2{# heures}one{# heure}other{# heures}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minute}one{# minute}other{# minutes}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Économiseur de pile"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertes"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Pile"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Saisies d\'écran"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Messages généraux"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Applications instantanées"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configuration"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Stockage"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Conseils"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Applications instantanées"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"basculer"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'application pour laquelle ajouter des commandes"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> commande ajoutée.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> commandes ajoutées.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}other{# commandes ajoutées.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Ajouter la tuile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne pas ajouter de tuile"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Choisir l\'utilisateur"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> application est active</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> applications sont actives</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# application est active}one{# application est active}other{# applications sont actives}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nouvelle information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Applications actives"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ces applications sont actives et s\'exécutent même lorsque vous ne les utilisez pas. Cela améliore leur fonctionnalité, mais peut également affecter l\'autonomie de la pile."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"L\'alarme a été réglée"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"L\'appareil photo et le micro sont désactivés"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# notifications}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion en cours…"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou changez la sortie, votre diffusion actuelle s\'arrêtera"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Changer la sortie"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Inconnue"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index 9d78e91..4ec0084 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Désactivé"</item>
     <item msgid="460891964396502657">"Activé"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Non accessible"</item>
+    <item msgid="8014986104355098744">"Désactivé"</item>
+    <item msgid="5966994759929723339">"Activé"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 14f7d06..815f018 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Option \"Capteurs désactivés\" active"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Supprimer toutes les notifications"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"<xliff:g id="NUMBER">%s</xliff:g> autres"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> autre notification à l\'intérieur.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> autres notifications à l\'intérieur.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# autre notification dans le groupe.}one{# autre notification dans le groupe.}other{# autres notifications dans le groupe.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"L\'écran est verrouillé en mode paysage."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"L\'écran est verrouillé en mode portrait."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Vitrine des desserts"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotation automatique"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Économiseur d\'écran"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accès à l\'appareil photo"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accès au micro"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponible"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Point d\'accès"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Activation…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Écon. données activé"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d appareil</item>
-      <item quantity="other">%d appareils</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# appareil}one{# appareil}other{# appareils}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampe de poche"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Caméra en cours d\'utilisation"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Données mobiles"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la dernière session ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Non, nouvelle session"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oui, continuer"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mode Invité"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Vous êtes en mode Invité"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si vous ajoutez un utilisateur, le mode Invité sera désactivé et toutes les applis et les données de la session Invité actuelle seront supprimées."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite nombre utilisateurs atteinte"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Vous pouvez ajouter <xliff:g id="COUNT">%d</xliff:g> profil utilisateur.</item>
-      <item quantity="other">Vous pouvez ajouter jusqu\'à <xliff:g id="COUNT">%d</xliff:g> profils utilisateur.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Vous ne pouvez créer qu\'un seul utilisateur.}one{Vous pouvez ajouter # utilisateur.}other{Vous pouvez ajouter jusqu\'à # utilisateurs.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Supprimer l\'utilisateur ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Toutes les applications et les données de cet utilisateur seront supprimées."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Supprimer"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"M\'envoyer un rappel"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Annuler"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Répétée après <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d heure</item>
-      <item quantity="other">%d heures</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minute</item>
-      <item quantity="other">%d minutes</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# heure}=2{# heures}one{# heure}other{# heures}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minute}one{# minute}other{# minutes}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Économiseur de batterie"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertes"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batterie"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Captures d\'écran"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Nouveaux messages"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Applis instantanées"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configurer"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Espace de stockage"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Astuces"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Applis instantanées"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activer/désactiver"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'appli pour laquelle ajouter des commandes"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> commande ajoutée.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> commandes ajoutées.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}other{# commandes ajoutées.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Ajouter le bloc"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne pas ajouter le bloc"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Choisir l\'utilisateur"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> appli est active</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> applis sont actives</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# appli est active}one{# appli est active}other{# applis sont actives}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nouvelles informations"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Applis actives"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ces applis sont actives et s\'exécutent même lorsque vous ne les utilisez pas. Cela améliore leur fonctionnement, mais peut également affecter l\'autonomie de la batterie."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme réglée"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Appareil photo et micro désactivés"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# notifications}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion…"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou que vous modifiez le résultat, votre annonce actuelle s\'arrêtera"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Modifier le résultat"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Inconnue"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index 47fa9c5..8c6c4f5 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Désactivé"</item>
     <item msgid="460891964396502657">"Activé"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Indisponible"</item>
+    <item msgid="8014986104355098744">"Désactivé"</item>
+    <item msgid="5966994759929723339">"Activé"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 8e03b12..d510b83 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"A opción Desactivar sensores está activada"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Eliminar todas as notificacións."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"<xliff:g id="NUMBER">%s</xliff:g> máis"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> notificacións máis no grupo.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> notificación máis no grupo.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Hai # notificación máis no grupo.}other{Hai # notificacións máis no grupo.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"A pantalla está bloqueada en orientación horizontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"A pantalla está bloqueada en orientación vertical."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Caixa de sobremesa"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Xirar automaticamente"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Xirar pantalla automaticamente"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localización"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Protector de pantalla"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acceso á cámara"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acceso ao micrófono"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dispoñible"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Zona wifi"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Activando…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Aforro datos activo"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d dispositivos</item>
-      <item quantity="one">%d dispositivo</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispositivo}other{# dispositivos}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lanterna"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Cámara en uso"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Datos móbiles"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Queres continuar coa túa sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Comezar de novo"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Si, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo de convidado"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Estás usando o modo de convidado"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ao engadir un usuario novo, sairás do modo de convidado e eliminaranse todas as aplicacións e datos da sesión de convidado actual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Alcanzouse o límite de usuarios"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Podes engadir ata <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
-      <item quantity="one">Só se pode crear un usuario.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Só se pode crear 1 usuario.}other{Podes engadir # usuarios como máximo.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Queres quitar o usuario?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Eliminaranse todas as aplicacións e os datos deste usuario."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Quitar"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Lembrarme"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Desfacer"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Adiouse <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d horas</item>
-      <item quantity="one">%d hora</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutos</item>
-      <item quantity="one">%d minuto</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hora}=2{# horas}other{# horas}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuto}other{# minutos}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Aforro de batería"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertas"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batería"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Capturas de pantalla"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mensaxes xerais"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Aplicacións Instantáneas"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configurar"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Almacenamento"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Consellos"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Aplicacións Instantáneas"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activar/desactivar"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Escolle unha aplicación para engadir controis"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">Engadíronse <xliff:g id="NUMBER_1">%s</xliff:g> controis.</item>
-      <item quantity="one">Engadiuse <xliff:g id="NUMBER_0">%s</xliff:g> control.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Engadiuse # control.}other{Engadíronse # controis.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Quitouse"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Está entre os controis favoritos"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Está entre os controis favoritos (posición: <xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Engadir atallo"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Non engadir atallo"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Seleccionar usuario"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplicacións activas</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicación activa</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{Hai # aplicación activa}other{Hai # aplicacións activas}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova información"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicacións activas"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Estas aplicacións están activas e en execución mesmo cando non as usas. Deste xeito mellórase o seu funcionamento, pero tamén é posible que se vexa afectada a duración da batería."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarma definida"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A cámara e o micrófono están desactivados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificacións}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Difusión"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Queres deixar de emitir contido a través de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se emites contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou cambias de saída, a emisión en curso deterase"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitir contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambiar de saída"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Descoñecida"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
index 229836c..590ec4a 100644
--- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Desactivado"</item>
     <item msgid="460891964396502657">"Activado"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Non dispoñible"</item>
+    <item msgid="8014986104355098744">"Desactivado"</item>
+    <item msgid="5966994759929723339">"Activado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 5673725..6d14e46 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"\'સેન્સર બંધ છે\'ની સુવિધા સક્રિય છે"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"બધા સૂચનો સાફ કરો."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> વધુ સૂચના અંદર છે.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> વધુ સૂચના અંદર છે.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{વધુ # નોટિફિકેશન અંદર છે.}one{વધુ # નોટિફિકેશન અંદર છે.}other{વધુ # નોટિફિકેશન અંદર છે.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"સ્ક્રીન લેન્ડસ્કેપ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"સ્ક્રીન પોટ્રેટ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
     <string name="dessert_case" msgid="9104973640704357717">"ડેઝર્ટ કેસ"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ઑટો રોટેટ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ઑટો રોટેટ સ્ક્રીન"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"સ્થાન"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"સ્ક્રીન સેવર"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"કૅમેરાનો ઍક્સેસ"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"માઇકનો ઍક્સેસ"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ઉપલબ્ધ છે"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"હૉટસ્પૉટ"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ચાલુ કરી રહ્યાં છીએ…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ડેટા સેવર ચાલુ છે"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d ઉપકરણ</item>
-      <item quantity="other">%d ઉપકરણો</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# ડિવાઇસ}one{# ડિવાઇસ}other{# ડિવાઇસ}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ફ્લૅશલાઇટ"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"કૅમેરાનો ઉપયોગ થાય છે"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"મોબાઇલ ડેટા"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"શું તમે તમારું સત્ર ચાલુ રાખવા માંગો છો?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"શરૂ કરો"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"હા, ચાલુ રાખો"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"અતિથિ મોડ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"તમે અતિથિ મોડમાં છો"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"કોઈ નવા વપરાશકર્તાને ઉમેરવાથી અતિથિ મોડમાંથી નીકળી જવાશે તેમજ હાલના અતિથિ સત્રમાંથી તમામ ઍપ અને ડેટા ડિલીટ થઈ જશે."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"વપરાશકર્તા સંખ્યાની મર્યાદા"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">તમે <xliff:g id="COUNT">%d</xliff:g> વપરાશકર્તા સુધી ઉમેરી શકો છો.</item>
-      <item quantity="other">તમે <xliff:g id="COUNT">%d</xliff:g> વપરાશકર્તાઓ સુધી ઉમેરી શકો છો.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{માત્ર એક જ વપરાશકર્તા બનાવી શકાય છે.}one{તમે વધુમાં વધુ # વપરાશકર્તા ઉમેરી શકો છો.}other{તમે વધુમાં વધુ # વપરાશકર્તા ઉમેરી શકો છો.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"વપરાશકર્તાને દૂર કરીએ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"આ વપરાશકર્તાની તમામ ઍપ્લિકેશનો અને ડેટા કાઢી નાખવામાં આવશે."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"કાઢી નાખો"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"મને યાદ કરાવો"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"છેલ્લો ફેરફાર રદ કરો"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> માટે સ્નૂઝ કરો"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d કલાક</item>
-      <item quantity="other">%d કલાક</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d મિનિટ</item>
-      <item quantity="other">%d મિનિટ</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# કલાક}=2{# કલાક}one{# કલાક}other{# કલાક}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# મિનિટ}one{# મિનિટ}other{# મિનિટ}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"બૅટરી સેવર"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"અલર્ટ"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"બૅટરી"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"સ્ક્રીનશૉટ"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"સામાન્ય સંદેશા"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"સેટઅપ કરો"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"સ્ટોરેજ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"હિન્ટ"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ટૉગલ કરો"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ડિવાઇસનાં નિયંત્રણો"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"નિયંત્રણો ઉમેરવા માટે ઍપ પસંદ કરો"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> નિયંત્રણ ઉમેર્યું.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> નિયંત્રણો ઉમેર્યા.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# નિયંત્રણ ઉમેર્યું.}one{# નિયંત્રણ ઉમેર્યું.}other{# નિયંત્રણ ઉમેર્યા.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"કાઢી નાખ્યું"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"મનપસંદમાં ઉમેર્યું"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"મનપસંદમાં ઉમેર્યું, સ્થાન <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ટાઇલ ઉમેરો"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ટાઇલ ઉમેરશો નહીં"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"વપરાશકર્તા પસંદ કરો"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ઍપ સક્રિય છે</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ઍપ સક્રિય છે</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ઍપ સક્રિય છે}one{# ઍપ સક્રિય છે}other{# ઍપ સક્રિય છે}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"નવી માહિતી"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"સક્રિય ઍપ"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"જ્યારે તમે આ ઍપનો ઉપયોગ ન કરતા હો, ત્યારે પણ તે સક્રિય અને ચાલતી હોય છે. આનાથી તેની કાર્યક્ષમતામાં સુધારો થાય છે, પરંતુ બૅટરીની આવરદાને અસર પણ થઈ શકે છે."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"અલાર્મ સેટ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"કૅમેરા અને માઇક બંધ છે"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# નોટિફિકેશન}one{# નોટિફિકેશન}other{# નોટિફિકેશન}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"બ્રૉડકાસ્ટ કરી રહ્યાં છે"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> બ્રોડકાસ્ટ કરવાનું રોકીએ?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"જો તમે <xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો અથવા આઉટપુટ બદલો, તો તમારું હાલનું બ્રોડકાસ્ટ બંધ થઈ જશે"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"આઉટપુટ બદલો"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"અજાણ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
index c502ba3..73b3720 100644
--- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"બંધ છે"</item>
     <item msgid="460891964396502657">"ચાલુ છે"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"અનુપલબ્ધ"</item>
+    <item msgid="8014986104355098744">"બંધ છે"</item>
+    <item msgid="5966994759929723339">"ચાલુ છે"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 40821bf..d385337 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"सेंसर बंद हैं"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"सभी सूचनाएं साफ़ करें."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">इसमें <xliff:g id="NUMBER_1">%s</xliff:g> और सूचनाएं हैं.</item>
-      <item quantity="other">इसमें <xliff:g id="NUMBER_1">%s</xliff:g> और सूचनाएं हैं.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{ग्रुप में # सूचना है.}one{ग्रुप में # सूचना है.}other{ग्रुप में # सूचनाएं हैं.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"स्क्रीन लैंडस्केप दिशा में लॉक है."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"स्‍क्रीन पोर्ट्रेट दिशा में लॉक है."</string>
     <string name="dessert_case" msgid="9104973640704357717">"मिठाई का डिब्बा"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ऑटो-रोटेट"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रीन का अपने-आप दिशा बदलना (ऑटो-रोटेट)"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"जगह"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"स्क्रीन सेवर"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"कैमरे का ऐक्सेस"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"माइक्रोफ़ोन का ऐक्सेस"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"उपलब्ध"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"हॉटस्पॉट"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"हॉटस्पॉट चालू हो रहा है…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"डेटा बचाया जा रहा है"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d डिवाइस</item>
-      <item quantity="other">%d डिवाइस</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# डिवाइस}one{# डिवाइस}other{# डिवाइस}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"फ़्लैशलाइट"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"कैमरा इस्तेमाल में है"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"मोबाइल डेटा"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"क्‍या आपको अपना सेशन जारी रखना है?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"फिर से शुरू करें"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हां, जारी रखें"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"मेहमान मोड"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"आप मेहमान मोड में हैं"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"किसी नए उपयोगकर्ता को जोड़ने पर, मेहमान मोड को बंद कर दिया जाएगा. साथ ही, मेहमान के तौर पर ब्राउज़ करने के मौजूदा सेशन से, सभी ऐप्लिकेशन और डेटा को मिटा दिया जाएगा."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"अब और उपयोगकर्ता नहीं जोड़े जा सकते"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">आप ज़्यादा से ज़्यादा <xliff:g id="COUNT">%d</xliff:g> उपयोगकर्ता जोड़ सकते हैं.</item>
-      <item quantity="other">आप ज़्यादा से ज़्यादा <xliff:g id="COUNT">%d</xliff:g> उपयोगकर्ता जोड़ सकते हैं.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{सिर्फ़ एक उपयोगकर्ता खाता जोड़ा जा सकता है.}one{ज़्यादा से ज़्यादा # उपयोगकर्ता खाता जोड़ा जा सकता है.}other{ज़्यादा से ज़्यादा # उपयोगकर्ता खाते जोड़े जा सकते हैं.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"उपयोगकर्ता निकालें?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"इस उपयोगकर्ता के सभी ऐप और डेटा को हटा दिया जाएगा."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"हटाएं"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"बाद में याद दिलाएं"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"पहले जैसा करें"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> के लिए याद दिलाया गया"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d घंटे</item>
-      <item quantity="other">%d घंटे</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d मिनट</item>
-      <item quantity="other">%d मिनट</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# घंटा}=2{# घंटे}one{# घंटा}other{# घंटे}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# मिनट}one{# मिनट}other{# मिनट}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"बैटरी सेवर"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"सूचनाएं"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"बैटरी"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"स्‍क्रीनशॉट"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"सामान्य संदेश"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"सेट अप"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"स्टोरेज"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"संकेत"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"टॉगल करें"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"डिवाइस कंट्रोल"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"कंट्रोल जोड़ने के लिए ऐप्लिकेशन चुनें"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> कंट्रोल जोड़ा गया.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> कंट्रोल जोड़े गए.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कंट्रोल जोड़ा गया.}one{# कंट्रोल जोड़ा गया.}other{# कंट्रोल जोड़े गए.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"हटाया गया"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"पसंदीदा बनाया गया"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"पसंदीदा बनाया गया, क्रम संख्या <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"टाइल जोड़ें"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"टाइल न जोड़ें"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"उपयोगकर्ता चुनें"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ऐप्लिकेशन चालू है</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ऐप्लिकेशन चालू हैं</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ऐप्लिकेशन चालू है}one{# ऐप्लिकेशन चालू है}other{# ऐप्लिकेशन चालू हैं}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"नई जानकारी"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ये ऐप्लिकेशन चालू हैं"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"ये ऐप्लिकेशन चालू हैं और आपके इस्तेमाल न करने पर भी चल रहे हैं. इससे, ये बेहतर तरीके से फ़ंक्शन करते हैं. हालांकि, इससे बैटरी लाइफ़ पर भी असर पड़ सकता है."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट किया गया"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कैमरा और माइक बंद हैं"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}one{# सूचना}other{# सूचनाएं}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट ऐप्लिकेशन"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर ब्रॉडकास्ट करना रोकें?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट शुरू करने पर या आउटपुट बदलने पर, आपका मौजूदा ब्रॉडकास्ट बंद हो जाएगा"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट करें"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट बदलें"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"कोई जानकारी नहीं"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
index 9af07bc..a156b0c 100644
--- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"बंद है"</item>
     <item msgid="460891964396502657">"चालू है"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"उपलब्ध नहीं है"</item>
+    <item msgid="8014986104355098744">"बंद है"</item>
+    <item msgid="5966994759929723339">"चालू है"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 1ddf767..60a8402 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -205,11 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Senzori isključeni aktivno"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Brisanje svih obavijesti."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"još <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">U skupini je još <xliff:g id="NUMBER_1">%s</xliff:g> obavijest.</item>
-      <item quantity="few">U skupini su još <xliff:g id="NUMBER_1">%s</xliff:g> obavijesti.</item>
-      <item quantity="other">U skupini je još <xliff:g id="NUMBER_1">%s</xliff:g> obavijesti.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{U grupi je još # obavijest.}one{U grupi je još # obavijest.}few{U grupi su još # obavijesti.}other{U grupi je još # obavijesti.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Zaslon je zaključan u pejzažnoj orijentaciji."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Zaslon je zaključan u portretnoj orijentaciji."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Izlog za slastice"</string>
@@ -227,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autom. zakretanje"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko zakretanje zaslona"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Čuvar zaslona"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pristup fotoaparatu"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pristup mikrofonu"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupno"</string>
@@ -256,11 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Žarišna točka"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Uključivanje…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Štednja pod. prom. uklj."</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d uređaj</item>
-      <item quantity="few">%d uređaja</item>
-      <item quantity="other">%d uređaja</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# uređaj}one{# uređaj}few{# uređaja}other{# uređaja}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Svjetiljka"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Upotrebljava se kamera"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobilni podaci"</string>
@@ -353,12 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Način rada za goste"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Upotrebljavate način rada za goste"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ako dodate novog korisnika, napustit ćete način rada za goste i izbrisat će se svi podaci i aplikacije iz trenutačne gostujuće sesije."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dosegnuto je ograničenje korisnika"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
-      <item quantity="few">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
-      <item quantity="other">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Može se izraditi samo jedan korisnik.}one{Možete dodati najviše # korisnika.}few{Možete dodati najviše # korisnika.}other{Možete dodati najviše # korisnika.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Ukloniti korisnika?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Izbrisat će se sve aplikacije i podaci ovog korisnika."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Ukloni"</string>
@@ -544,16 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Podsjeti me"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Poništi"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Odgođeno <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d sat</item>
-      <item quantity="few">%d sata</item>
-      <item quantity="other">%d sati</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minuta</item>
-      <item quantity="few">%d minute</item>
-      <item quantity="other">%d minuta</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# h}=2{# h}one{# h}few{# h}other{# h}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# min}one{# min}few{# min}other{# min}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Štednja baterije"</string>
     <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>
@@ -702,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Upozorenja"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Baterija"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Snimke zaslona"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Općenite poruke"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant aplikacije"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Postavljanje"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Pohrana"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Savjeti"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant aplikacije"</string>
@@ -776,11 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"promijeni"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Odabir aplikacije za dodavanje kontrola"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one">Dodana je <xliff:g id="NUMBER_1">%s</xliff:g> kontrola.</item>
-      <item quantity="few">Dodane su <xliff:g id="NUMBER_1">%s</xliff:g> kontrole.</item>
-      <item quantity="other">Dodano je <xliff:g id="NUMBER_1">%s</xliff:g> kontrola.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodana je # kontrola.}one{Dodana je # kontrola.}few{Dodane su # kontrole.}other{Dodano je # kontrola.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u favorite"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano u favorite, položaj <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -937,11 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj pločicu"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nemoj dodati pločicu"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Odabir korisnika"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivna</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikacije su aktivne</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivno</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikacija je aktivna}one{# aplikacija je aktivna}few{# aplikacije su aktivne}other{# aplikacija je aktivno}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Te su aplikacije aktivne i pokrenute čak i kad ih ne koristite. Time se poboljšava njihova funkcionalnost, ali to može utjecati na trajanje baterije."</string>
@@ -970,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je postavljen"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat i mikrofon su isključeni"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavijest}one{# obavijest}few{# obavijesti}other{# obavijesti}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, vaše će se trenutačno emitiranje zaustaviti"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Emitiranje aplikacije <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Promjena izlaza"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nepoznato"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
index a057c48..b69b064 100644
--- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Isključeno"</item>
     <item msgid="460891964396502657">"Uključeno"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Nedostupno"</item>
+    <item msgid="8014986104355098744">"Isključeno"</item>
+    <item msgid="5966994759929723339">"Uključeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 531fcf0..9b09ccc 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Az Érzékelők kikapcsolva kártya aktív"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Minden értesítés törlése"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> további értesítés.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> további értesítés.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# további értesítés a csoportban.}other{# további értesítés a csoportban.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"A képernyő zárolva van fekvő tájolásban."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"A képernyő zárolva van álló tájolásban."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatikus elforgatás"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatikus képernyőforgatás"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Tartózkodási hely"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Képernyővédő"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Hozzáférés a kamerához"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonelérés"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Rendelkezésre áll"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Bekapcsolás…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Aktív adatcsökkentés"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d eszköz</item>
-      <item quantity="one">%d eszköz</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# eszköz}other{# eszköz}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Zseblámpa"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"A kamera használatban van"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobiladatok"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Folytatja a munkamenetet?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Újrakezdés"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Igen, folytatom"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Vendég mód"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Vendég módban van"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Új felhasználó felvételével kilép a vendég módból, és az aktuális vendégmunkamenetből származó összes alkalmazás és adat törlődik majd."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Maximális felhasználószám elérve"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Legfeljebb <xliff:g id="COUNT">%d</xliff:g> felhasználót adhat hozzá.</item>
-      <item quantity="one">Csak egy felhasználót lehet létrehozni.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Csak egy felhasználót lehet létrehozni.}other{Legfeljebb # felhasználót adhat hozzá.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Törli a felhasználót?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"A felhasználóhoz tartozó minden adat és alkalmazás törölve lesz."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Eltávolítás"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Emlékeztessen"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Visszavonás"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Elhalasztva: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d óra</item>
-      <item quantity="one">%d óra</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d perc</item>
-      <item quantity="one">%d perc</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# óra}=2{# óra}other{# óra}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# perc}other{# perc}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Akkumulátorkímélő mód"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Értesítések"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Akkumulátor"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Képernyőképek"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Általános üzenetek"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Azonnali alkalmazások"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Beállítás"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Tárhely"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Tippek"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Azonnali alkalmazások"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"váltás"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Eszközvezérlők"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Válasszon alkalmazást a vezérlők hozzáadásához"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> vezérlő hozzáadva.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> vezérlő hozzáadva.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# vezérlő hozzáadva.}other{# vezérlő hozzáadva.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Eltávolítva"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Hozzáadva a kedvencekhez"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Hozzáadva a kedvencekhez <xliff:g id="NUMBER">%d</xliff:g>. helyen"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Mozaik hozzáadása"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne legyen hozzáadva"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Felhasználóválasztás"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> alkalmazás aktív</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> alkalmazás aktív</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# alkalmazás aktív}other{# alkalmazás aktív}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Új információ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktív alkalmazások"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ezek az alkalmazások aktívak és futnak, még akkor is, amikor nem használja őket. Ez javítja a működésüket, de hatással lehet az akkumulátor-élettartamra is."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ébresztő beállítva"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A kamera és a mikrofon ki vannak kapcsolva"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# értesítés}other{# értesítés}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sugárzás"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Leállítja a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> közvetítését?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"A(z) <xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése vagy a kimenet módosítása esetén a jelenlegi közvetítés leáll"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Kimenet módosítása"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ismeretlen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
index 47109a3..050bc14 100644
--- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Ki"</item>
     <item msgid="460891964396502657">"Be"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Nem áll rendelkezésre"</item>
+    <item msgid="8014986104355098744">"Ki"</item>
+    <item msgid="5966994759929723339">"Be"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 7f2d577..a707c63 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Տվիչներն անջատված են"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Մաքրել բոլոր ծանուցումները:"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Ներսում ևս <xliff:g id="NUMBER_1">%s</xliff:g> ծանուցում կա:</item>
-      <item quantity="other">Ներսում ևս <xliff:g id="NUMBER_1">%s</xliff:g> ծանուցում կա:</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Խմբում ևս # ծանուցում կա։}one{Խմբում ևս # ծանուցում կա։}other{Խմբում ևս # ծանուցում կա։}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Էկրանը կողպված է հորիզոնական դիրքավորման մեջ:"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Էկրանը կողպված է ուղղաձիգ դիրքավորմամբ:"</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Ինքնապտտում"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ավտոմատ պտտել էկրանը"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Տեղորոշում"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Էկրանապահ"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Տեսախցիկի հասանելիություն"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Խոսափողի հասանելիություն"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Հասանելի է"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Թեժ կետ"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Միացում…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Թրաֆիկը տնտեսվում է"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d սարք</item>
-      <item quantity="other">%d սարք</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# սարք}one{# սարք}other{# սարք}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Լապտեր"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Օգտագործվում է տեսախցիկը"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Բջջային ինտերնետ"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Շարունակե՞լ աշխատաշրջանը։"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Վերսկսել"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Այո, շարունակել"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Հյուրի ռեժիմ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Դուք հյուրի ռեժիմում եք"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ավելացնելով նոր օգտատեր՝ դուք դուրս կգաք հյուրի ռեժիմից։ Հյուրի ընթացիկ աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն։"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Սահմանաչափը սպառված է"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Հնարավոր է ավելացնել առավելագույնը <xliff:g id="COUNT">%d</xliff:g> օգտատեր։</item>
-      <item quantity="other">Հնարավոր է ավելացնել առավելագույնը <xliff:g id="COUNT">%d</xliff:g> օգտատեր։</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Հնարավոր է ստեղծել միայն մեկ օգտատեր։}one{Կարող եք առավելագույնը # օգտատեր ավելացնել։}other{Կարող եք առավելագույնը # օգտատեր ավելացնել։}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Հեռացնե՞լ օգտատիրոջը:"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Այս օգտատիրոջ բոլոր հավելվածներն ու տվյալները կջնջվեն:"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Հեռացնել"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Հիշեցնել ինձ"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Հետարկել"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Հետաձգվել է <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ով"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d ժամ</item>
-      <item quantity="other">%d ժամ</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d րոպե</item>
-      <item quantity="other">%d րոպե</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ժամ}=2{# ժամ}one{# ժամ}other{# ժամ}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# րոպե}one{# րոպե}other{# րոպե}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Մարտկոցի տնտեսում"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Ծանուցումներ"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Մարտկոց"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Սքրինշոթներ"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Ընդհանուր հաղորդագրություններ"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Ակնթարթային հավելվածներ"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Կարգավորում"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Տարածք"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Հուշումներ"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Ակնթարթային հավելվածներ"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"միացնել/անջատել"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Սարքերի կառավարման տարրեր"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Ընտրեք հավելված` կառավարման տարրեր ավելացնելու համար"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one">Ավելացվեց կառավարման <xliff:g id="NUMBER_1">%s</xliff:g> տարր։</item>
-      <item quantity="other">Ավելացվեց կառավարման <xliff:g id="NUMBER_1">%s</xliff:g> տարր։</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Ավելացվեց կառավարման # տարր։}one{Ավելացվեց կառավարման # տարր։}other{Ավելացվեց կառավարման # տարր։}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Հեռացված է"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ավելացված է ընտրանիում"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ավելացված է ընտրանիում, դիրքը՝ <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Ավելացնել սալիկ"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Չավելացնել սալիկ"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Ընտրեք օգտատեր"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> հավելված ակտիվ է</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> հավելված ակտիվ է</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{Ակտիվ է # հավելված}one{Ակտիվ է # հավելված}other{Ակտիվ է # հավելված}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Նոր տեղեկություն"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ակտիվ հավելվածներ"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Այս հավելվածներն ակտիվ են և աշխատում են, նույնիսկ երբ դուք չեք օգտագործում դրանք։ Դա բարելավում է հավելվածների գործառույթները, սակայն կարող է նաև ազդել մարտկոցի աշխատաժամանակի վրա։"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Զարթուցիչը դրված է"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Տեսախցիկը և խոսափողն անջատված են"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ծանուցում}one{# ծանուցում}other{# ծանուցում}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Հեռարձակում"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Կանգնեցնել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի հեռարձակումը"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Եթե հեռարձակեք <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը կամ փոխեք աուդիո ելքը, ձեր ընթացիկ հեռարձակումը կկանգնեցվի։"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Հեռարձակել <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Փոխել աուդիո ելքը"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Անհայտ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
index a78b7a1..6015fbd 100644
--- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Անջատված է"</item>
     <item msgid="460891964396502657">"Միացված է"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Հասանելի չէ"</item>
+    <item msgid="8014986104355098744">"Անջատված է"</item>
+    <item msgid="5966994759929723339">"Միացված է"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index d492159..fb51e6b 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensor nonaktif diaktifkan"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Menghapus semua pemberitahuan."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> notifikasi lainnya di dalam.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> notifikasi lainnya di dalam.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# notifikasi lainnya di dalam.}other{# notifikasi lainnya di dalam.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Layar dikunci dalam orientasi lanskap."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Layar dikunci dalam orientasi potret."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Etalase Hidangan Penutup"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Putar Otomatis"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Putar layar otomatis"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasi"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Akses kamera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Akses mikrofon"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tersedia"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Mengaktifkan…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Penghemat Data aktif"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d perangkat</item>
-      <item quantity="one">%d perangkat</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# perangkat}other{# perangkat}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampu Senter"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera sedang digunakan"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Data seluler"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Lanjutkan sesi Anda?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulai ulang"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ya, lanjutkan"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mode tamu"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Anda sedang menggunakan mode tamu"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Menambahkan pengguna baru akan membuat Anda keluar dari mode tamu dan menghapus semua aplikasi serta data dari sesi tamu saat ini."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Batas pengguna tercapai"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Anda dapat menambahkan hingga <xliff:g id="COUNT">%d</xliff:g> pengguna.</item>
-      <item quantity="one">Hanya dapat membuat satu pengguna.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Hanya dapat membuat satu pengguna.}other{Anda dapat menambahkan maksimal # pengguna.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Hapus pengguna?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Semua aplikasi dan data pengguna ini akan dihapus."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Hapus"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Ingatkan saya"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Urungkan"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Ditunda selama <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d jam</item>
-      <item quantity="one">%d jam</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d menit</item>
-      <item quantity="one">%d menit</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# jam}=2{# jam}other{# jam}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# menit}other{# menit}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Penghemat Baterai"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Notifikasi"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Baterai"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Screenshot"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Pesan Umum"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Aplikasi Instan"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Penyiapan"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Penyimpanan"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Petunjuk"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Aplikasi Instan"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alihkan"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrol perangkat"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Pilih aplikasi untuk menambahkan kontrol"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontrol ditambahkan.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontrol ditambahkan.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol ditambahkan.}other{# kontrol ditambahkan.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Dihapus"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Difavoritkan"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Difavoritkan, posisi <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tambahkan kartu"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Jangan tambah kartu"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Pilih pengguna"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikasi aktif</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikasi aktif</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikasi aktif}other{# aplikasi aktif}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informasi baru"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplikasi aktif"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Aplikasi ini aktif dan berjalan, meski Anda tidak sedang menggunakannya. Hal ini akan meningkatkan fungsi aplikasi, tetapi juga dapat memengaruhi masa pakai baterai."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm disetel"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon nonaktif"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikasi}other{# notifikasi}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika Anda menyiarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau mengubah output, siaran saat ini akan dihentikan"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ubah output"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tidak diketahui"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml
index 6f81b29..b8eb2f7 100644
--- a/packages/SystemUI/res/values-in/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Nonaktif"</item>
     <item msgid="460891964396502657">"Aktif"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Tidak tersedia"</item>
+    <item msgid="8014986104355098744">"Nonaktif"</item>
+    <item msgid="5966994759929723339">"Aktif"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 387bdd7..7420ff1 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Slökkt á skynjurum valið"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Hreinsa allar tilkynningar."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> tilkynning í viðbót.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> tilkynningar í viðbót.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# tilkynning í viðbót.}one{# tilkynning í viðbót.}other{# tilkynningar í viðbót.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Skjárinn er læstur í langsniði."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Skjárinn er læstur í skammsniði."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Eftirréttaborð"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Sjálfvirkur snúningur"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Snúa skjá sjálfkrafa"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Staðsetning"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Skjávari"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Aðgangur að myndavél"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Aðgangur að hljóðnema"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tiltækt"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Heitur reitur"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Kveikir…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Gagnasparnaður á"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d tæki</item>
-      <item quantity="other">%d tæki</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# tæki}one{# tæki}other{# tæki}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Vasaljós"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Myndavél í notkun"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Farsímagögn"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Viltu halda áfram með lotuna?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Byrja upp á nýtt"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Já, halda áfram"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gestastilling"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Þú ert í gestastillingu"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Þegar nýjum notanda er bætt við er gestastillingu lokað og öllum forritum og gögnum úr núverandi gestalotu eytt."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Notandahámarki náð"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Þú getur bætt við allt að <xliff:g id="COUNT">%d</xliff:g> notanda.</item>
-      <item quantity="other">Þú getur bætt við allt að <xliff:g id="COUNT">%d</xliff:g> notendum.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Aðeins er hægt að stofna einn notanda.}one{Þú getur bætt við allt að # notanda.}other{Þú getur bætt við allt að # notendum.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Fjarlægja notandann?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Öllum forritum og gögnum þessa notanda verður eytt."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Fjarlægja"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Minna mig á"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Afturkalla"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Þaggað í <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d klukkustund</item>
-      <item quantity="other">%d klukkustundir</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d mínúta</item>
-      <item quantity="other">%d mínútur</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# klukkustund}=2{# klukkustundir}one{# klukkustund}other{# klukkustundir}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# mínúta}one{# mínúta}other{# mínútur}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Rafhlöðusparnaður"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Tilkynningar"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Rafhlaða"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skjámyndir"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Almenn skilaboð"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Skyndiforrit"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Uppsetning"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Geymslurými"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Vísbendingar"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Skyndiforrit"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"kveikja/slökkva"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Tækjastjórnun"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Veldu forrit til að bæta við stýringum"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> stýringu bætt við.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> stýringum bætt við.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# stýringu bætt við.}one{# stýringu bætt við.}other{# stýringum bætt við.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Fjarlægt"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Eftirlæti"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Eftirlæti, staða <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Bæta reit við"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ekki bæta reit við"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Velja notanda"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> forrit virkt</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> forrit virk</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# forrit virkt}one{# forrit virkt}other{# forrit virk}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nýjar upplýsingar"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Virk forrit"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Þessi forrit eru virk og í gangi jafnvel þótt þú sért ekki að nota þau. Þetta bætir virkni þeirra en gæti einnig haft áhrif á rafhlöðuendingu."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Vekjari stilltur"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Slökkt á myndavél og hljóðnema"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# tilkynning}one{# tilkynning}other{# tilkynningar}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Útsending í gangi"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hætta að senda út <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ef þú sendir út <xliff:g id="SWITCHAPP">%1$s</xliff:g> eða skiptir um úttak lýkur yfirstandandi útsendingu"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Senda út <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Skipta um úttak"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Óþekkt"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml
index 29bce82..12dd776 100644
--- a/packages/SystemUI/res/values-is/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Slökkt"</item>
     <item msgid="460891964396502657">"Kveikt"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Ekki í boði"</item>
+    <item msgid="8014986104355098744">"Slökkt"</item>
+    <item msgid="5966994759929723339">"Kveikt"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index f3ff5ef..e16fc15 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Opzione Sensori disattivati attiva"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Cancella tutte le notifiche."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Altre <xliff:g id="NUMBER_1">%s</xliff:g> notifiche nel gruppo.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> altra notifica nel gruppo.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# altra notifica nel gruppo.}other{Altre # notifiche nel gruppo.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Lo schermo è bloccato in orientamento orizzontale."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Lo schermo è bloccato in orientamento verticale."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Vetrina di dolci"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotazione automatica"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotazione automatica dello schermo"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Geolocalizzazione"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Salvaschermo"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accesso alla fotocamera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accesso al microfono"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponibile"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Attivazione…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Risp. dati attivo"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d dispositivi</item>
-      <item quantity="one">%d dispositivo</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispositivo}other{# dispositivi}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Torcia"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Fotocamera in uso"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Dati mobili"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vuoi continuare la sessione?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Ricomincia"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sì, continua"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modalità Ospite"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Sei in modalità Ospite"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Se aggiungi un nuovo utente, la modalità Ospite viene disattivata e vengono eliminati tutti i dati e le app della sessione Ospite corrente."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite di utenti raggiunto"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Puoi aggiungere fino a <xliff:g id="COUNT">%d</xliff:g> utenti.</item>
-      <item quantity="one">È possibile creare un solo utente.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Può essere creato un solo utente.}other{Puoi aggiungere fino a # utenti.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Rimuovere l\'utente?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Tutte le app e i dati di questo utente verranno eliminati."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Rimuovi"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Ricordamelo"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Annulla"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Posticipato di <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d ore</item>
-      <item quantity="one">%d ora</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minuti</item>
-      <item quantity="one">%d minuto</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ora}=2{# ore}other{# ore}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuto}other{# minuti}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Risparmio energetico"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Avvisi"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batteria"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Screenshot"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Messaggi generali"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"App istantanee"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configurazione"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Spazio di archiviazione"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Suggerimenti"</string>
     <string name="instant_apps" msgid="8337185853050247304">"App istantanee"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"attiva/disattiva"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controllo dispositivi"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Scegli un\'app per aggiungere controlli"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controlli aggiunti.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> controllo aggiunto.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controllo aggiunto.}other{# controlli aggiunti.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Rimosso"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Aggiunto ai preferiti"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Preferito, posizione <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Aggiungi riquadro"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Non aggiungerlo"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Seleziona utente"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> app attive</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app attiva</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{C\'è # app attiva}other{Ci sono # app attive}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nuove informazioni"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"App attive"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Queste app sono attive e in esecuzione, anche quando non le utilizzi. Questo migliora la loro funzionalità, ma influisce sulla durata della batteria."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Sveglia impostata"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotocamera e microfono non attivi"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifica}other{# notifiche}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Trasmissione in corso…"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vuoi interrompere la trasmissione dell\'app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambi l\'uscita, la trasmissione attuale viene interrotta"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Cambia uscita"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Unknown"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index 757a866..5ec557b 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Off"</item>
     <item msgid="460891964396502657">"On"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Non disponibile"</item>
+    <item msgid="8014986104355098744">"Off"</item>
+    <item msgid="5966994759929723339">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 58e4523..a889c9c 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -205,12 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"ההגדרה \'חיישנים כבויים\' פעילה"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"הסרת כל ההתראות."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="two">עוד <xliff:g id="NUMBER_1">%s</xliff:g> התראות נוספות.</item>
-      <item quantity="many">עוד <xliff:g id="NUMBER_1">%s</xliff:g> התראות.</item>
-      <item quantity="other">עוד <xliff:g id="NUMBER_1">%s</xliff:g> התראות נוספות.</item>
-      <item quantity="one">יש התראה נוספת.<xliff:g id="NUMBER_0">%s</xliff:g>.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{עוד התראה אחת (#) בקבוצה.}two{עוד # התראות בקבוצה.}many{עוד # התראות בקבוצה.}other{עוד # התראות בקבוצה.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"המסך נעול עכשיו לרוחב."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"המסך נעול כעת לאורך."</string>
     <string name="dessert_case" msgid="9104973640704357717">"מזנון קינוחים"</string>
@@ -228,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"סיבוב אוטומטי"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"סיבוב אוטומטי של המסך"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"מיקום"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"שומר מסך"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"גישה למצלמה"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"גישה למיקרופון"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"יש גישה"</string>
@@ -257,12 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"‏נקודת אינטרנט (hotspot)"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ההפעלה מתבצעת…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"חוסך הנתונים פועל"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="two">‏%d מכשירים</item>
-      <item quantity="many">‏%d מכשירים</item>
-      <item quantity="other">‏%d מכשירים</item>
-      <item quantity="one">מכשיר אחד</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{מכשיר אחד (#)}two{# מכשירים}many{# מכשירים}other{# מכשירים}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"פנס"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"המצלמה בשימוש"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"חבילת גלישה"</string>
@@ -355,13 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"האם ברצונך להמשיך בפעילות באתר?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"סשן חדש"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"כן, להמשיך"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"מצב אורח"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"התחברת במצב אורח"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"הוספת משתמש חדש תגרום ליציאה ממצב האורח ותמחק את כל האפליקציות והנתונים מהגלישה הנוכחית כאורח."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"הגעת למגבלת המשתמשים שניתן להוסיף"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="two">ניתן להוסיף עד <xliff:g id="COUNT">%d</xliff:g> משתמשים.</item>
-      <item quantity="many">ניתן להוסיף עד <xliff:g id="COUNT">%d</xliff:g> משתמשים.</item>
-      <item quantity="other">ניתן להוסיף עד <xliff:g id="COUNT">%d</xliff:g> משתמשים.</item>
-      <item quantity="one">ניתן ליצור רק משתמש אחד.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{ניתן ליצור רק משתמש אחד.}two{אפשר להוסיף עד # משתמשים.}many{אפשר להוסיף עד # משתמשים.}other{אפשר להוסיף עד # משתמשים.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"להסיר את המשתמש?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"כל האפליקציות והנתונים של המשתמש הזה יימחקו."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"הסרה"</string>
@@ -547,18 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"אשמח לקבל תזכורת"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"ביטול"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"נדחה לטיפול בעוד <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="two">שעתיים</item>
-      <item quantity="many">‏%d שעות</item>
-      <item quantity="other">‏%d שעות</item>
-      <item quantity="one">שעה</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="two">‏%d דקות</item>
-      <item quantity="many">‏%d דקות</item>
-      <item quantity="other">‏%d דקות</item>
-      <item quantity="one">דקה</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{שעה}=2{שעתיים}many{# שעות}other{# שעות}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{דקה}two{# דקות}many{# דקות}other{# דקות}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"חיסכון בסוללה"</string>
     <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>
@@ -707,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"התראות"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"סוללה"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"צילומי מסך"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"הודעות כלליות"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"אפליקציות ללא התקנה"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"הגדרה"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"אחסון"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"טיפים"</string>
     <string name="instant_apps" msgid="8337185853050247304">"אפליקציות ללא התקנה"</string>
@@ -781,12 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"החלפת מצב"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"פקדי מכשירים"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"יש לבחור אפליקציה כדי להוסיף פקדים"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="two">נוספו <xliff:g id="NUMBER_1">%s</xliff:g> פקדים.</item>
-      <item quantity="many">נוספו <xliff:g id="NUMBER_1">%s</xliff:g> פקדים.</item>
-      <item quantity="other">נוספו <xliff:g id="NUMBER_1">%s</xliff:g> פקדים.</item>
-      <item quantity="one">נוסף פקד אחד (<xliff:g id="NUMBER_0">%s</xliff:g>).</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{נוסף אמצעי בקרה אחד (#).}two{נוספו # אמצעי בקרה.}many{נוספו # אמצעי בקרה.}other{נוספו # אמצעי בקרה.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"הוסר"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"סומן כמועדף"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"סומן כמועדף, במיקום <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -943,12 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"הוספת אריח"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"לא להוסיף אריח"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"בחירת משתמש"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="two"><xliff:g id="COUNT_1">%s</xliff:g> אפליקציות פעילות</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> אפליקציות פעילות</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> אפליקציות פעילות</item>
-      <item quantity="one">אפליקציה אחת (<xliff:g id="COUNT_0">%s</xliff:g>) פעילה</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{אפליקציה אחת (#) פעילה}two{# אפליקציות פעילות}many{# אפליקציות פעילות}other{# אפליקציות פעילות}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"מידע חדש"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"אפליקציות פעילות"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"האפליקציות האלה פעילות גם כשלא משתמשים בהן. הפעולה של האפליקציות משפרת את הפונקציונליות שלהן, אבל היא עשויה גם להשפיע על חיי הסוללה."</string>
@@ -977,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ההתראה מוגדרת"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"המצלמה והמיקרופון כבויים"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{התראה אחת}two{# התראות}many{# התראות}other{# התראות}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"שידור"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"האם להפסיק לשדר את התוכן מאפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"אם משדרים את התוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g> או משנים את הפלט, השידור הנוכחי יפסיק לפעול"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"שידור תוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"שינוי הפלט"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"לא ידוע"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
index 46be20c..91577b8 100644
--- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"כבוי"</item>
     <item msgid="460891964396502657">"פועל"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"לא זמין"</item>
+    <item msgid="8014986104355098744">"כבוי"</item>
+    <item msgid="5966994759929723339">"מופעל"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index d243c06..7bfa60c 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"センサー OFF: 有効"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"通知をすべて消去。"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"他 <xliff:g id="NUMBER">%s</xliff:g> 件"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">他 <xliff:g id="NUMBER_1">%s</xliff:g> 件の通知</item>
-      <item quantity="one">他 <xliff:g id="NUMBER_0">%s</xliff:g> 件の通知</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{グループ内にあと # 件の通知があります。}other{グループ内にあと # 件の通知があります。}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"画面は横向きにロックされています。"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"画面は縦向きにロックされています。"</string>
     <string name="dessert_case" msgid="9104973640704357717">"デザートケース"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動回転"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"画面を自動回転します"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"位置情報"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"スクリーン セーバー"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"カメラへのアクセス"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"マイクへのアクセス"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"使用可能"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"アクセスポイント"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ON にしています…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"データセーバー ON"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d 台のデバイス</item>
-      <item quantity="one">%d 台のデバイス</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# 台のデバイス}other{# 台のデバイス}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ライト"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"カメラを使用中"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"モバイルデータ"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"セッションを続行しますか?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"最初から開始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"続行"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ゲストモード"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ゲストモード使用中"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"新しいユーザーを追加するとゲストモードは終了し、現在のゲスト セッションからすべてのアプリとデータが削除されます。"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ユーザー数が上限に達しました"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">最大 <xliff:g id="COUNT">%d</xliff:g> 人のユーザーを追加できます。</item>
-      <item quantity="one">作成できるユーザーは 1 人のみです。</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{作成できるユーザーは 1 人のみです。}other{最大 # 人のユーザーを追加できます。}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"ユーザーを削除しますか?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"このユーザーのアプリとデータがすべて削除されます。"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"削除"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"リマインダーの設定"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"元に戻す"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"スヌーズ: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d時間</item>
-      <item quantity="one">%d時間</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d分</item>
-      <item quantity="one">%d分</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# 時間}=2{# 時間}other{# 時間}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# 分}other{# 分}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"バッテリー セーバー"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"アラート"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"バッテリー"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"スクリーンショット"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"一般メッセージ"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"セットアップ"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ストレージ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"ヒント"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"切り替え"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"デバイス コントロール"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"コントロールを追加するアプリの選択"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> 件のコントロールを追加しました。</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> 件のコントロールを追加しました。</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# 件のコントロールを追加しました。}other{# 件のコントロールを追加しました。}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"削除済み"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"お気に入りに追加済み"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"お気に入りに追加済み、位置: <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"タイルを追加"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"タイルを追加しない"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ユーザーの選択"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> 個のアプリが実行中です</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> 個のアプリが実行中です</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# 個のアプリがアクティブです}other{# 個のアプリがアクティブです}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"最新情報"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"実行中のアプリ"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"ユーザーが使用していない状態でもアクティブで実行中のアプリの一覧です。機能面は向上しますが、バッテリー駆動時間に影響する可能性があります。"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"アラームを設定しました"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"カメラとマイクが OFF です"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 件の通知}other{# 件の通知}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ブロードキャスト"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> のブロードキャストを停止しますか?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャストしたり、出力を変更したりすると、現在のブロードキャストが停止します。"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャスト"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"出力を変更"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
index fd966da..c2a3321 100644
--- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"OFF"</item>
     <item msgid="460891964396502657">"ON"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"使用不可"</item>
+    <item msgid="8014986104355098744">"OFF"</item>
+    <item msgid="5966994759929723339">"ON"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 9ad4aa5..406aea6 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"სენსორების გამორთვა აქტიურია"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"ყველა შეტყობინების წაშლა"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">კიდევ <xliff:g id="NUMBER_1">%s</xliff:g> შეტყობინება ჯგუფში.</item>
-      <item quantity="one">კიდევ <xliff:g id="NUMBER_0">%s</xliff:g> შეტყობინება ჯგუფში.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{კიდევ # შეტყობინება.}other{კიდევ # შეტყობინება.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ეკრანი დაბლოკილია თარაზულ ორიენტაციაში"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ეკრანი დაბლოკილია პორტრეტის ორიენტაციაში."</string>
     <string name="dessert_case" msgid="9104973640704357717">"სადესერტო ყუთი"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ავტოროტაცია"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ეკრანის ავტომატური შეტრიალება"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"მდებარეობა"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"ეკრანმზოგი"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"კამერაზე წვდომა"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"მიკროფონზე წვდომა"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ხელმისაწვდომი"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"წვდომის წერტილი"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ირთვება…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"მონაცემთა დამზოგველი ჩართულია"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d მოწყობილობა</item>
-      <item quantity="one">%d მოწყობილობა</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# მოწყობილობა}other{# მოწყობილობა}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ფანარი"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"კამერა გამოიყენება"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"მობილური ინტერნეტი"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"გსურთ, თქვენი სესიის გაგრძელება?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ხელახლა დაწყება"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"დიახ, გავაგრძელოთ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"სტუმრის რეჟიმი"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"თქვენ სტუმრის რეჟიმში ხართ"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"თუ ახალ მომხმარებელს დაამატებთ, სტუმრის რეჟიმი დაიხურება და სტუმრის რეჟიმის მიმდინარე სესიიდან ყველა აპი და მონაცემი წაიშლება."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"მიღწეულია მომხმარებელთა ლიმიტი"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">შესაძლებელია <xliff:g id="COUNT">%d</xliff:g>-მდე მომხმარებლის დამატება.</item>
-      <item quantity="one">შესაძლებელია მხოლოდ ერთი მომხმარებლის შექმნა.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{შესაძლებელია მხოლოდ ერთი მომხმარებლის შექმნა.}other{შეგიძლიათ #-მდე მომხმარებლის დამატება.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"გსურთ მომხმარებლის წაშლა?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ამ მომხმარებლის ყველა აპი და მონაცემი წაიშლება."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"წაშლა"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"შემახსენე"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"მოქმედების გაუქმება"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"ჩაჩუმებული იქნება <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d საათი</item>
-      <item quantity="one">%d საათი</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d წუთი</item>
-      <item quantity="one">%d წუთი</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# საათი}=2{# საათი}other{# საათი}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# წუთი}other{# წუთი}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"ბატარეის დამზოგი"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"გაფრთხილებები"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ბატარეა"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"ეკრანის ანაბეჭდები"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"ზოგადი შეტყობინებები"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"მყისიერი აპები"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"დაყენება"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"მეხსიერება"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"მინიშნებები"</string>
     <string name="instant_apps" msgid="8337185853050247304">"მყისიერი აპები"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"გადართვა"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"მოწყობილ. მართვის საშუალებები"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"აირჩიეთ აპი მართვის საშუალებების დასამატებლად"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">დაემატა <xliff:g id="NUMBER_1">%s</xliff:g> მართვის საშუალება.</item>
-      <item quantity="one">დაემატა <xliff:g id="NUMBER_0">%s</xliff:g> მართვის საშუალება.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{დაემატა მართვის # საშუალება.}other{დაემატა მართვის # საშუალება.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ამოიშალა"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"რჩეულებშია"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"რჩეულებშია, პოზიციაზე <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"დაემატოს"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"არ დაემატოს"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"მომხმარებლის არჩევა"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other">აქტიურია <xliff:g id="COUNT_1">%s</xliff:g> აპი</item>
-      <item quantity="one">აქტიურია <xliff:g id="COUNT_0">%s</xliff:g> აპი</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{აქტიურია # აპი}other{აქტიურია # აპი}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ახალი ინფორმაცია"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"აქტიური აპები"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"ეს აპები აქტიურია და გაშვებულია, მაშინაც კი, როცა მათ არ იყენებთ. ეს აუმჯობესებს მათ ფუნქციურობას, მაგრამ შეიძლება ბატარეის მუშაობის ხანგრძლივობაზე იმოქმედოს."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"მაღვიძარა დაყენებულია"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"კამერა და მიკროფონი გამორთულია"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# შეტყობინება}other{# შეტყობინება}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"იწყებთ მაუწყებლობას"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"გსურთ <xliff:g id="APP_NAME">%1$s</xliff:g>-ის ტრანსლაციის შეჩერება?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაციის შემთხვევაში ან აუდიოს გამოსასვლელის შეცვლისას, მიმდინარე ტრანსლაცია შეჩერდება"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაცია"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"აუდიოს გამოსასვლელის შეცვლა"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"უცნობი"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
index 0c7d5af..c951874 100644
--- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"გამორთვა"</item>
     <item msgid="460891964396502657">"ჩართვა"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"მიუწვდომელია"</item>
+    <item msgid="8014986104355098744">"გამორთულია"</item>
+    <item msgid="5966994759929723339">"ჩართულია"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 695921f..4f5b7e0 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Датчиктер өшірулі."</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Барлық хабарларды жойыңыз."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Ішінде тағы <xliff:g id="NUMBER_1">%s</xliff:g> хабарландыру.</item>
-      <item quantity="one">Ішінде тағы <xliff:g id="NUMBER_0">%s</xliff:g> хабарландыру.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Ішінде тағы # хабарландыру бар.}other{Ішінде тағы # хабарландыру бар.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Экран ландшафт бағытында бекітілген."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Экран портрет бағытында бекітілген."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Десерт жағдайы"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматты түрде бұру"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматты айналатын экран"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Локация"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Скринсейвер"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Камераны пайдалану"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Микрофонды пайдалану"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Қолжетімді"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Хотспот"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Қосылуда…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Трафикті үнемдеу режимі қосулы"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d құрылғы</item>
-      <item quantity="one">%d құрылғы</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# құрылғы}other{# құрылғы}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Қалта шам"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Камера қолданылып жатыр"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мобильдік деректер"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансты жалғастыру керек пе?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Қайта бастау"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Иә, жалғастыру"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Қонақ режимі"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Сіз қонақ режиміндесіз"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Жаңа пайдаланушы қосылған кезде, қонақ режимі жабылады, ағымдағы қонақ сеансындағы барлық қолданба мен дерек жойылады."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Пайдаланушылар саны шегіне жетті"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> пайдаланушыға дейін енгізуге болады.</item>
-      <item quantity="one">Тек бір пайдаланушыны жасауға болады.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Тек бір пайдаланушыны жасауға болады.}other{Ең көбі # пайдаланушы қосуға болады.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Пайдаланушы жойылсын ба?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Осы пайдаланушының барлық қолданбалары мен деректері жойылады."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Жою"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Есіме салу"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Қайтару"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> кейінге қалдырылды"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d сағат</item>
-      <item quantity="one">%d сағат</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d минут</item>
-      <item quantity="one">%d минут</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# сағат}=2{# сағат}other{# сағат}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# минут}other{# минут}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Батареяны үнемдеу режимі"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Ескертулер"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Батарея"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Скриншоттар"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Жалпы хабарлар"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Реттеу"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Жад"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Кеңестер"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ауыстыру"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Құрылғыны басқару элементтері"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Басқару элементтері қосылатын қолданбаны таңдаңыз"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> басқару элементі енгізілді.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> басқару элементі енгізілді.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# басқару элементі қосылды.}other{# басқару элементі қосылды.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Өшірілді"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Таңдаулыларға қосылды"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Таңдаулыларға қосылды, <xliff:g id="NUMBER">%d</xliff:g>-позиция"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Бөлшек қосу"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Бөлшек қоспау"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Пайдаланушыны таңдау"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> қолданба қосылып тұр.</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> қолданба қосылып тұр.</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# қолданба қосылып тұр.}other{# қолданба қосылып тұр.}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Жаңа ақпарат"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Істеп тұрған қолданбалар"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Бұл қолданбаларды пайдаланбасаңыз да, олар іске қосылып, жұмыс істеп тұрады. Бұл олардың жұмысын жақсартады, алайда батарея жұмысының ұзақтығына да әсер етуі мүмкін."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Оятқыш орнатылды"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера мен микрофон өшірулі"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# хабарландыру}other{# хабарландыру}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Таратуда"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын таратуды тоқтатасыз ба?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын таратсаңыз немесе аудио шығысын өзгертсеңіз, қазіргі тарату сеансы тоқтайды."</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын тарату"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Аудио шығысын өзгерту"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Белгісіз"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
index 5466663..c312b49 100644
--- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Өшірулі"</item>
     <item msgid="460891964396502657">"Қосулы"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Қолжетімді емес."</item>
+    <item msgid="8014986104355098744">"Өшірулі."</item>
+    <item msgid="5966994759929723339">"Қосулы."</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 9870649..a921cb9 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"ឧបករណ៍​ចាប់សញ្ញា​បានបិទ"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"សម្អាត​ការ​ជូន​ដំណឹង​ទាំងអស់។"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">មានការជូនដំណឹង <xliff:g id="NUMBER_1">%s</xliff:g> ទៀតនៅខាងក្នុង</item>
-      <item quantity="one">មានការជូនដំណឹង <xliff:g id="NUMBER_0">%s</xliff:g> ទៀតនៅខាងក្នុង</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{មានការជូនដំណឹង # ទៀតនៅខាងក្នុង។}other{មាន​ការ​ជូនដំណឹង # ទៀត​នៅ​ខាង​ក្នុង។}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"អេក្រង់​ជាប់​សោ​ក្នុង​ទិស​ផ្ដេក។"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"បា​ន​ចាក់​សោ​អេក្រង់​​ក្នុង​ទិស​បញ្ឈរ។"</string>
     <string name="dessert_case" msgid="9104973640704357717">"ករណី Dessert"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"បង្វិល​ស្វ័យ​ប្រវត្តិ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"បង្វិលអេក្រង់ស្វ័យប្រវត្តិ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ទី​តាំង​"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"ធាតុរក្សាអេក្រង់"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"ការចូលប្រើ​កាមេរ៉ា"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"ការចូលប្រើ​មីក្រូហ្វូន"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"អាចចូលប្រើបាន"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ហតស្ប៉ត"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"កំពុង​បើក..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"កម្មវិធីសន្សំសំចៃទិន្នន័យបានបើក"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">ឧបករណ៍ %d</item>
-      <item quantity="one">ឧបករណ៍ %d</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{ឧបករណ៍ #}other{ឧបករណ៍ #}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ពិល"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"កំពុងប្រើ​កាមេរ៉ា"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"ទិន្នន័យ​ទូរសព្ទចល័ត"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"តើ​អ្នក​ចង់​បន្ត​វគ្គ​របស់​អ្នក​ទេ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ចាប់ផ្ដើមសាជាថ្មី"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"បាទ​/ចាស ​បន្ត"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"មុខងារ​ភ្ញៀវ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"អ្នកស្ថិតនៅក្នុងមុខងារភ្ញៀវ"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ការបញ្ចូលអ្នកប្រើប្រាស់ថ្មីនឹងធ្វើឱ្យចាកចេញពីមុខងារភ្ញៀវ និងលុបកម្មវិធីនិងទិន្នន័យទាំងអស់ចេញពីវគ្គភ្ញៀវបច្ចុប្បន្ន។"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"​បាន​ឈាន​ដល់ចំនួន​កំណត់អ្នកប្រើប្រាស់"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">អ្នកអាចបញ្ចូល​អ្នក​ប្រើប្រាស់បាន​រហូតដល់ <xliff:g id="COUNT">%d</xliff:g> នាក់។</item>
-      <item quantity="one">អាច​បង្កើត​អ្នក​ប្រើប្រាស់​បាន​​តែម្នាក់ប៉ុណ្ណោះ។</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{អាច​បង្កើត​អ្នក​ប្រើប្រាស់​បាន​​តែម្នាក់ប៉ុណ្ណោះ។}other{អ្នកអាចបញ្ចូល​អ្នកប្រើប្រាស់​បាន​រហូតដល់ # នាក់។}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"យកអ្នកប្រើចេញ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"កម្មវិធី និងទិន្នន័យទាំងអស់របស់អ្នកប្រើនេះនឹងត្រូវបានលុប។"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"ដកចេញ"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"រំលឹក​ខ្ញុំ"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"ត្រឡប់វិញ"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"បាន​ផ្អាក​រយៈពេល <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d ម៉ោង</item>
-      <item quantity="one">%d ម៉ោង</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d នាទី</item>
-      <item quantity="one">%d នាទី</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ម៉ោង}=2{# ម៉ោង}other{# ម៉ោង}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# នាទី}other{# នាទី}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"មុខងារ​សន្សំ​ថ្ម"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"ការជូនដំណឹង"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ថ្ម"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"រូបថត​អេក្រង់"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"សារ​ទូទៅ"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"កម្មវិធី​ប្រើ​ភ្លាមៗ"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"ការរៀបចំ"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ទំហំផ្ទុក"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"ការ​សម្រួល"</string>
     <string name="instant_apps" msgid="8337185853050247304">"កម្មវិធី​ប្រើ​ភ្លាមៗ"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"បិទ/បើក"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"ជ្រើសរើស​កម្មវិធីដែលត្រូវបញ្ចូល​ផ្ទាំងគ្រប់គ្រង"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">បានបញ្ចូល​ការគ្រប់គ្រង <xliff:g id="NUMBER_1">%s</xliff:g>។</item>
-      <item quantity="one">បានបញ្ចូល​ការគ្រប់គ្រង <xliff:g id="NUMBER_0">%s</xliff:g>។</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{បានបញ្ចូល​ការគ្រប់គ្រង #។}other{បានបញ្ចូល​ការគ្រប់គ្រង #។}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"បានដកចេញ"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"បានដាក់ជា​សំណព្វ"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"បានដាក់ជា​សំណព្វ ទីតាំង​ទី <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"បញ្ចូល​ប្រអប់"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"កុំ​បញ្ចូល​ប្រអប់"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ជ្រើសរើសអ្នកប្រើប្រាស់"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other">កម្មវិធី <xliff:g id="COUNT_1">%s</xliff:g> កំពុងដំណើរការ</item>
-      <item quantity="one">កម្មវិធី <xliff:g id="COUNT_0">%s</xliff:g> កំពុងដំណើរការ</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{កម្មវិធី # កំពុងដំណើរការ}other{កម្មវិធី # កំពុងដំណើរការ}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ព័ត៌មានថ្មី"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"កម្មវិធីសកម្ម"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"កម្មវិធីទាំងនេះគឺសកម្ម និងកំពុងដំណើរការ ទោះបីជាអ្នកមិនកំពុងប្រើវាក៏ដោយ។ ដំណើរការនេះធ្វើឱ្យមុខងាររបស់កម្មវិធីទាំងនេះប្រសើរឡើង ប៉ុន្តែវាក៏អាចប៉ះពាល់ដល់កម្រិតថាមពលថ្មផងដែរ។"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"រូបកំណត់​ម៉ោងរោទ៍"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"កាមេរ៉ា និង​មីក្រូហ្វូន​ត្រូវបានបិទ"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{ការ​ជូន​ដំណឹង #}other{ការ​ជូនដំណឹង #}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ការផ្សាយ"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"បញ្ឈប់ការផ្សាយ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ប្រសិនបើអ្នក​ផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ឬប្ដូរឧបករណ៍បញ្ចេញសំឡេង ការផ្សាយបច្ចុប្បន្នរបស់អ្នកនឹង​បញ្ឈប់"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ការផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ប្ដូរឧបករណ៍បញ្ចេញសំឡេង"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"មិនស្គាល់"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml
index f4830f5..ec748cf 100644
--- a/packages/SystemUI/res/values-km/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"បិទ"</item>
     <item msgid="460891964396502657">"បើក"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"មិនមានទេ"</item>
+    <item msgid="8014986104355098744">"បិទ"</item>
+    <item msgid="5966994759929723339">"បើក"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index ca543425..46fa9a4 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"ಸೆನ್ಸರ್‌ಗಳು ಆಫ್ ಆಗಿವೆ"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸು."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಅಧಿಸೂಚನೆಗಳು ಒಳಗಿವೆ.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಅಧಿಸೂಚನೆಗಳು ಒಳಗಿವೆ.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{ಇನ್ನೂ # ಅಧಿಸೂಚನೆ ಒಳಗಿದೆ.}one{ಇನ್ನೂ # ಅಧಿಸೂಚನೆಗಳು ಒಳಗಿವೆ.}other{ಇನ್ನೂ # ಅಧಿಸೂಚನೆಗಳು ಒಳಗಿವೆ.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ಪರದೆಯನ್ನು ಲ್ಯಾಂಡ್‌ಸ್ಕೇಪ್ ಓರಿಯಂಟೇಶನ್‍ನಲ್ಲಿ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ಪರದೆಯನ್ನು ಪೋರ್ಟ್ರೇಟ್ ಓರಿಯಂಟೇಶನ್‍ನಲ್ಲಿ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="dessert_case" msgid="9104973640704357717">"ಡೆಸರ್ಟ್ ಕೇಸ್"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ಸ್ವಯಂ-ತಿರುಗುವಿಕೆ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ಪರದೆಯನ್ನು ಸ್ವಯಂ-ತಿರುಗಿಸಿ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ಸ್ಥಳ"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"ಸ್ಕ್ರೀನ್ ಸೇವರ್"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"ಕ್ಯಾಮರಾ ಆ್ಯಕ್ಸೆಸ್"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"ಮೈಕ್ ಆ್ಯಕ್ಸೆಸ್"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ಲಭ್ಯವಿದೆ"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ಹಾಟ್‌ಸ್ಪಾಟ್"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ಆನ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ಡೇಟಾ ಸೇವರ್ ಆನ್ ಆಗಿದೆ"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d ಸಾಧನಗಳು</item>
-      <item quantity="other">%d ಸಾಧನಗಳು</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# ಸಾಧನ}one{# ಸಾಧನಗಳು}other{# ಸಾಧನಗಳು}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ಫ್ಲಾಶ್‌ಲೈಟ್‌"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"ಕ್ಯಾಮರಾ ಬಳಕೆಯಲ್ಲಿದೆ"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"ಮೊಬೈಲ್ ಡೇಟಾ"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ನಿಮ್ಮ ಸೆಷನ್‌ ಮುಂದುವರಿಸಲು ಇಚ್ಚಿಸುವಿರಾ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ಹೌದು, ಮುಂದುವರಿಸಿ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ಅತಿಥಿ ಮೋಡ್"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ನೀವು ಅತಿಥಿ ಮೋಡ್‌ನಲ್ಲಿದ್ದೀರಿ"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸುವುದರಿಂದ ಅತಿಥಿ ಮೋಡ್‌ನಿಂದ ನಿರ್ಗಮಿಸುತ್ತದೆ ಮತ್ತು ಪ್ರಸ್ತುತ ಅತಿಥಿ ಸೆಶನ್‌ನಿಂದ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ಬಳಕೆದಾರರ ಮಿತಿ ತಲುಪಿದೆ"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">ನೀವು <xliff:g id="COUNT">%d</xliff:g> ಬಳಕೆದಾರರವರೆಗೆ ಸೇರಿಸಬಹುದು.</item>
-      <item quantity="other">ನೀವು <xliff:g id="COUNT">%d</xliff:g> ಬಳಕೆದಾರರವರೆಗೆ ಸೇರಿಸಬಹುದು.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{ಒಬ್ಬ ಬಳಕೆದಾರರನ್ನು ಮಾತ್ರ ರಚಿಸಬಹುದು.}one{ನೀವು # ಬಳಕೆದಾರರವರೆಗೆ ಸೇರಿಸಬಹುದು.}other{ನೀವು # ಬಳಕೆದಾರರವರೆಗೆ ಸೇರಿಸಬಹುದು.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"ಬಳಕೆದಾರರನ್ನು ತೆಗೆದುಹಾಕುವುದೇ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ಈ ಬಳಕೆದಾರರ ಎಲ್ಲಾ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುವುದು."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"ತೆಗೆದುಹಾಕಿ"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"ನನಗೆ ಜ್ಞಾಪಿಸಿ"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ಗೆ ಸ್ನೂಜ್ ಮಾಡಲಾಗಿದೆ"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d ಗಂಟೆಗಳು</item>
-      <item quantity="other">%d ಗಂಟೆಗಳು</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d ನಿಮಿಷಗಳು</item>
-      <item quantity="other">%d ನಿಮಿಷಗಳು</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ಗಂಟೆ}=2{# ಗಂಟೆಗಳು}one{# ಗಂಟೆಗಳು}other{# ಗಂಟೆಗಳು}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# ನಿಮಿಷ}one{# ನಿಮಿಷಗಳು}other{# ನಿಮಿಷಗಳು}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"ಬ್ಯಾಟರಿ ಸೇವರ್‌‌"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"ಅಲರ್ಟ್‌ಗಳು"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ಬ್ಯಾಟರಿ"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳು"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"ಸಾಮಾನ್ಯ ಸಂದೇಶಗಳು"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"ಸೆಟಪ್"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ಸಂಗ್ರಹಣೆ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"ಸುಳಿವುಗಳು"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ಟಾಗಲ್ ಮಾಡಿ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ಸಾಧನ ನಿಯಂತ್ರಣಗಳು"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲು ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ನಿಯಂತ್ರಣವನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}one{# ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}other{# ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ಮೆಚ್ಚಲಾಗಿರುವುದು"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ಮೆಚ್ಚಲಾಗಿರುವುದು, ಸ್ಥಾನ <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ಟೈಲ್ ಅನ್ನು ಸೇರಿಸಿ"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ಟೈಲ್ ಅನ್ನು ಸೇರಿಸಬೇಡಿ"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ಬಳಕೆದಾರರನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ಆ್ಯಪ್‌ಗಳು ಸಕ್ರಿಯವಾಗಿವೆ</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ಆ್ಯಪ್‌ಗಳು ಸಕ್ರಿಯವಾಗಿವೆ</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ಆ್ಯಪ್ ಸಕ್ರಿಯವಾಗಿದೆ}one{# ಆ್ಯಪ್‌ಗಳು ಸಕ್ರಿಯವಾಗಿವೆ}other{# ಆ್ಯಪ್‌ಗಳು ಸಕ್ರಿಯವಾಗಿವೆ}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ಹೊಸ ಮಾಹಿತಿ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ಸಕ್ರಿಯ ಆ್ಯಪ್‌ಗಳು"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"ಈ ಆ್ಯಪ್‌ಗಳನ್ನು ಬಳಸದಿದ್ದರೂ ಸಹ, ಅವುಗಳು ಸಕ್ರಿಯವಾಗಿರುತ್ತವೆ ಮತ್ತು ಚಾಲನೆಯಲ್ಲಿರುತ್ತವೆ. ಇದು ಅವುಗಳ ಫಂಕ್ಷನಾಲಿಟಿಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ, ಆದರೆ ಇದು ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಬಹುದು."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ಅಲಾರಾಂ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ಅಧಿಸೂಚನೆ}one{# ಅಧಿಸೂಚನೆಗಳು}other{# ಅಧಿಸೂಚನೆಗಳು}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ಪ್ರಸಾರ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಪ್ರಸಾರವನ್ನು ನಿಲ್ಲಿಸಬೇಕೆ?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ನೀವು <xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿದರೆ ಅಥವಾ ಔಟ್‌ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿದರೆ, ನಿಮ್ಮ ಪ್ರಸ್ತುತ ಪ್ರಸಾರವು ಸ್ಥಗಿತಗೊಳ್ಳುತ್ತದೆ"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿ"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ಔಟ್‌ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿ"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ಅಪರಿಚಿತ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index 5cf2f5c..864a607 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"ಆಫ್ ಮಾಡಿ"</item>
     <item msgid="460891964396502657">"ಆನ್ ಮಾಡಿ"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"ಲಭ್ಯವಿಲ್ಲ"</item>
+    <item msgid="8014986104355098744">"ಆಫ್ ಮಾಡಿ"</item>
+    <item msgid="5966994759929723339">"ಆನ್ ಮಾಡಿ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 35fc411..47c2646 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"센서 끄기 활성화"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"모든 알림 지우기"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"<xliff:g id="NUMBER">%s</xliff:g>개 더보기"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g>개 알림 더보기</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g>개 알림 더보기</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{그룹에 알림이 #개 더 있습니다.}other{그룹에 알림이 #개 더 있습니다.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"화면이 가로 방향으로 잠겨 있습니다."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"화면이 세로 방향으로 잠겨 있습니다."</string>
     <string name="dessert_case" msgid="9104973640704357717">"디저트 케이스"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"자동 회전"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"화면 자동 회전"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"위치"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"화면 보호기"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"카메라 액세스"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"마이크 액세스"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"사용 가능"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"핫스팟"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"켜는 중..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"데이터 절약 모드"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">기기 %d대</item>
-      <item quantity="one">기기 %d대</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{기기 #대}other{기기 #대}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"손전등"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"카메라 사용 중"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"모바일 데이터"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"세션을 계속 진행하시겠습니까?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"다시 시작"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"계속 진행"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"게스트 모드"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"게스트 모드 사용 중"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"새로운 사용자를 추가하면 게스트 모드가 종료되고 기존 게스트 세션의 모든 앱과 데이터가 삭제됩니다."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"사용자 제한 도달"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">사용자를 <xliff:g id="COUNT">%d</xliff:g>명까지 추가할 수 있습니다.</item>
-      <item quantity="one">사용자를 한 명만 만들 수 있습니다.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{사용자는 한 명만 등록할 수 있습니다.}other{사용자는 최대 #명을 등록할 수 있습니다.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"사용자를 삭제할까요?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"이 사용자의 모든 앱과 데이터가 삭제됩니다."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"삭제"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"알림 받기"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"실행취소"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> 동안 일시 중지됨"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d시간</item>
-      <item quantity="one">%d시간</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d분</item>
-      <item quantity="one">%d분</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{#시간}=2{#시간}other{#시간}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{#분}other{#분}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"절전 모드"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"알림"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"배터리"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"스크린샷"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"일반 메시지"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"인스턴트 앱"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"설정"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"저장용량"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"힌트"</string>
     <string name="instant_apps" msgid="8337185853050247304">"인스턴트 앱"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"전환"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"기기 컨트롤"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"컨트롤을 추가할 앱을 선택하세요"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">제어 기능 <xliff:g id="NUMBER_1">%s</xliff:g>개가 추가되었습니다.</item>
-      <item quantity="one">제어 기능 <xliff:g id="NUMBER_0">%s</xliff:g>개가 추가되었습니다.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{설정이 #개 추가되었습니다.}other{설정이 #개 추가되었습니다.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"삭제됨"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"즐겨찾기에 추가됨"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"즐겨찾기에 추가됨, 위치 <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"타일 추가"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"타일 추가 안함"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"사용자 선택"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other">활성 상태인 앱 <xliff:g id="COUNT_1">%s</xliff:g>개</item>
-      <item quantity="one">활성 상태인 앱 <xliff:g id="COUNT_0">%s</xliff:g>개</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{활성 상태인 앱 #개}other{활성 상태인 앱 #개}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"새로운 정보"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"활성 상태의 앱"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"사용 중이 아닐 때도 활성화되어 실행되는 앱입니다. 이 경우 앱 기능성이 향상되지만 배터리 수명에 영향을 줄 수도 있습니다."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"알람이 설정되었습니다."</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"카메라 및 마이크가 사용 중지되었습니다."</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{알림 #개}other{알림 #개}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"방송 중"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> 방송을 중지하시겠습니까?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 앱을 방송하거나 출력을 변경하면 기존 방송이 중단됩니다"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 방송"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"출력 변경"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"알 수 없음"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index 3244ffa..c52c17c 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"꺼짐"</item>
     <item msgid="460891964396502657">"켜짐"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"사용 불가"</item>
+    <item msgid="8014986104355098744">"꺼짐"</item>
+    <item msgid="5966994759929723339">"켜짐"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 9c35b6f..437708a 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"\"Сенсорлорду өчүрүүнү\" активдештирүү"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Бардык билдирмелерди өчүрүү."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Дагы <xliff:g id="NUMBER_1">%s</xliff:g> эскертме бар.</item>
-      <item quantity="one">Дагы <xliff:g id="NUMBER_0">%s</xliff:g> эскертме бар.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Дагы # билдирме бар.}other{Дагы # билдирме бар.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Экран туурасынан турган бойдон бекитилген."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Экран тикесинен турган бойдон бекитилген."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Десерт себети"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Авто буруу"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Экранды авто буруу"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Жайгашкан жер"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Көшөгө"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Камера"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Микрофон"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Жеткиликтүү"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Байланыш түйүнү"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Күйгүзүлүүдө…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Трафикти үнөмдөө күйүк"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d түзмөк</item>
-      <item quantity="one">%d түзмөк</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# түзмөк}other{# түзмөк}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Кол чырак"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Камера колдонулууда"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мобилдик Интернет"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансыңызды улантасызбы?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Кайра баштоо"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ооба, уланта берели"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Конок режими"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Конок режиминдесиз"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Жаңы колдонуучуну кошсоңуз, конок режими жабылып, учурдагы конок сеансындагы бардык колдонмолор жана башка нерселер өчүп калат."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Дагы колдонуучу кошууга болбойт"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> колдонуучуга чейин кошууга болот.</item>
-      <item quantity="one">Бир колдонуучуну гана кошууга болот.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Бир колдонуучуну гана кошууга болот.}other{# чейин колдонуучу кошсоңуз болот.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Колдонуучу алынып салынсынбы?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Бул колдонуучунун бардык колдонмолору жана маалыматтары өчүрүлөт."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Өчүрүү"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Эскертилсин"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Кайтаруу"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> тындырылды"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d саат</item>
-      <item quantity="one">%d саат</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d мүнөт</item>
-      <item quantity="one">%d мүнөт</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# саат}=2{# саат}other{# саат}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# мүнөт}other{# мүнөт}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Батареяны үнөмдөгүч"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Эскертүүлөр"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Батарея"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Скриншоттор"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Жалпы билдирүүлөр"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Ыкчам ачылуучу колдонмолор"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Тууралоо"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Сактагыч"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Кеңештер"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Ыкчам ачылуучу колдонмолор"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"өчүрүү/күйгүзүү"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Түзмөктү башкаруу элементтери"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Башкаруу элементтери кошула турган колдонмону тандоо"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> башкаруу элементи кошулду.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> башкаруу элементи кошулду.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# көзөмөл кошулду.}other{# көзөмөл кошулду.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Өчүрүлдү"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Сүйүктүүлөргө кошулду"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Сүйүктүүлөргө <xliff:g id="NUMBER">%d</xliff:g>-позицияга кошулду"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Ыкчам баскыч кошуу"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ыкчам баскыч кошулбасын"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Колдонуучуну тандоо"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> колдонмо иштеп жатат</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> колдонмо иштеп жатат</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# колдонмо иштеп жатат}other{# колдонмо иштеп жатат}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Жаңы маалымат"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Жигердүү колдонмолор"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Бул колдонмолор жабылып турса да, активдүү болуп, иштеп турушат. Алардын функционалдуулугу жакшырат, бирок батареянын кубатынын мөөнөтүнө кедергиси тийиши мүмкүн."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Ойготкуч коюлду"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера жана микрофон өчүк"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# билдирме}other{# билдирме}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Кеңири таратуу"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда кабарлоо токтотулсунбу?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Эгер <xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарласаңыз же аудионун чыгуусун өзгөртсөңүз, учурдагы кабарлоо токтотулат"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарлоо"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Аудионун чыгуусун өзгөртүү"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Белгисиз"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
index 5518fcc..f872926 100644
--- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Өчүк"</item>
     <item msgid="460891964396502657">"Күйүк"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Жеткиликсиз"</item>
+    <item msgid="8014986104355098744">"Өчүк"</item>
+    <item msgid="5966994759929723339">"Күйүк"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 87ed408..8e84afe 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"ປິດການເຮັດວຽກຂອງເຊັນເຊີແລ້ວ"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"ລຶບການແຈ້ງເຕືອນທັງໝົດ."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">ມີ <xliff:g id="NUMBER_1">%s</xliff:g> ການແຈ້ງເຕືອນເພີ່ມເຕີມຢູ່ທາງໃນ.</item>
-      <item quantity="one">ມີ <xliff:g id="NUMBER_0">%s</xliff:g> ການແຈ້ງເຕືອນເພີ່ມເຕີມຢູ່ທາງໃນ.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{ມີ # ການແຈ້ງເຕືອນເພີ່ມເຕີມຢູ່ທາງໃນ.}other{ມີ # ການແຈ້ງເຕືອນເພີ່ມເຕີມຢູ່ທາງໃນ.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ໜ້າຈໍຖືກລັອກໃນລວງນອນ."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ໜ້າຈໍຖືກລັອກຢູ່ໃນໂໝດແນວຕັ້ງ."</string>
     <string name="dessert_case" msgid="9104973640704357717">"ກ່ອງຂອງຫວານ"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ໝຸນ​ອັດ​ຕະ​ໂນ​ມັດ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ໝຸນໜ້າຈໍອັດຕະໂນມັດ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ສະຖານທີ່"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"ພາບພັກໜ້າຈໍ"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"ການເຂົ້າເຖິງກ້ອງຖ່າຍຮູບ"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"ການເຂົ້າເຖິງໄມ"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ສາມາດໃຊ້ໄດ້"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"​ຮັອດ​ສະ​ປອດ"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ກຳລັງເປີດ..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ເປີດຕົວປະຢັດອິນເຕີເນັດຢູ່"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d ອຸປະກອນ</item>
-      <item quantity="one">%d ອຸປະກອນ</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{ອຸປະກອນ # ເຄື່ອງ}other{ອຸປະກອນ # ເຄື່ອງ}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"​ໄຟ​ສາຍ"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"ມີການໃຊ້ກ້ອງຖ່າຍຮູບຢູ່"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"ອິນເຕີເນັດມືຖື"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ທ່ານ​ຕ້ອງ​ການ​ສືບ​ຕໍ່​ເຊດ​ຊັນ​ຂອງ​ທ່ານບໍ່?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ເລີ່ມຕົ້ນໃຫມ່"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"​ຕົກ​ລົງ, ດຳ​ເນີນ​ການ​ຕໍ່"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ໂໝດແຂກ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ທ່ານກຳລັງຢູ່ໃນໂໝດແຂກ"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ການເພີ່ມຜູ້ໃຊ້ໃໝ່ຈະອອກຈາກໂໝດແຂກ ແລະ ລຶບແອັບ ແລະ ຂໍ້ມູນທັງໝົດອອກຈາກເຊດຊັນແຂກປັດຈຸບັນ."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ຮອດຂີດຈຳກັດຜູ້ໃຊ້ແລ້ວ"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">ທ່ານສາມາດເພີ່ມໄດ້ສູງສຸດ <xliff:g id="COUNT">%d</xliff:g> ຄົນ.</item>
-      <item quantity="one">ສາມາດສ້າງໄດ້ໜຶ່ງຜູ້ໃຊ້ເທົ່ານັ້ນ.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{ສາມາດສ້າງຜູ້ໃຊ້ໄດ້ຄົນດຽວເທົ່ານັ້ນ.}other{ທ່ານສາມາດເພີ່ມຜູ້ໃຊ້ໄດ້ສູງສຸດ # ຄົນ.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"ລຶບຜູ້ໃຊ້ອອກບໍ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ທຸກ​ແອັບ ແລະ ຂໍ້​ມູນ​ຂອງ​ຜູ້​ໃຊ້​ນີ້​ຈະ​ຖືກ​ລຶບ."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"ເອົາ​ອອກ"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"ແຈ້ງເຕືອນຂ້ອຍ"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"ຍົກເລີກ"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"ເລື່ອນໄປ <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ນາທີແລ້ວ"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d ຊົ່ວໂມງ</item>
-      <item quantity="one">%d ຊົ່ວໂມງ</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d ນາທີ</item>
-      <item quantity="one">%d ນາທີ</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ຊົ່ວໂມງ}=2{# ຊົ່ວໂມງ}other{# ຊົ່ວໂມງ}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# ນາທີ}other{# ນາທີ}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"ຕົວປະຢັດ​ແບັດເຕີຣີ"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"ການແຈ້ງເຕືອນ"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ແບັດເຕີຣີ"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"ຮູບຖ່າຍໜ້າຈໍ"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"ຂໍ້ຄວາມທົ່ວໄປ"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"ອິນສະແຕນແອັບ"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"ຕັ້ງຄ່າ"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ບ່ອນເກັບຂໍ້ມູນ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"ຄຳໃບ້"</string>
     <string name="instant_apps" msgid="8337185853050247304">"ອິນສະແຕນແອັບ"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ສະຫຼັບ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ການຄວບຄຸມອຸປະກອນ"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"ເລືອກແອັບເພື່ອເພີ່ມການຄວບຄຸມ"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">ເພີ່ມ <xliff:g id="NUMBER_1">%s</xliff:g> ການຄວບຄຸມແລ້ວ.</item>
-      <item quantity="one">ເພີ່ມ <xliff:g id="NUMBER_0">%s</xliff:g> ການຄວບຄຸມແລ້ວ.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ເພີ່ມ # ການຄວບຄຸມແລ້ວ.}other{ເພີ່ມ # ການຄວບຄຸມແລ້ວ.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ລຶບອອກແລ້ວ"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ, ຕຳແໜ່ງ <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ເພີ່ມແຜ່ນ"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ຢ່າເພີ່ມແຜ່ນ"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ເລືອກຜູ້ໃຊ້"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ແອັບນຳໃຊ້ຢູ່</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ແອັບນຳໃຊ້ຢູ່</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{ນຳໃຊ້ຢູ່ # ແອັບ}other{ນຳໃຊ້ຢູ່ # ແອັບ}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ຂໍ້ມູນໃໝ່"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ແອັບທີ່ນຳໃຊ້ຢູ່"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"ແອັບເຫຼົ່ານີ້ແມ່ນເປີດ ແລະ ເອີ້ນໃຊ້ຢູ່, ເຖິງແມ່ນວ່າທ່ານຈະບໍ່ໄດ້ກຳລັງໃຊ້ພວກມັນກໍຕາມ. ນີ້ຈະປັບປຸງການເຮັດວຽກຂອງພວກມັນ, ແຕ່ອາດກະທົບກັບອາຍຸແບັດເຕີຣີໄດ້."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ຕັ້ງໂມງປຸກແລ້ວ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ປິດກ້ອງຖ່າຍຮູບ ແລະ ໄມແລ້ວ"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ການແຈ້ງເຕືອນ}other{# ການແຈ້ງເຕືອນ}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ກຳລັງອອກອາກາດ"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ຢຸດການອອກອາກາດ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ຫາກທ່ານອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ຫຼື ປ່ຽນເອົ້າພຸດ, ການອອກອາກາດປັດຈຸບັນຂອງທ່ານຈະຢຸດ"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ປ່ຽນເອົ້າພຸດ"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ບໍ່ຮູ້ຈັກ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
index c6b7e6c..6ae37e4 100644
--- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"ປິດ"</item>
     <item msgid="460891964396502657">"ເປີດ"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
+    <item msgid="8014986104355098744">"ປິດ"</item>
+    <item msgid="5966994759929723339">"ເປີດ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index c9aa65c..3722176 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -205,12 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Parinktis „Jutikliai išjungti“ aktyvi"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Išvalyti visus pranešimus."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"Dar <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Grupėje yra dar <xliff:g id="NUMBER_1">%s</xliff:g> pranešimas.</item>
-      <item quantity="few">Grupėje yra dar <xliff:g id="NUMBER_1">%s</xliff:g> pranešimai.</item>
-      <item quantity="many">Grupėje yra dar <xliff:g id="NUMBER_1">%s</xliff:g> pranešimo.</item>
-      <item quantity="other">Grupėje yra dar <xliff:g id="NUMBER_1">%s</xliff:g> pranešimų.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Grupėje yra dar # pranešimas.}one{Grupėje yra dar # pranešimas.}few{Grupėje yra dar # pranešimai.}many{Grupėje yra dar # pranešimo.}other{Grupėje yra dar # pranešimų.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Užrakintas ekranas yra horizontalios orientacijos."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Užrakintas ekranas yra vertikalios orientacijos."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Desertų dėklas"</string>
@@ -228,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatinis pasukimas"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatiškai sukti ekraną"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Vietovė"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Ekrano užsklanda"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Prieiga prie fotoaparato"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Prieiga prie mikrofono"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Pasiekiama"</string>
@@ -257,12 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Viešosios interneto prieigos taškas"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Įjungiama…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Duom. taup. pr. įj."</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d įrenginys</item>
-      <item quantity="few">%d įrenginiai</item>
-      <item quantity="many">%d įrenginio</item>
-      <item quantity="other">%d įrenginių</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# įrenginys}one{# įrenginys}few{# įrenginiai}many{# įrenginio}other{# įrenginių}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Žibintuvėlis"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Fotoaparatas naudojamas"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobiliojo ryšio duomenys"</string>
@@ -355,13 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ar norite tęsti sesiją?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Pradėti iš naujo"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Taip, tęsti"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Svečio režimas"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Naudojatės svečio režimu"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Pridėjus naują naudotoją, bus išeita iš svečio režimo ir iš dabartinės svečio sesijos bus ištrintos visos programos ir duomenys."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Pasiekta naudotojų riba"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Galite pridėti iki <xliff:g id="COUNT">%d</xliff:g> naudotojo.</item>
-      <item quantity="few">Galite pridėti iki <xliff:g id="COUNT">%d</xliff:g> naudotojų.</item>
-      <item quantity="many">Galite pridėti iki <xliff:g id="COUNT">%d</xliff:g> naudotojo.</item>
-      <item quantity="other">Galite pridėti iki <xliff:g id="COUNT">%d</xliff:g> naudotojų.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Galima sukurti tik vieną naudotoją.}one{Galite pridėti iki # naudotojo.}few{Galite pridėti iki # naudotojų.}many{Galite pridėti iki # naudotojo.}other{Galite pridėti iki # naudotojų.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Pašalinti naudotoją?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Bus ištrinti visi šio naudotojo duomenys ir programos."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Pašalinti"</string>
@@ -547,18 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Priminti"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Anuliuoti"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Nustatyta snausti <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d valanda</item>
-      <item quantity="few">%d valandos</item>
-      <item quantity="many">%d valandos</item>
-      <item quantity="other">%d valandų</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minutė</item>
-      <item quantity="few">%d minutės</item>
-      <item quantity="many">%d minutės</item>
-      <item quantity="other">%d minučių</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# valanda}=2{# valandos}one{# valanda}few{# valandos}many{# valandos}other{# valandų}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minutė}one{# minutė}few{# minutės}many{# minutės}other{# minučių}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Akum. taus. pr."</string>
     <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>
@@ -707,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Įspėjimai"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Akumuliatorius"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Ekrano kopijos"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Bendrieji pranešimai"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Akimirksniu įkeliamos programos"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Sąranka"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Saugykla"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Užuominos"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Akimirksniu įkeliamos programos"</string>
@@ -781,12 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"perjungti"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Įrenginio valdikliai"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Pasirinkite programą, kad pridėtumėte valdiklių"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one">Pridėtas <xliff:g id="NUMBER_1">%s</xliff:g> valdiklis.</item>
-      <item quantity="few">Pridėti <xliff:g id="NUMBER_1">%s</xliff:g> valdikliai.</item>
-      <item quantity="many">Pridėta <xliff:g id="NUMBER_1">%s</xliff:g> valdiklio.</item>
-      <item quantity="other">Pridėta <xliff:g id="NUMBER_1">%s</xliff:g> valdiklių.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Pridėtas # valdiklis.}one{Pridėtas # valdiklis.}few{Pridėti # valdikliai.}many{Pridėta # valdiklio.}other{Pridėta # valdiklių.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Pašalinta"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Įtraukta į mėgstamiausius"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Įtraukta į mėgstamiausius, padėtis: <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -943,12 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Pridėti išklotinės elementą"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepridėti išklotinės elemento"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Naudotojo pasirinkimas"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> programa yra aktyvi</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> programos yra aktyvios</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> programos yra aktyvi</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> programų yra aktyvios</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aktyvi programa}one{# aktyvi programa}few{# aktyvios programos}many{# aktyvios programos}other{# aktyvių programų}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nauja informacija"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktyvios programos"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Šios programos yra aktyvios ir vykdomos, net jei jų nenaudojate. Tai atlikus patobulinamos jų funkcijos, bet taip pat gali būti paveiktas ir akumuliatoriaus veikimo laikas."</string>
@@ -977,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signalas nustatytas"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Vaizdo kamera ir mikrofonas išjungti"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pranešimas}one{# pranešimas}few{# pranešimai}many{# pranešimo}other{# pranešimų}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transliavimas"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Sustabdyti „<xliff:g id="APP_NAME">%1$s</xliff:g>“ transliaciją?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jei transliuosite „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“ arba pakeisite išvestį, dabartinė transliacija bus sustabdyta"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transliuoti „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Keisti išvestį"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nežinoma"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
index 3e289e1..03d98c4 100644
--- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Išjungta"</item>
     <item msgid="460891964396502657">"Įjungta"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Nepasiekiama"</item>
+    <item msgid="8014986104355098744">"Išjungta"</item>
+    <item msgid="5966994759929723339">"Įjungta"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 7c1e658..a1a2424 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -205,11 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Aktivizēts iestatījums “Sensori izslēgti”"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Notīrīt visus paziņojumus"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"vēl <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="zero">Vēl <xliff:g id="NUMBER_1">%s</xliff:g> paziņojumi grupā.</item>
-      <item quantity="one">Vēl <xliff:g id="NUMBER_1">%s</xliff:g> paziņojums grupā.</item>
-      <item quantity="other">Vēl <xliff:g id="NUMBER_1">%s</xliff:g> paziņojumi grupā.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Vēl # paziņojums grupā.}zero{Vēl # paziņojumi grupā.}one{Vēl # paziņojums grupā.}other{Vēl # paziņojumi grupā.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekrāns tagad ir bloķēts ainavas orientācijā."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekrāns tagad ir bloķēts portreta orientācijā."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Saldo ēdienu stends"</string>
@@ -227,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automātiska pagriešana"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automātiska ekrāna pagriešana"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Atrašanās vieta"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Ekrānsaudzētājs"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kamera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofons"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Piekļuve atļauta"</string>
@@ -256,11 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Tīklājs"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Notiek ieslēgšana…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Datu liet. s. iesl."</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="zero">%d ierīču</item>
-      <item quantity="one">%d ierīce</item>
-      <item quantity="other">%d ierīces</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# ierīce}zero{# ierīču}one{# ierīce}other{# ierīces}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lukturītis"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera tiek lietota"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobilie dati"</string>
@@ -353,12 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vai vēlaties turpināt savu sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Sākt no sākuma"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Jā, turpināt"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Viesa režīms"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Jūs izmantojat viesa režīmu"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ja pievienosiet jaunu lietotāju, viesa režīms tiks aizvērts un visas pašreizējās viesa sesijas lietotnes un dati tiks dzēsti."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Sasniegts lietotāju ierobežojums"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="zero">Varat pievienot ne vairāk kā <xliff:g id="COUNT">%d</xliff:g> lietotājus.</item>
-      <item quantity="one">Varat pievienot ne vairāk kā <xliff:g id="COUNT">%d</xliff:g> lietotāju.</item>
-      <item quantity="other">Varat pievienot ne vairāk kā <xliff:g id="COUNT">%d</xliff:g> lietotājus.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Var izveidot tikai vienu lietotāju.}zero{Varat pievienot līdz # lietotājiem.}one{Varat pievienot līdz # lietotājam.}other{Varat pievienot līdz # lietotājiem.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Vai noņemt lietotāju?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Tiks dzēstas visas šī lietotāja lietotnes un dati."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Noņemt"</string>
@@ -544,16 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Atgādināt"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Atsaukt"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Atlikts: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="zero">%d stundas</item>
-      <item quantity="one">%d stunda</item>
-      <item quantity="other">%d stundas</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="zero">%d minūtes</item>
-      <item quantity="one">%d minūte</item>
-      <item quantity="other">%d minūtes</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# stunda}=2{# stundas}zero{# stundu}one{# stunda}other{# stundas}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minūte}zero{# minūšu}one{# minūte}other{# minūtes}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Akumulatora enerģijas taupīšanas režīms"</string>
     <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>
@@ -702,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Brīdinājumi"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Akumulators"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Ekrānuzņēmumi"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Vispārīgi ziņojumi"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Tūlītējās lietotnes"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Iestatīšana"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Krātuve"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Padomi"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Tūlītējās lietotnes"</string>
@@ -776,11 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"pārslēgt"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Ierīču vadīklas"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Izvēlieties lietotni, lai pievienotu vadīklas"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="zero">Pievienotas <xliff:g id="NUMBER_1">%s</xliff:g> vadīklas.</item>
-      <item quantity="one">Pievienota <xliff:g id="NUMBER_1">%s</xliff:g> vadīkla.</item>
-      <item quantity="other">Pievienotas <xliff:g id="NUMBER_1">%s</xliff:g> vadīklas.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Pievienota # vadīkla.}zero{Pievienotas # vadīklas.}one{Pievienota # vadīkla.}other{Pievienotas # vadīklas.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Noņemta"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Pievienota izlasei"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Pievienota izlasei, <xliff:g id="NUMBER">%d</xliff:g>. pozīcija"</string>
@@ -937,11 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Pievienot elementu"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepievienot elementu"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Lietotāja atlase"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="zero"><xliff:g id="COUNT_1">%s</xliff:g> lietotnes ir aktīvas</item>
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> lietotne ir aktīva</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> lietotnes ir aktīvas</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# lietotne ir aktīva}zero{# lietotnes ir aktīvas}one{# lietotne ir aktīva}other{# lietotnes ir aktīvas}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Jauna informācija"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktīvās lietotnes"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Šīs lietotnes ir aktīvas un darbojas, pat ja jūs tās neizmantojat. Tas uzlabo lietotņu funkcionalitāti, taču var arī ietekmēt akumulatora darbības ilgumu."</string>
@@ -970,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signāls ir iestatīts"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera un mikrofons ir izslēgti"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# paziņojums}zero{# paziņojumu}one{# paziņojums}other{# paziņojumi}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Notiek apraidīšana"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vai apturēt lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> apraidīšanu?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ja sāksiet lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraidīšanu vai mainīsiet izvadi, pašreizējā apraide tiks apturēta"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraide"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Izvades maiņa"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Nezināms"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
index eb210c2..6e9264d 100644
--- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Izslēgts"</item>
     <item msgid="460891964396502657">"Ieslēgts"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Nav pieejams"</item>
+    <item msgid="8014986104355098744">"Izslēgts"</item>
+    <item msgid="5966994759929723339">"Ieslēgts"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 8624604..5c1bf4a 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Исклучувањето на сензорите е активно"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Избриши ги сите известувања."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Уште <xliff:g id="NUMBER_1">%s</xliff:g> известување внатре.</item>
-      <item quantity="other">Уште <xliff:g id="NUMBER_1">%s</xliff:g> известувања внатре.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Уште # известување внатре.}one{Уште # известување внатре.}other{Уште # известувања внатре.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Екранот е заклучен во ориентација на пејзаж."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Екранот е заклучен во ориентација на портрет."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматско ротирање"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматско ротирање на екранот"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Заштитник на екран"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Пристап до камерата"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Пристап до микрофонот"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Дозволен"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Точка на пристап"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Се вклучува…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Вклучен штедач"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d уред</item>
-      <item quantity="other">%d уреди</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# уред}one{# уред}other{# уреда}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Светилка"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Камерата е во употреба"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мобилен интернет"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Дали сакате да продолжите со сесијата?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни одново"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продолжи"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Режим на гостин"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Користите режим на гостин"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ако додадете нов корисник, ќе излезете од режимот на гостин и ќе ги избришете сите апликации и податоци од тековната гостинска сесија."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнато ограничување на корисник"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Може да додадете најмногу <xliff:g id="COUNT">%d</xliff:g> корисник.</item>
-      <item quantity="other">Може да додадете најмногу <xliff:g id="COUNT">%d</xliff:g> корисници.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{]Може да се создаде само еден корисник.}one{Може да додадете најмногу # корисник}other{Може да додадете најмногу # корисници}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Да се отстрани корисникот?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Сите апликации и податоци од овој корисник ќе се избришат."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Отстрани"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Потсети ме"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Врати"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Одложено за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d час</item>
-      <item quantity="other">%d часа</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d минута</item>
-      <item quantity="other">%d минути</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# час}=2{# часа}one{# час}other{# часа}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# минута}one{# минута}other{# минути}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Штедач на батерија"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Известувања"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Батерија"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Слики од екранот"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Општи пораки"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Инстант апликации"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Поставување"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Капацитет"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Совети"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Инстант апликации"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"вклучување/исклучување"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Контроли за уредите"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Изберете апликација за да додадете контроли"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one">Додадена е <xliff:g id="NUMBER_1">%s</xliff:g> контрола.</item>
-      <item quantity="other">Додадени се <xliff:g id="NUMBER_1">%s</xliff:g> контроли.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Додадена е # контрола.}one{Додадени се # контрола.}other{Додадени се # контроли.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Отстранета"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Омилена"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Омилена, позиција <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Додајте плочка"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Не додавајте плочка"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Изберете корисник"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one">Активни се <xliff:g id="COUNT_1">%s</xliff:g> апликација</item>
-      <item quantity="other">Активни се <xliff:g id="COUNT_1">%s</xliff:g> апликации</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{Активна е # апликација}one{Активни се # апликација}other{Активни се # апликации}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нови информации"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активни апликации"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Овие апликации се активни и работат, дури и кога не ги користите. Ова ја подобрува нивната функционалност, но може да влијае и на траењето на батеријата."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Алармот е наместен"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонот се исклучени"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известување}one{# известување}other{# известувања}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитување"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се прекине емитувањето на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитувате на <xliff:g id="SWITCHAPP">%1$s</xliff:g> или го промените излезот, тековното емитување ќе запре"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитување на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Променете излез"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index 78be6dd..96c8a49 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Исклучен"</item>
     <item msgid="460891964396502657">"Вклучен"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Недостапно"</item>
+    <item msgid="8014986104355098744">"Исклучено"</item>
+    <item msgid="5966994759929723339">"Вклучено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 30aab4e..e951978 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"സെൻസറുകൾ ഓഫ് സജീവമാണ്"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"എല്ലാ വിവരങ്ങളും മായ്‌ക്കുക."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">ഉള്ളിൽ <xliff:g id="NUMBER_1">%s</xliff:g> അറിയിപ്പുകൾ കൂടിയുണ്ട്.</item>
-      <item quantity="one">ഉള്ളിൽ <xliff:g id="NUMBER_0">%s</xliff:g> അറിയിപ്പ് കൂടിയുണ്ട്.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# അറിയിപ്പ് കൂടിയുണ്ട്.}other{# അറിയിപ്പുകൾ കൂടിയുണ്ട്.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"സ്‌ക്രീൻ ലാൻഡ്‌സ്‌കേപ്പ് ഓറിയന്റേഷനിൽ ലോക്കുചെയ്‌തു."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"സ്‌ക്രീൻ പോർട്രെയ്‌റ്റ് ഓറിയന്റേഷനിൽ ലോക്കുചെയ്‌തു."</string>
     <string name="dessert_case" msgid="9104973640704357717">"ഡെസേർട്ട് കെയ്സ്"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"സ്‌ക്രീൻ സ്വയമേവ തിരിയൽ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"സ്‌ക്രീൻ സ്വയമേവ തിരിക്കുക"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ലൊക്കേഷൻ"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"സ്ക്രീൻ സേവർ"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"ക്യാമറ ആക്‌സസ്"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"മൈക്ക് ആക്‌സസ്"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ലഭ്യമാണ്"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ഹോട്ട്‌സ്‌പോട്ട്"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ഓണാക്കുന്നു…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ഡാറ്റ സേവർ ഓണാണ്"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d ഉപകരണങ്ങൾ</item>
-      <item quantity="one">%d ഉപകരണം</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# ഉപകരണം}other{# ഉപകരണങ്ങൾ}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ടോർച്ച്"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"ക്യാമറ ഉപയോഗത്തിലാണ്"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"മൊബൈൽ ഡാറ്റ"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"നിങ്ങളുടെ സെഷൻ തുടരണോ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"പുനരാംരംഭിക്കുക"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"അതെ, തുടരുക"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"അതിഥി മോഡ്"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"നിങ്ങൾ അതിഥി മോഡിലാണ്"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"പുതിയൊരു ഉപയോക്താവിനെ ചേർത്താൽ അതിഥി മോഡിൽ നിന്ന് പുറത്ത് കടക്കുകയും നിലവിലെ അതിഥി മോഡിലുള്ള എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കുകയും ചെയ്യും."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ഉപയോക്തൃ പരിധി എത്തി"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">നിങ്ങൾക്ക് <xliff:g id="COUNT">%d</xliff:g> ഉപയോക്താക്കളെ വരെ ചേർക്കാനാവും.</item>
-      <item quantity="one">ഒരു ഉപയോക്താവിന് മാത്രമേ സൃഷ്‌ടിക്കാനാവൂ.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{ഒരു ഉപയോക്താവിനെ മാത്രമേ സൃഷ്‌ടിക്കാനാകൂ.}other{നിങ്ങൾക്ക് # ഉപയോക്താക്കളെ വരെ ചേർക്കാം.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"ഉപയോക്താവിനെ ഇല്ലാതാക്കണോ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ഈ ഉപയോക്താവിന്റെ എല്ലാ ആപ്സും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"നീക്കംചെയ്യുക"</string>
@@ -411,7 +406,7 @@
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"ഈ ഉപകരണം <xliff:g id="VPN_APP_0">%1$s</xliff:g>, <xliff:g id="VPN_APP_1">%2$s</xliff:g> എന്നിവയിലൂടെ ഇന്റർനെറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്‌തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്‌റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്‌മിന് ദൃശ്യമാകും."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്‌തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള, ഔദ്യോഗിക ആപ്പുകളിലെ നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്‌റ്റിവിറ്റി നിങ്ങളുടെ ഐടി അഡ്‌മിനും VPN ദാതാവിനും ദൃശ്യമാകും."</string>
     <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"നിങ്ങളുടെ വ്യക്തിപര ആപ്പുകൾ <xliff:g id="VPN_APP">%1$s</xliff:g> വഴി ഇന്റർനെറ്റിലേക്ക് കണക്‌റ്റ് ചെയ്‌തിരിക്കുന്നു. ഇമെയിലുകളും ബ്രൗസിംഗ് ഡാറ്റയും ഉൾപ്പെടെയുള്ള നിങ്ങളുടെ നെറ്റ്‌വർക്ക് ആക്‌റ്റിവിറ്റി നിങ്ങളുടെ VPN ദാതാവിന് ദൃശ്യമാകും."</string>
-    <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
+    <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" 5"</string>
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN ക്രമീകരണം തുറക്കുക"</string>
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്. നിങ്ങൾ ഉപയോഗിക്കുന്ന ആപ്പുകൾ, സ്‌ക്രീൻ സമയം, ലൊക്കേഷൻ എന്നിവ പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ രക്ഷിതാവിന് കാണാനും നിയന്ത്രിക്കാനുമാകും."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"എന്നെ ഓർമ്മിപ്പിക്കുക"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"പഴയപടിയാക്കുക"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> സമയത്തേക്ക് സ്‌നൂസ് ‌ചെയ്‌തു"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d മണിക്കൂർ</item>
-      <item quantity="one">%d മണിക്കൂർ</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d മിനിറ്റ്</item>
-      <item quantity="one">%d മിനിറ്റ്</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# മണിക്കൂർ}=2{# മണിക്കൂർ}other{# മണിക്കൂർ}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# മിനിറ്റ്}other{# മിനിറ്റ്}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"ബാറ്ററി ലാഭിക്കൽ"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"മുന്നറിയിപ്പുകൾ"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ബാറ്ററി"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"സ്‌ക്രീൻഷോട്ടുകൾ"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"പൊതുവായ സന്ദേശങ്ങൾ"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"സജ്ജീകരണം"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"സ്റ്റോറേജ്"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"സൂചനകൾ"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"മാറ്റുക"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ഉപകരണ നിയന്ത്രണങ്ങൾ"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"നിയന്ത്രണങ്ങൾ ചേർക്കാൻ ആപ്പ് തിരഞ്ഞെടുക്കുക"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> നിയന്ത്രണങ്ങൾ ചേർത്തു.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> നിയന്ത്രണം ചേർത്തു.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# നിയന്ത്രണം ചേർത്തു.}other{# നിയന്ത്രണങ്ങൾ ചേർത്തു.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"നീക്കം ചെയ്‌തു"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"പ്രിയപ്പെട്ടതാക്കി"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"പ്രിയപ്പെട്ടതാക്കി, സ്ഥാനം <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ടൈൽ ചേർക്കുക"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ടൈൽ ചേർക്കരുത്"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ഉപയോക്താവിനെ തിരഞ്ഞെടുക്കൂ"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ആപ്പുകൾ സജീവമാണ്</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ആപ്പ് സജീവമാണ്</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ആപ്പ് സജീവമാണ്}other{# ആപ്പുകൾ സജീവമാണ്}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"പുതിയ വിവരങ്ങൾ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"സജീവമായ ആപ്പുകൾ"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"നിങ്ങൾ ഉപയോഗിക്കാത്തപ്പോൾ പോലും ഈ ആപ്പുകൾ സജീവമായിരിക്കും, പ്രവർത്തിച്ചുകൊണ്ടിരിക്കുകയും ചെയ്യും. ഇത് അവയുടെ പ്രവർത്തനക്ഷമത മെച്ചപ്പെടുത്തുന്നു, എന്നാൽ ഇത് ബാറ്ററി ലൈഫിനെ ബാധിച്ചേക്കാനിടയുണ്ട്."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"അലാറം സജ്ജീകരിച്ചു"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ക്യാമറയും മൈക്കും ഓഫാണ്"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# അറിയിപ്പ്}other{# അറിയിപ്പുകൾ}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"പ്രക്ഷേപണം ചെയ്യുന്നു"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുന്നത് അവസാനിപ്പിക്കണോ?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"നിങ്ങൾ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുകയോ ഔട്ട്പുട്ട് മാറ്റുകയോ ചെയ്താൽ നിങ്ങളുടെ നിലവിലുള്ള ബ്രോഡ്‌കാസ്റ്റ് അവസാനിക്കും"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്‌കാസ്റ്റ് ചെയ്യുക"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ഔട്ട്പുട്ട് മാറ്റുക"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"അജ്ഞാതം"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
index 1208928..7a07873 100644
--- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"ഓഫാണ്"</item>
     <item msgid="460891964396502657">"ഓണാണ്"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"ലഭ്യമല്ല"</item>
+    <item msgid="8014986104355098744">"ഓഫാണ്"</item>
+    <item msgid="5966994759929723339">"ഓണാണ്"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index f0ff215..f9ca17e 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Мэдрэгчийг унтраах идэвхтэй байна"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Бүх мэдэгдлийг цэвэрлэх."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">дотор бусад <xliff:g id="NUMBER_1">%s</xliff:g> мэдэгдэл байна.</item>
-      <item quantity="one">дотор бусад <xliff:g id="NUMBER_0">%s</xliff:g> мэдэгдэл байна.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{дотор # мэдэгдэл байна.}other{дотор # мэдэгдэл байна.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Дэлгэц хэвтээ чиглэлд түгжигдсэн."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Дэлгэц босоо чиглэлээр түгжигдсэн."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Амттаны хайрцаг"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматаар эргэх"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Дэлгэцийг автоматаар эргүүлэх"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Байршил"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Дэлгэц амраагч"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Камерын хандалт"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Микрофоны хандалт"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Боломжтой"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Сүлжээний цэг"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Асааж байна…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Дата хэмнэгчийг асаасан"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d төхөөрөмж</item>
-      <item quantity="one">%d төхөөрөмж</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# төхөөрөмж}other{# төхөөрөмж}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Гар чийдэн"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Камерыг ашиглаж байна"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мобайл дата"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Та үргэлжлүүлэхийг хүсэж байна уу?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Дахин эхлүүлэх"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Тийм, үргэлжлүүлэх"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Зочны горим"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Та зочны горимд байна"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Шинэ хэрэглэгч нэмснээр зочны горимоос гаргах бөгөөд бүх апп болон өгөгдлийг одоогийн зочны харилцан үйлдлээс устгана."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Хэрэглэгчийн хязгаарт хүрсэн"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Та <xliff:g id="COUNT">%d</xliff:g> хүртэлх хэрэглэгч нэмэх боломжтой.</item>
-      <item quantity="one">Зөвхөн нэг хэрэглэгч үүсгэх боломжтой.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Зөвхөн нэг хэрэглэгч үүсгэх боломжтой.}other{Та # хүртэлх хэрэглэгч нэмж болно.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Хэрэглэгчийг устгах уу?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Энэ хэрэглэгчийн бүх апп болон мэдээлэл устах болно."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Арилгах"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Надад сануулах"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Болих"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>-д түр хойшлуулсан"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d цаг</item>
-      <item quantity="one">%d цаг</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d минут</item>
-      <item quantity="one">%d минут</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# цаг}=2{# цаг}other{# цаг}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# минут}other{# минут}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Батарей хэмнэгч"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Сэрэмжлүүлэг"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Батарей"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Дэлгэцийн зураг дарах"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Энгийн мессеж"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Шуурхай апп"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Тохируулга"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Хадгалах сан"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Заавар"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Шуурхай апп"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"асаах/унтраах"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Төхөөрөмжийн хяналт"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Хяналтууд нэмэхийн тулд аппыг сонгоно уу"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> хяналтыг нэмлээ.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> хяналтыг нэмлээ.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# хяналт нэмсэн.}other{# хяналт нэмсэн.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Хассан"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Дуртай гэж тэмдэглэсэн"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>-р байршилд дуртай гэж тэмдэглэсэн"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Хавтан нэмэх"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Хавтанг бүү нэм"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Хэрэглэгч сонгох"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> апп идэвхтэй байна</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> апп идэвхтэй байна</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# апп идэвхтэй байна}other{# апп идэвхтэй байна}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Шинэ мэдээлэл"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Идэвхтэй аппууд"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Та эдгээр аппыг ашиглаагүй байсан ч тэдгээр нь идэвхтэй бөгөөд ажиллаж байна. Энэ нь тэдгээрийн ажиллагааг сайжруулах ч батарейн ажиллах хугацаанд мөн нөлөөлж магадгүй."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Сэрүүлгийг тохируулсан"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камер болон микрофон унтраалттай байна"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# мэдэгдэл}other{# мэдэгдэл}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Нэвтрүүлэлт"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нэвтрүүлэхээ зогсоох уу?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Хэрэв та <xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлсэн эсвэл гаралтыг өөрчилсөн бол таны одоогийн нэвтрүүлэлтийг зогсооно"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлэх"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Гаралтыг өөрчлөх"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Тодорхойгүй"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
index 3748440..776c487 100644
--- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Унтраалттай"</item>
     <item msgid="460891964396502657">"Асаалттай"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Боломжгүй"</item>
+    <item msgid="8014986104355098744">"Унтраалттай"</item>
+    <item msgid="5966994759929723339">"Асаалттай"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 64bb6fa..19694db 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"सेन्सर बंद आहेत"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"सर्व सूचना साफ करा."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">आत आणखी <xliff:g id="NUMBER_1">%s</xliff:g> सूचना.</item>
-      <item quantity="one">आत आणखी <xliff:g id="NUMBER_0">%s</xliff:g> सूचना.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{आतमध्ये आणखी # सूचना आहे.}other{आतमध्ये आणखी # सूचना आहेत.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"लॅंडस्केप ओरिएंटेशनमध्ये स्क्रीन लॉक केली आहे."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"पोर्ट्रेट अभिमुखतेमध्ये स्क्रीन लॉक केली आहे."</string>
     <string name="dessert_case" msgid="9104973640704357717">"मिष्ठान्न प्रकरण"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ऑटो-रोटेट"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ऑटो-रोटेट स्क्रीन"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"स्थान"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"स्क्रीन सेव्हर"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"कॅमेराचा अ‍ॅक्सेस"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"माइकचा ॲक्सेस"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"उपलब्ध आहे"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"हॉटस्पॉट"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"सुरू करत आहे…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"डेटा सेव्हर सुरू आहे"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d डिव्हाइस</item>
-      <item quantity="one">%d डिव्हाइस</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# डिव्हाइस}other{# डिव्हाइस}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"फ्लॅशलाइट"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"कॅमेरा वापरात आहे"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"मोबाइल डेटा"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"तुम्ही तुमचे सत्र सुरू ठेवू इच्छिता?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"येथून सुरू करा"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"होय, सुरू ठेवा"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"अतिथी मोड"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"तुम्ही अतिथी मोडमध्ये आहात"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"नवीन वापरकर्ता जोडल्याने अतिथी मोडमधून बाहेर पडाल आणि सध्याच्या अतिथी सत्रातील सर्व अ‍ॅप्स व डेटा हटवला जाईल."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"वापरकर्ता मर्यादा गाठली"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">तुम्ही <xliff:g id="COUNT">%d</xliff:g> वापरकर्त्यांपर्यंत जोडू शकता.</item>
-      <item quantity="one">फक्त एक वापरकर्ता तयार केला जाऊ शकतो.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{फक्त एक वापरकर्ता तयार केला जाऊ शकतो.}other{तुम्ही कमाल # वापरकर्ते जोडू शकता.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"वापरकर्त्यास काढायचे?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"या वापरकर्त्याचे सर्व अ‍ॅप्स आणि डेटा काढून टाकला जाईल."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"काढा"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"मला आठवण करून द्या"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"पहिल्यासारखे करा"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> साठी स्नूझ करा"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other"> %d तास</item>
-      <item quantity="one">%d तास</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other"> %d मिनिटे</item>
-      <item quantity="one">%d मिनिट</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# तास}=2{# तास}other{# तास}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# मिनिट}other{# मिनिटे}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"बॅटरी सेव्हर"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"सूचना"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"बॅटरी"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"स्क्रीनशॉट"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"सर्वसाधारण मेसेज"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"सेटअप"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"स्टोरेज"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"सूचना"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"टॉगल करा"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"डिव्हाइस नियंत्रणे"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"नियंत्रणे जोडण्यासाठी ॲप निवडा"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> नियंत्रणे जोडली.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> नियंत्रण जोडले.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# नियंत्रण जोडले आहे.}other{# नियंत्रणे जोडली आहेत.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"काढून टाकले"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"आवडले"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"आवडले, स्थान <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"टाइल जोडा"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"टाइल जोडू नका"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"वापरकर्ता निवडा"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> अ‍ॅप्स अ‍ॅक्टिव्ह आहेत</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> अ‍ॅप अ‍ॅक्टिव्ह आहे</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# अ‍ॅप अ‍ॅक्टिव्ह आहे}other{# अ‍ॅप्स अ‍ॅक्टिव्ह आहेत}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"नवीन माहिती"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"अ‍ॅक्टिव्ह ॲप्स"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"तुम्ही वापरत नसतानाही ही अ‍ॅप्स अ‍ॅक्टिव्ह असून रन होत आहेत. यामुळे त्यांची कार्यक्षमता सुधारते, पण त्याचा बॅटरी लाइफवरदेखील परिणाम होऊ शकतो."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट केला"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कॅमेरा आणि माइक बंद आहेत"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}other{# सूचना}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट करत आहे"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> चे प्रसारण थांबवायचे आहे का?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तुम्ही <xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण केल्यास किंवा आउटपुट बदलल्यास, तुमचे सध्याचे प्रसारण बंद होईल"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण करा"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपूट बदला"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"अज्ञात"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
index a6a3873..f75f0d0 100644
--- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"बंद आहे"</item>
     <item msgid="460891964396502657">"सुरू आहे"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"उपलब्ध नाही"</item>
+    <item msgid="8014986104355098744">"बंद आहे"</item>
+    <item msgid="5966994759929723339">"सुरू आहे"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index db64dd0..e85b3a0 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Penderia dimatikan aktif"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Padamkan semua pemberitahuan."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> lagi pemberitahuan di dalam.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> lagi pemberitahuan di dalam.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# lagi pemberitahuan dalam kumpulan.}other{# lagi pemberitahuan dalam kumpulan.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Skrin dikunci dalam orientasi landskap."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Skrin dikunci dalam orientasi potret."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Bekas Pencuci Mulut"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autoputar"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Autoputar skrin"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasi"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Penyelamat skrin"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Akses kamera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Akses mikrofon"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tersedia"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Tempat liputan"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Menghidupkan…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Penjimat Data dihidupkan"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d peranti</item>
-      <item quantity="one">%d peranti</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# peranti}other{# peranti}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lampu Suluh"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera sedang digunakan"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Data mudah alih"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Adakah anda ingin meneruskan sesi anda?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulakan semula"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ya, teruskan"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mod tetamu"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Anda dalam mod tetamu"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Tindakan menambahkan pengguna baharu akan menyebabkan anda keluar daripada mod tetamu dan memadamkan semua apl dan data daripada sesi tetamu semasa."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Had pengguna dicapai"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Anda boleh menambah sehingga <xliff:g id="COUNT">%d</xliff:g> pengguna.</item>
-      <item quantity="one">Hanya satu pengguna yang boleh dibuat.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Hanya satu pengguna boleh dibuat.}other{Anda boleh menambahkan sehingga # pengguna}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Alih keluar pengguna?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Semua apl dan data pengguna ini akan dipadamkan."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Alih keluar"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Ingatkan saya"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Buat asal"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Ditunda selama <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d jam</item>
-      <item quantity="one">%d jam</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minit</item>
-      <item quantity="one">%d minit</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# jam}=2{# jam}other{# jam}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minit}other{# minit}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Penjimat Bateri"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Makluman"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Bateri"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Tangkapan skrin"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mesej Am"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Apl Segera"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Persediaan"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Storan"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Pembayang"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Apl Segera"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"togol"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kawalan peranti"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Pilih apl untuk menambahkan kawalan"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kawalan ditambah.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kawalan ditambah.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kawalan ditambah.}other{# kawalan ditambah.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Dialih keluar"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Digemari"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Digemari, kedudukan <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tambahkan jubin"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Jangan tambah jubin"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Pilih pengguna"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apl aktif</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> apl aktif</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# apl aktif}other{# apl aktif}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Maklumat baharu"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apl aktif"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Apl ini aktif dan berfungsi walaupun anda tidak menggunakannya. Ini meningkatkan kefungsian apl tetapi mungkin akan memberikan kesan kepada hayat bateri."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Penggera ditetapkan"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon dimatikan"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pemberitahuan}other{# pemberitahuan}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika anda siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau tukarkan output, siaran semasa anda akan berhenti"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Tukar output"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Tidak diketahui"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
index cfd831a..9fa7ab5 100644
--- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Mati"</item>
     <item msgid="460891964396502657">"Hidup"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Tidak tersedia"</item>
+    <item msgid="8014986104355098744">"Mati"</item>
+    <item msgid="5966994759929723339">"Hidup"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index fb60b95..81f8189 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"အာရုံခံစနစ်များ ပိတ်ထားသည်"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"အကြောင်းကြားချက်အားလုံးကို ထုတ်ပစ်သည်။"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">အတွင်းတွင် အကြောင်းကြားချက် နောက်ထပ် <xliff:g id="NUMBER_1">%s</xliff:g> ခုရှိပါသည်။</item>
-      <item quantity="one">အတွင်းတွင် အကြောင်းကြားချက် နောက်ထပ် <xliff:g id="NUMBER_0">%s</xliff:g> ခုရှိပါသည်။</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{အထဲတွင် နောက်ထပ်အကြောင်းကြားချက် # ခု ရှိသည်။}other{အထဲတွင် နောက်ထပ်အကြောင်းကြားချက် # ခု ရှိသည်။}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ဖန်သားပြင် အနေအထားက အလျားလိုက်အဖြစ် ပုံသေ လုပ်ထားပါသည်"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ဖန်သားပြင် အနေအထားက ဒေါင်လိုက်အဖြစ် ပုံသေ လုပ်ထားပါသည်"</string>
     <string name="dessert_case" msgid="9104973640704357717">"မုန့်ထည့်သော ပုံး"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"အော်တို-လည်"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"မျက်နှာပြင်အား အလိုအလျောက်လှည့်ခြင်း"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"တည်နေရာ"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"စကရင်ချွေတာစနစ်"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"ကင်မရာသုံးခွင့်"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"မိုက်သုံးခွင့်"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ရနိုင်သည်"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ဟော့စပေါ့"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ဖွင့်နေသည်…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"\'ဒေတာချွေတာမှု\' ဖွင့်ထားသည်"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">စက် %d ခု</item>
-      <item quantity="one">စက် %d ခု</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{စက် # ခု}other{စက် # ခု}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ဖလက်ရှ်မီး"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"ကင်မရာကို သုံးနေသည်"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"မိုဘိုင်းဒေတာ"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"သင်၏ စက်ရှင်ကို ဆက်လုပ်လိုပါသလား။"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ပြန်စပါ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ဆက်လုပ်ပါ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ဧည့်သည်မုဒ်"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"သင်သည် ဧည့်သည်မုဒ်တွင် ဖြစ်သည်"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"အသုံးပြုသူ အသစ်ထည့်ခြင်းက ဧည့်သည်မုဒ်မှ ထွက်သွားမည်ဖြစ်ပြီး လက်ရှိဧည့်သည် စက်ရှင်မှ အက်ပ်နှင့် ဒေတာအားလုံးကို ဖျက်လိုက်ပါမည်။"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"အသုံးပြုသူ အကန့်အသတ် ပြည့်သွားပါပြီ"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">အသုံးပြုသူ <xliff:g id="COUNT">%d</xliff:g> ဦးအထိ ထည့်နိုင်သည်။</item>
-      <item quantity="one">အသုံးပြုသူ တစ်ဦးသာ ထည့်နိုင်သည်။</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{အသုံးပြုသူတစ်ဦးသာ ထည့်နိုင်သည်။}other{အသုံးပြုသူ # ယောက်အထိ ထည့်နိုင်သည်။}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"သုံးစွဲသူကိုဖယ်ရှားမည်လား?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ဤအသုံးပြုသူ၏ ဒေတာနှင့် အပ်ဖ်များအားလုံး ဖျက်လိုက်ပါမည်"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"ဖယ်ရှားရန်"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"ကျွန်ုပ်ကို သတိပေးပါ"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"နောက်ပြန်ရန်"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ဆိုင်းငံ့ရန်"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d နာရီ</item>
-      <item quantity="one">%d နာရီ</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d မိနစ်</item>
-      <item quantity="one">%d မိနစ်</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# နာရီ}=2{# နာရီ}other{# နာရီ}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# မိနစ်}other{# မိနစ်}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"ဘက်ထရီ အားထိန်း"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"သတိပေးချက်များ"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ဘက်ထရီ"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"မျက်နှာပြင်ဓာတ်ပုံများ"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"အထွေထွေ မက်ဆေ့ဂျ်များ"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"စနစ်ထည့်ရန်"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"သိုလှောင်ခန်း"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"အရိပ်အမြွက်များ"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ပြောင်းရန်"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"စက်ထိန်းစနစ်"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"ထိန်းချုပ်မှုများထည့်ရန် အက်ပ်ရွေးခြင်း"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">ခလုတ် <xliff:g id="NUMBER_1">%s</xliff:g> ခု ထည့်လိုက်သည်။</item>
-      <item quantity="one">ခလုတ် <xliff:g id="NUMBER_0">%s</xliff:g> ခု ထည့်လိုက်သည်။</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}other{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ဖယ်ရှားထားသည်"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်၊ အဆင့် <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"အကွက်ငယ် ထည့်ရန်"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"အကွက်ငယ် မထည့်ပါ"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"အသုံးပြုသူ ရွေးခြင်း"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other">အက်ပ် <xliff:g id="COUNT_1">%s</xliff:g> ခု ပွင့်နေသည်</item>
-      <item quantity="one">အက်ပ် <xliff:g id="COUNT_0">%s</xliff:g> ခု ပွင့်နေသည်</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{အက်ပ် # ခု ပွင့်နေသည်}other{အက်ပ် # ခု ပွင့်နေသည်}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"အချက်အလက်သစ်"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ပွင့်နေသည့်အက်ပ်များ"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"အသုံးမပြုချိန်တွင်လည်း ဤအက်ပ်များက ပွင့်နေပြီး လုပ်ဆောင်နေပါသည်။ ၎င်းက လုပ်ဆောင်ချက်ကို ပိုမိုကောင်းမွန်စေသော်လည်း ဘက်ထရီ သက်တမ်းတိုစေနိုင်ပါသည်။"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"နိုးစက် သတ်မှတ်ထားသည်"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ကင်မရာနှင့် မိုက် ပိတ်ထားသည်"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{အကြောင်းကြားချက် # ခု}other{အကြောင်းကြားချက် # ခု}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ထုတ်လွှင့်ခြင်း"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ထုတ်လွှင့်ခြင်းကို ရပ်မလား။"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ကို ထုတ်လွှင့်သောအခါ (သို့) အထွက်ကို ပြောင်းသောအခါ သင့်လက်ရှိထုတ်လွှင့်ခြင်း ရပ်သွားမည်"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ထုတ်လွှင့်ခြင်း"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"အထွက်ကို ပြောင်းခြင်း"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"မသိ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml
index 665af20..493a7f0 100644
--- a/packages/SystemUI/res/values-my/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"ပိတ်"</item>
     <item msgid="460891964396502657">"ဖွင့်"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"မရနိုင်ပါ"</item>
+    <item msgid="8014986104355098744">"ပိတ်"</item>
+    <item msgid="5966994759929723339">"ဖွင့်"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 4057de6..d6ce3fe 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"«Sensorene er av» er aktiv"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Fjern alle varslinger."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> andre varsler i gruppen.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> annet varsel i gruppen.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# annet varsel i gruppen.}other{# andre varsler i gruppen.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Skjermen er låst i liggende retning."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Skjermen er låst i stående retning."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessertmonter"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotér automatisk"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotér skjermen automatisk"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Sted"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Skjermsparer"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameratilgang"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofontilgang"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tilgjengelig"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Wi-Fi-sone"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Slår på …"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Datasparing er på"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d enheter</item>
-      <item quantity="one">%d enhet</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# enhet}other{# enheter}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lommelykt"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kameraet er i bruk"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobildata"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsette økten?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start på nytt"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsett"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gjestemodus"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Du er i gjestemodus"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Hvis du legger til en ny bruker, avsluttes gjestemodus, og alle apper og data fra den gjeldende gjesteøkten slettes."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Grensen for antall brukere er nådd"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Du kan legge til opptil <xliff:g id="COUNT">%d</xliff:g> brukere.</item>
-      <item quantity="one">Du kan bare opprette én bruker.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Du kan bare opprette én bruker.}other{Du kan legge til opptil # brukere.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Vil du fjerne brukeren?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Alle apper og data som tilhører denne brukeren, blir slettet."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Fjern"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Minn meg på det"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Angre"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Slumrer i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d timer</item>
-      <item quantity="one">%d time</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutter</item>
-      <item quantity="one">%d minutt</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# time}=2{# timer}other{# timer}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minutt}other{# minutter}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Batterisparing"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Varsler"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batteri"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skjermdumper"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Generelle meldinger"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Konfigurering"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Lagring"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Hint"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"slå av/på"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Enhetsstyring"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Velg en app for å legge til kontroller"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontroller er lagt til.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontroll er lagt til.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll er lagt til.}other{# kontroller er lagt til.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoritt"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favoritt, posisjon <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Legg til brikke"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ikke legg til brikke"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Velg bruker"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apper er aktive</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app er aktiv</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app er aktiv}other{# apper er aktive}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Ny informasjon"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktive apper"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Disse appene er aktive og kjører – selv når du ikke bruker dem. Dette forbedrer funksjonaliteten deres, men det kan også påvirke batterilevetiden."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmen er stilt inn"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er av"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# varsel}other{# varsler}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Kringkaster"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vil du stoppe kringkastingen av <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du kringkaster <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller endrer utgangen, stopper den nåværende kringkastingen din"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Kringkast <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Endre utgang"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ukjent"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
index a28b817..6fa902a 100644
--- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Av"</item>
     <item msgid="460891964396502657">"På"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Utilgjengelig"</item>
+    <item msgid="8014986104355098744">"Av"</item>
+    <item msgid="5966994759929723339">"På"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 896a4f4..409db0b 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"सेन्सर निष्क्रिय नामक सुविधा सक्रिय छ"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"सबै सूचनाहरू हटाउनुहोस्।"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">भित्र थप <xliff:g id="NUMBER_1">%s</xliff:g> सूचनाहरू छन्।</item>
-      <item quantity="one">भित्र थप <xliff:g id="NUMBER_0">%s</xliff:g> सूचना छ।</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{समूहभित्र थप # सूचना छ।}other{समूहभित्र थप # वटा सूचना छन्।}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"स्क्रिनलाई ल्यान्डस्केप अवस्थामा बन्द गरिएको छ।"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"स्क्रिन पोर्टेट अभिमूखमा लक गरिएको छ।"</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"अटो रोटेट"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"स्क्रिन स्वतःघुम्ने"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"लोकेसन"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"स्क्रिन सेभर"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"क्यामेरा प्रयोग गर्ने अनुमति"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"माइक प्रयोग गर्ने अनुमति"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"उपलब्ध छ"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"हटस्पट"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"सक्रिय गर्दै…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"डेटा सेभर सक्रिय छ"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d यन्त्रहरू</item>
-      <item quantity="one">%d यन्त्र</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# डिभाइस}other{# वटा डिभाइस}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"फ्ल्यासलाइट"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"क्यामेरा प्रयोग भइरहेको छ"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"मोबाइल डेटा"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"तपाईं आफ्नो सत्र जारी गर्न चाहनुहुन्छ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"सुरु गर्नुहोस्"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हो, जारी राख्नुहोस्"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"अतिथि मोड"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"तपाईं अतिथि मोड चलाउँदै हुनुहुन्छ"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"तपाईंले नयाँ प्रयोगकर्ता थप्नुभयो भने तपाईं अतिथि मोडबाट बाहिरिनु हुने छ र हालको अतिथि सत्रका सबै एप तथा डेटा मेटिने छ।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"प्रयोगकर्ताको सीमा पुग्यो"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">तपाईं अधिकतम <xliff:g id="COUNT">%d</xliff:g> प्रयोगहरू मात्र थप्न सक्नुहुन्छ।</item>
-      <item quantity="one">एउटा प्रयोगकर्ता मात्र सिर्जना गर्न सकिन्छ।</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{एउटा प्रोफाइल मात्र बनाउन सकिन्छ।}other{तपाईं बढीमा # जना प्रयोगकर्ता सामेल गराउन सक्नुहुन्छ।}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"प्रयोगकर्ता हटाउन चाहनुहुन्छ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"यस प्रयोगकर्ताको सबै एपहरू तथा डेटा हटाइने छ।"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"हटाउनुहोस्"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"मलाई सम्झाउनुहोस्"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"अन्डू गर्नुहोस्"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> का लागि स्नुज गरियो"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d घन्टा</item>
-      <item quantity="one">%d घन्टा</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d मिनेट</item>
-      <item quantity="one">%d मिनेट</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# घण्टा}=2{# घण्टा}other{# घण्टा}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# मिनेट}other{# मिनेट}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"ब्याट्री सेभर"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"सतर्कताहरू"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ब्याट्री"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"स्क्रिनशटहरू"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"सामान्य सन्देशहरू"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"सेटअप गर्नुहोस्"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"भण्डारण"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"सङ्केतहरू"</string>
     <string name="instant_apps" msgid="8337185853050247304">"तात्कालिक एपहरू"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"टगल गर्नुहोस्"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"डिभाइस नियन्त्रण गर्ने विजेटहरू"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"कन्ट्रोल थप्नु पर्ने एप छान्नुहोस्"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> वटा नियन्त्र थपियो।</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> नियन्त्र थपियो</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कन्ट्रोल हालियो।}other{# वटा कन्ट्रोल हालियो।}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"हटाइएको"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"मनपराइएको"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"मन पराइएका कुराहरूको <xliff:g id="NUMBER">%d</xliff:g> औँ स्थानमा"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"टाइल हाल्नुहोस्"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"टाइल नहाल्नुहोस्"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"प्रयोगकर्ता चयन गर्नु…"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> वटा एप सक्रिय छन्</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> एप सक्रिय छ</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# एप सक्रिय छ}other{# वटा एप सक्रिय छन्}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"नयाँ जानकारी"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"सक्रिय एपहरू"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"यी एपहरू प्रयोग नगरेका बेला पनि सक्रिय र चालु अवस्थामा रहन्छन्। यसले एपहरूलाई अझ राम्ररी काम गर्न सक्ने बनाउँछ। तर यसका कारणले ब्याट्रीको आयु भने घट्न सक्छ।"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"अलार्म सेट गरिएको छ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"क्यामेरा र माइक अफ छन्"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# वटा सूचना}other{# वटा सूचनाहरू}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"प्रसारण गरिँदै छ"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ब्रोडकास्ट गर्न छाड्ने हो?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तपाईंले <xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुभयो वा आउटपुट परिवर्तन गर्नुभयो भने तपाईंको हालको ब्रोडकास्ट रोकिने छ"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुहोस्"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"आउटपुट परिवर्तन गर्नुहोस्"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"अज्ञात"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
index 80edf29..17193ba 100644
--- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"अफ छ"</item>
     <item msgid="460891964396502657">"अन छ"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"अनुपलब्ध"</item>
+    <item msgid="8014986104355098744">"अफ"</item>
+    <item msgid="5966994759929723339">"अन"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 06f23fb..9501ddf 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"\'Sensoren uit\' actief"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Alle meldingen wissen."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Nog <xliff:g id="NUMBER_1">%s</xliff:g> meldingen in deze groep.</item>
-      <item quantity="one">Nog <xliff:g id="NUMBER_0">%s</xliff:g> melding in deze groep.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Nog # melding in deze groep.}other{Nog # meldingen in deze groep.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Het scherm is nu vergrendeld in liggende stand."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Het scherm is nu vergrendeld in staande stand."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessertshowcase"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatisch draaien"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Scherm automatisch draaien"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Locatie"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Cameratoegang"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Microfoontoegang"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Beschikbaar"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Aanzetten…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Databesparing staat aan"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d apparaten</item>
-      <item quantity="one">%d apparaat</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# apparaat}other{# apparaten}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Zaklamp"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Camera in gebruik"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobiele data"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Wil je doorgaan met je sessie?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Opnieuw starten"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, doorgaan"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gastmodus"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Je gebruikt de gastmodus"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Als je een nieuwe gebruiker toevoegt, wordt de gastmodus afgesloten en worden alle apps en gegevens van de huidige gastsessie verwijderd."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Gebruikerslimiet bereikt"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Je kunt maximaal <xliff:g id="COUNT">%d</xliff:g> gebruikers toevoegen.</item>
-      <item quantity="one">Er kan maar één gebruiker worden gemaakt.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Er kan maar 1 gebruiker worden gemaakt.}other{Je kunt maximaal # gebruikers toevoegen.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Gebruiker verwijderen?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Alle apps en gegevens van deze gebruiker worden verwijderd."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Verwijderen"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Herinneren"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Ongedaan maken"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Snoozefunctie <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> actief"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d uur</item>
-      <item quantity="one">%d uur</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minuten</item>
-      <item quantity="one">%d minuut</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# uur}=2{# uur}other{# uur}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuut}other{# minuten}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Batterijbesparing"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Meldingen"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batterij"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Screenshots"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Algemene berichten"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant-apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Instellen"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Opslag"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Hints"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant-apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"schakelen"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Apparaatbediening"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Kies de app waaraan je bedieningselementen wilt toevoegen"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> bedieningselementen toegevoegd.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> bedieningselement toegevoegd.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# bedieningselement toegevoegd.}other{# bedieningselementen toegevoegd.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Verwijderd"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Gemarkeerd als favoriet"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Gemarkeerd als favoriet, positie <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tegel toevoegen"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Tegel niet toevoegen"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Gebruiker selecteren"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps zijn actief</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app is actief</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app is actief}other{# apps zijn actief}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nieuwe informatie"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Actieve apps"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Deze apps zijn actief, ook als je ze niet gebruikt. Dit verbetert de functionaliteit, maar kan ook van invloed zijn op de batterijduur."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Wekker gezet"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera en microfoon staan uit"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# melding}other{# meldingen}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitzending"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Uitzending van <xliff:g id="APP_NAME">%1$s</xliff:g> stopzetten?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Als je <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzendt of de uitvoer wijzigt, wordt je huidige uitzending gestopt"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzenden"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Uitvoer wijzigen"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Onbekend"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
index c4603b2..fbccd78 100644
--- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Uit"</item>
     <item msgid="460891964396502657">"Aan"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Niet beschikbaar"</item>
+    <item msgid="8014986104355098744">"Uit"</item>
+    <item msgid="5966994759929723339">"Aan"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index ed9bbcd..681c2bb 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"\'ସେନ୍‌ସର୍ ବନ୍ଦ\' ସକ୍ରିୟ ଅଛି"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"ସମସ୍ତ ବିଜ୍ଞପ୍ତି ଖାଲି କରନ୍ତୁ।"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">ଭିତରେ ଆଉ <xliff:g id="NUMBER_1">%s</xliff:g>ଟି ଅଧିକ ବିଜ୍ଞପ୍ତି ରହିଛି।</item>
-      <item quantity="one">ଭିତରେ ଆଉ <xliff:g id="NUMBER_0">%s</xliff:g>ଟି ଅଧିକ ବିଜ୍ଞପ୍ତି ରହିଛି।</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{ଭିତରେ #ଟି ଅଧିକ ବିଜ୍ଞପ୍ତି ଅଛି।}other{ଭିତରେ #ଟି ଅଧିକ ବିଜ୍ଞପ୍ତି ଅଛି।}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ଲ୍ୟାଣ୍ଡସ୍କେପ୍‌ ଅବସ୍ଥାରେ ସ୍କ୍ରୀନ୍‍କୁ ଲକ୍‌ କରାଯାଇଛି।"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ପୋର୍ଟ୍ରେଟ୍‍ ଅବସ୍ଥାରେ ସ୍କ୍ରୀନ୍‍କୁ ଲକ୍‌ କରାଯାଇଛି।"</string>
     <string name="dessert_case" msgid="9104973640704357717">"ଡେଜର୍ଟ କେସ୍‌"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ଅଟୋ-ରୋଟେଟ୍"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ଅଟୋ-ରୋଟେଟ୍ ସ୍କ୍ରିନ୍"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ଲୋକେସନ୍‍"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"ସ୍କ୍ରିନ ସେଭର"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"କ୍ୟାମେରା ଆକ୍ସେସ୍"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"ମାଇକ୍ ଆକ୍ସେସ୍"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ଉପଲବ୍ଧ"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ହଟସ୍ପଟ୍‌"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ଚାଲୁ ହେଉଛି…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ଡାଟା ସେଭର୍‌ ଅନ୍‌ ଅଛି"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d ଡିଭାଇସ୍‌ଗୁଡ଼ିକ</item>
-      <item quantity="one">%d ଡିଭାଇସ୍</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{#ଟି ଡିଭାଇସ}other{#ଟି ଡିଭାଇସ}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ଫ୍ଲାସ୍‍ଲାଇଟ୍"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"କ୍ୟାମେରା ବ୍ୟବହାରରେ ଅଛି"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"ମୋବାଇଲ୍‌ ଡାଟା"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ଆପଣ ନିଜର ସେସନ୍ ଜାରି ରଖିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ହଁ, ଜାରି ରଖନ୍ତୁ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ଅତିଥି ମୋଡ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ଆପଣ ଅତିଥି ମୋଡରେ ଅଛନ୍ତି"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବା ଦ୍ୱାରା ଅତିଥି ମୋଡରୁ ବାହାରି ଯିବ ଏବଂ ବର୍ତ୍ତମାନର ଅତିଥି ସେସନରୁ ସମସ୍ତ ଆପ ଓ ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ଉପଯୋଗକର୍ତ୍ତା ସୀମାରେ ପହଞ୍ଚିଛି"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">କେବଳ <xliff:g id="COUNT">%d</xliff:g> ଉପଯୋଗକର୍ତ୍ତା ହିଁ ତିଆରି କରିହେବ।</item>
-      <item quantity="one">କେବଳ ଜଣେ ଉପଯୋଗକର୍ତ୍ତା ହିଁ ତିଆରି କରିହେବ।</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{କେବଳ ଜଣେ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରାଯାଇପାରିବ।}other{କେବଳ # ଜଣ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରାଯାଇପାରିବ।}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"ୟୁଜରଙ୍କୁ ବାହାର କରିବେ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ଏହି ୟୁଜରଙ୍କ ସମସ୍ତ ଆପ୍‍ ଓ ଡାଟା ଡିଲିଟ୍‍ ହେବ।"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"ମୋତେ ରିମାଇଣ୍ଡର୍ କରନ୍ତୁ"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"ପୂର୍ବବତ୍ କରନ୍ତୁ"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ପାଇଁ ସ୍ନୁଜ୍‍ କରାଗଲା"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d ଘଣ୍ଟା</item>
-      <item quantity="one">%d ଘଣ୍ଟା</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d ମିନିଟ୍‍</item>
-      <item quantity="one">%d ମିନିଟ୍‍</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ଘଣ୍ଟା}=2{# ଘଣ୍ଟା}other{# ଘଣ୍ଟା}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# ମିନିଟ}other{# ମିନିଟ}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"ବ୍ୟାଟେରୀ ସେଭର୍"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"ଆଲର୍ଟଗୁଡ଼ିକ"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ବ୍ୟାଟେରୀ"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"ସ୍କ୍ରୀନଶଟ୍‍"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"ସାଧାରଣ ମେସେଜ୍"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"ସେଟଅପ"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ଷ୍ଟୋରେଜ୍‌"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"ହିଣ୍ଟ"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ଟୋଗଲ୍ କରନ୍ତୁ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଯୋଗ କରିବାକୁ ଆପ୍ ବାଛନ୍ତୁ"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g>ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g>ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}other{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"କାଢ଼ି ଦିଆଯାଇଛି"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ପସନ୍ଦ କରାଯାଇଛି"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ପସନ୍ଦ କରାଯାଇଛି, ସ୍ଥିତି <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ଟାଇଲ୍ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ଟାଇଲ୍ ଯୋଗ କର ନାହିଁ"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ଉପଯୋଗକର୍ତ୍ତା ଚୟନ କର"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g>ଟି ଆପ ସକ୍ରିୟ ଅଛି</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g>ଟି ଆପ ସକ୍ରିୟ ଅଛି</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{#ଟି ଆପ ସକ୍ରିୟ ଅଛି}other{#ଟି ଆପ ସକ୍ରିୟ ଅଛି}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ନୂଆ ସୂଚନା"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ସକ୍ରିୟ ଆପଗୁଡ଼ିକ"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"ଆପଣ ଏହି ଆପ୍ସକୁ ବ୍ୟବହାର କରୁନଥିଲେ ମଧ୍ୟ ସେଗୁଡ଼ିକ ସକ୍ରିୟ ରହିଥାଏ ଏବଂ ଚାଲୁଥାଏ। ଏହା ସେଗୁଡ଼ିକର କାର୍ଯ୍ୟକ୍ଷମତାକୁ ଉନ୍ନତ କରେ, କିନ୍ତୁ ଏହା ମଧ୍ୟ ବ୍ୟାଟେରୀ ଲାଇଫକୁ ପ୍ରଭାବିତ କରିପାରେ।"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ଆଲାରାମ ସେଟ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"କ୍ୟାମେରା ଏବଂ ମାଇକ ବନ୍ଦ ଅଛି"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#ଟି ବିଜ୍ଞପ୍ତି}other{#ଟି ବିଜ୍ଞପ୍ତି}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ବ୍ରଡକାଷ୍ଟ କରୁଛି"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ଯଦି ଆପଣ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତି କିମ୍ବା ଆଉଟପୁଟ ବଦଳାନ୍ତି, ତେବେ ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ବ୍ରଡକାଷ୍ଟ ବନ୍ଦ ହୋଇଯିବ"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତୁ"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ଆଉଟପୁଟ ବଦଳାନ୍ତୁ"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ଅଜଣା"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml
index 2d9fb84..acaa3fb 100644
--- a/packages/SystemUI/res/values-or/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"ବନ୍ଦ ଅଛି"</item>
     <item msgid="460891964396502657">"ଚାଲୁ ଅଛି"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"ଉପଲବ୍ଧ ନାହିଁ"</item>
+    <item msgid="8014986104355098744">"ବନ୍ଦ ଅଛି"</item>
+    <item msgid="5966994759929723339">"ଚାଲୁ ଅଛି"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 97974288..0ca2cde 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"\'ਸੈਂਸਰ ਬੰਦ ਕਰੋ\' ਨੂੰ ਕਿਰਿਆਸ਼ੀਲ ਕਰੋ"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਹਟਾਓ।"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">ਅੰਦਰ <xliff:g id="NUMBER_1">%s</xliff:g> ਹੋਰ ਸੂਚਨਾਵਾਂ।</item>
-      <item quantity="other">ਅੰਦਰ <xliff:g id="NUMBER_1">%s</xliff:g> ਹੋਰ ਸੂਚਨਾਵਾਂ।</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{ਗਰੁੱਪ ਵਿੱਚ # ਹੋਰ ਸੂਚਨਾ ਹੈ।}one{ਗਰੁੱਪ ਵਿੱਚ # ਹੋਰ ਸੂਚਨਾ ਹੈ।}other{ਗਰੁੱਪ ਵਿੱਚ # ਹੋਰ ਸੂਚਨਾਵਾਂ ਹਨ।}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ਸਕ੍ਰੀਨ ਲੈਂਡਸਕੇਪ ਅਨੁਕੂਲਨ ਵਿੱਚ  ਲਾਕ  ਕੀਤੀ ਹੈ।"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ਸਕ੍ਰੀਨ ਪੋਰਟਰੇਟ ਅਨੁਕੂਲਨ ਵਿੱਚ  ਲਾਕ  ਕੀਤੀ ਗਈ ਹੈ।"</string>
     <string name="dessert_case" msgid="9104973640704357717">"ਡੈਜ਼ਰਟ ਕੇਸ"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ਸਵੈ-ਘੁਮਾਓ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ਸਕ੍ਰੀਨ ਨੂੰ ਆਪਣੇ ਆਪ ਘੁੰਮਾਓ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ਟਿਕਾਣਾ"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"ਸਕ੍ਰੀਨ ਸੇਵਰ"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"ਕੈਮਰਾ ਪਹੁੰਚ"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"ਮਾਈਕ ਪਹੁੰਚ"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ਉਪਲਬਧ"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ਹੌਟਸਪੌਟ"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ਡਾਟਾ ਸੇਵਰ ਚਾਲੂ ਹੈ"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d ਡੀਵਾਈਸ</item>
-      <item quantity="other">%d ਡੀਵਾਈਸਾਂ</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# ਡੀਵਾਈਸ}one{# ਡੀਵਾਈਸ}other{# ਡੀਵਾਈਸ}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ਫਲੈਸ਼ਲਾਈਟ"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"ਕੈਮਰਾ ਵਰਤੋਂ ਵਿੱਚ ਹੈ"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"ਮੋਬਾਈਲ ਡਾਟਾ"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਸੈਸ਼ਨ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ਹਾਂ, ਜਾਰੀ ਰੱਖੋ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ਮਹਿਮਾਨ ਮੋਡ"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ਤੁਸੀਂ ਮਹਿਮਾਨ ਮੋਡ ਵਿੱਚ ਹੋ"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ਨਵੇਂ ਵਰਤੋਂਕਾਰ ਨੂੰ ਸ਼ਾਮਲ ਕਰਨ ਨਾਲ ਮੌਜੂਦਾ ਮਹਿਮਾਨ ਮੋਡ ਚਲਾ ਜਾਵੇਗਾ ਅਤੇ ਮੌਜੂਦਾ ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਦੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਸੀਮਾ ਪੂਰੀ ਹੋਈ"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">ਤੁਸੀਂ <xliff:g id="COUNT">%d</xliff:g> ਤੱਕ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੇ ਹੋ।</item>
-      <item quantity="other">ਤੁਸੀਂ <xliff:g id="COUNT">%d</xliff:g> ਤੱਕ ਵਰਤੋਂਕਾਰਾਂ ਨੂੰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੇ ਹੋ।</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{ਸਿਰਫ਼ ਇੱਕ ਵਰਤੋਂਕਾਰ ਹੀ ਬਣਾਇਆ ਜਾ ਸਕਦਾ ਹੈ।}one{ਤੁਸੀਂ # ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੇ ਹੋ।}other{ਤੁਸੀਂ # ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੇ ਹੋ।}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"ਕੀ ਵਰਤੋਂਕਾਰ ਹਟਾਉਣਾ ਹੈ?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ਇਸ ਉਪਭੋਗਤਾ ਦੇ ਸਾਰੇ ਐਪਸ ਅਤੇ  ਡਾਟਾ  ਮਿਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"ਹਟਾਓ"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"ਮੈਨੂੰ ਯਾਦ ਕਰਵਾਓ"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"ਅਣਕੀਤਾ ਕਰੋ"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ਲਈ ਸਨੂਜ਼ ਕੀਤਾ ਗਿਆ"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one"> %d ਘੰਟਾ</item>
-      <item quantity="other">%d ਘੰਟੇ</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d ਮਿੰਟ</item>
-      <item quantity="other"> %d ਮਿੰਟ</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ਘੰਟਾ}=2{# ਘੰਟੇ}one{# ਘੰਟਾ}other{# ਘੰਟੇ}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# ਮਿੰਟ}one{# ਮਿੰਟ}other{# ਮਿੰਟ}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"ਬੈਟਰੀ ਸੇਵਰ"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"ਸੁਚੇਤਨਾਵਾਂ"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"ਬੈਟਰੀ"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"ਆਮ ਸੁਨੇਹੇ"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"ਸੈੱਟਅੱਪ ਕਰੋ"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ਸਟੋਰੇਜ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"ਸੰਕੇਤ"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ਟੌਗਲ ਕਰੋ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ਡੀਵਾਈਸ ਕੰਟਰੋਲ"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਐਪ ਚੁਣੋ"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ।</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।}one{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।}other{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ।}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ਹਟਾਇਆ ਗਿਆ"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ, ਸਥਾਨ <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ਟਾਇਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ਟਾਇਲ ਸ਼ਾਮਲ ਨਾ ਕਰੋ"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"ਵਰਤੋਂਕਾਰ ਚੁਣੋ"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> ਐਪ ਕਿਰਿਆਸ਼ੀਲ ਹੈ</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ਐਪਾਂ ਕਿਰਿਆਸ਼ੀਲ ਹਨ</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ਐਪ ਕਿਰਿਆਸ਼ੀਲ ਹੈ}one{# ਐਪ ਕਿਰਿਆਸ਼ੀਲ ਹੈ}other{# ਐਪਾਂ ਕਿਰਿਆਸ਼ੀਲ ਹਨ}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ਨਵੀਂ ਜਾਣਕਾਰੀ"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"ਇਹ ਐਪਾਂ ਕਿਰਿਆਸ਼ੀਲ ਹਨ ਅਤੇ ਚੱਲ ਰਹੀਆਂ ਹਨ, ਭਾਵੇਂ ਤੁਸੀਂ ਇਨ੍ਹਾਂ ਦੀ ਵਰਤੋਂ ਨਹੀਂ ਕਰ ਰਹੇ। ਇਸ ਨਾਲ ਇਨ੍ਹਾਂ ਦੀ ਪ੍ਰਕਾਰਜਾਤਮਕਤਾ ਬਿਹਤਰ ਹੁੰਦੀ ਹੈ ਪਰ ਬੈਟਰੀ ਲਾਈਫ਼ ਵੀ ਪ੍ਰਭਾਵਿਤ ਹੋ ਸਕਦੀ ਹੈ।"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ਅਲਾਰਮ ਸੈੱਟ ਹੈ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ ਬੰਦ ਹਨ"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ਸੂਚਨਾ}one{# ਸੂਚਨਾ}other{# ਸੂਚਨਾਵਾਂ}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ਪ੍ਰਸਾਰਨ"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਦੇ ਪ੍ਰਸਾਰਨ ਨੂੰ ਰੋਕਣਾ ਹੈ?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ਜੇ ਤੁਸੀਂ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰਦੇ ਹੋ ਜਾਂ ਆਊਟਪੁੱਟ ਬਦਲਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਪ੍ਰਸਾਰਨ ਰੁਕ ਜਾਵੇਗਾ"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰੋ"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ਆਊਟਪੁੱਟ ਬਦਲੋ"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ਅਗਿਆਤ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
index 737b2b6..9653b92 100644
--- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"ਬੰਦ"</item>
     <item msgid="460891964396502657">"ਚਾਲੂ"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"ਉਪਲਬਧ ਨਹੀਂ"</item>
+    <item msgid="8014986104355098744">"ਬੰਦ"</item>
+    <item msgid="5966994759929723339">"ਚਾਲੂ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 57526e7..0da22d5 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -205,12 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Wyłączenie czujników aktywne"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Usuń wszystkie powiadomienia."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="few">Jeszcze <xliff:g id="NUMBER_1">%s</xliff:g> powiadomienia w grupie.</item>
-      <item quantity="many">Jeszcze <xliff:g id="NUMBER_1">%s</xliff:g> powiadomień w grupie.</item>
-      <item quantity="other">Jeszcze <xliff:g id="NUMBER_1">%s</xliff:g> powiadomienia w grupie.</item>
-      <item quantity="one">Jeszcze <xliff:g id="NUMBER_0">%s</xliff:g> powiadomienie w grupie.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Jeszcze # powiadomienie w grupie.}few{Jeszcze # powiadomienia w grupie.}many{Jeszcze # powiadomień w grupie.}other{Jeszcze # powiadomienia w grupie.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekran jest zablokowany w orientacji poziomej."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekran jest zablokowany w orientacji pionowej."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Półka ze słodkościami"</string>
@@ -228,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Autoobracanie"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Autoobracanie ekranu"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokalizacja"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Wygaszacz ekranu"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Dostęp do aparatu"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Dostęp do mikrofonu"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Odblokowany"</string>
@@ -257,12 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Włączam…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Włączono Oszczędzanie danych"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="few">%d urządzenia</item>
-      <item quantity="many">%d urządzeń</item>
-      <item quantity="other">%d urządzenia</item>
-      <item quantity="one">%d urządzenie</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# urządzenie}few{# urządzenia}many{# urządzeń}other{# urządzenia}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Latarka"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Aparat w użyciu"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobilna transmisja danych"</string>
@@ -355,13 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcesz kontynuować sesję?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Rozpocznij nową"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Tak, kontynuuj"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Tryb gościa"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Jesteś w trybie gościa"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dodanie nowego użytkownika spowoduje zamknięcie trybu gościa. Wszystkie aplikacje i dane z obecnej sesji gościa zostaną usunięte."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Osiągnięto limit użytkowników"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="few">Możesz dodać maksymalnie <xliff:g id="COUNT">%d</xliff:g> użytkowników.</item>
-      <item quantity="many">Możesz dodać maksymalnie <xliff:g id="COUNT">%d</xliff:g> użytkowników.</item>
-      <item quantity="other">Możesz dodać maksymalnie <xliff:g id="COUNT">%d</xliff:g> użytkownika.</item>
-      <item quantity="one">Można utworzyć tylko jednego użytkownika.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Można utworzyć tylko 1 użytkownika.}few{Możesz dodać maksymalnie # użytkowników}many{Możesz dodać maksymalnie # użytkowników}other{Możesz dodać maksymalnie # użytkownika}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Usunąć użytkownika?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Wszystkie aplikacje i dane tego użytkownika zostaną usunięte."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Usuń"</string>
@@ -547,18 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Przypomnij"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Cofnij"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Odłożono na <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="few">%d godziny</item>
-      <item quantity="many">%d godzin</item>
-      <item quantity="other">%d godziny</item>
-      <item quantity="one">%d godzina</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="few">%d minuty</item>
-      <item quantity="many">%d minut</item>
-      <item quantity="other">%d minuty</item>
-      <item quantity="one">]%d minuta</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# godzina}=2{# godziny}few{# godziny}many{# godzin}other{# godziny}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuta}few{# minuty}many{# minut}other{# minuty}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Oszczędzanie baterii"</string>
     <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>
@@ -707,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alerty"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Bateria"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Zrzuty ekranu"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Wiadomości"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Aplikacje błyskawiczne"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Konfiguracja"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Pamięć wewnętrzna"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Wskazówki"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Aplikacje błyskawiczne"</string>
@@ -781,12 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"przełącz"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Sterowanie urządzeniami"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Wybierz aplikację, do której chcesz dodać elementy sterujące"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="few">Dodano <xliff:g id="NUMBER_1">%s</xliff:g> elementy sterujące</item>
-      <item quantity="many">Dodano <xliff:g id="NUMBER_1">%s</xliff:g> elementów sterujących</item>
-      <item quantity="other">Dodano <xliff:g id="NUMBER_1">%s</xliff:g> elementu sterującego</item>
-      <item quantity="one">Dodano <xliff:g id="NUMBER_0">%s</xliff:g> element sterujący</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodano # element sterujący.}few{Dodano # elementy sterujące.}many{Dodano # elementów sterujących.}other{Dodano # elementu sterującego.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Usunięto"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano do ulubionych"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano do ulubionych, pozycja <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -943,12 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj kafelek"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nie dodawaj kafelka"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Wybierz użytkownika"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikacje są aktywne</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> aplikacji jest aktywnych</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacji jest aktywne</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikacja jest aktywna</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikacja jest aktywna}few{# aplikacje są aktywne}many{# aplikacji jest aktywnych}other{# aplikacji jest aktywne}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nowa informacja"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktywne aplikacje"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Te aplikacje są aktywne i działają, nawet gdy ich nie używasz. Zwiększa to ich funkcjonalność, ale może również pogarszać żywotność baterii."</string>
@@ -977,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm ustawiony"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Aparat i mikrofon są wyłączone"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# powiadomienie}few{# powiadomienia}many{# powiadomień}other{# powiadomienia}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmisja"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zatrzymaj transmisję aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jeśli transmitujesz aplikację <xliff:g id="SWITCHAPP">%1$s</xliff:g> lub zmieniasz dane wyjściowe, Twoja obecna transmisja zostanie zakończona"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmisja aplikacji <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Zmień dane wyjściowe"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Brak informacji"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index c1a4059..50650986 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Wyłączony"</item>
     <item msgid="460891964396502657">"Włączony"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Brak dostępu"</item>
+    <item msgid="8014986104355098744">"Wyłączono"</item>
+    <item msgid="5966994759929723339">"Włączono"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 2f45ea8..d166901 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"A opção \"Sensores desativados\" está ativa"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Limpar todas as notificações."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"Mais <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Mais <xliff:g id="NUMBER_1">%s</xliff:g> notificações no grupo.</item>
-      <item quantity="other">Mais <xliff:g id="NUMBER_1">%s</xliff:g> notificações no grupo.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Mais # notificação no grupo.}one{Mais # notificação no grupo.}other{Mais # notificações no grupo.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"A tela está bloqueada na orientação paisagem."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"A tela está bloqueada na orientação retrato."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Mostruário de sobremesas"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Protetor de tela"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acesso à câmera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acesso ao microfone"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponível"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Ponto de acesso"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Ativando…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Economia de dados ativada"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d dispositivo</item>
-      <item quantity="other">%d dispositivos</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispositivo}one{# dispositivo}other{# dispositivos}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lanterna"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Câmera em uso"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Dados móveis"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo visitante"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Você está no modo visitante"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ao adicionar um novo usuário, o dispositivo vai sair do modo visitante e excluir todos os apps e dados da Sessão de visitante atual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de usuários atingido"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">É possível adicionar até <xliff:g id="COUNT">%d</xliff:g> usuário.</item>
-      <item quantity="other">É possível adicionar até <xliff:g id="COUNT">%d</xliff:g> usuários.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Você só pode criar 1 usuário.}one{Você pode adicionar até # usuário.}other{Você pode adicionar até # usuários.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Remover usuário?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Todos os apps e dados deste usuário serão excluídos."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Remover"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Lembrete"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Desfazer"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Adiada para <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d hora</item>
-      <item quantity="other">%d horas</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minuto</item>
-      <item quantity="other">%d minutos</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hora}=2{# horas}one{# hora}other{# horas}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuto}one{# minuto}other{# minuto}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Economia de bateria"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertas"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Bateria"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Capturas de tela"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mensagens gerais"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configurar"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Armazenamento"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Dicas"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alternar"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> controle adicionado.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controles adicionados.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}other{# controles adicionados.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adicionar bloco"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Não adicionar bloco"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Selecionar usuário"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app está ativo</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps estão ativos</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app está ativo}one{# apps está ativo}other{# apps estão ativos}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova informação"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativos"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Esses apps ficam ativos e em execução mesmo quando não estão em uso. Isso melhora a funcionalidade deles, mas também pode afetar a duração da bateria."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}other{# notificações}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitindo"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Mudar saída"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecido"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
index abf8749..bc7efe6 100644
--- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Desativado"</item>
     <item msgid="460891964396502657">"Ativado"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Indisponível"</item>
+    <item msgid="8014986104355098744">"Desativado"</item>
+    <item msgid="5966994759929723339">"Ativado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c49ddcb..8c53698 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensores desativados ativo"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Limpar todas as notificações."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Mais <xliff:g id="NUMBER_1">%s</xliff:g> notificações no grupo.</item>
-      <item quantity="one">Mais <xliff:g id="NUMBER_0">%s</xliff:g> notificação no grupo.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Mais # notificação no grupo.}other{Mais # notificações no grupo.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"O ecrã está bloqueado na orientação horizontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"O ecrã está bloqueado na orientação vertical."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Vitrina de sobremesas"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotação auto."</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rodar o ecrã automaticamente"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Proteção de ecrã"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acesso câmara"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Ac. microfone"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponível"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Zona Wi-Fi"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"A ativar..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Poup. dados ativada"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d dispositivos</item>
-      <item quantity="one">%d dispositivo</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispositivo}other{# dispositivos}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lanterna"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Câmara em utilização"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Dados móveis"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Pretende continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo convidado"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Está no modo convidado"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ao adicionar um novo utilizador, o modo convidado é fechado e todas as apps e dados da sessão de convidado atual são eliminados."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de utilizadores alcançado"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Pode adicionar até <xliff:g id="COUNT">%d</xliff:g> utilizadores.</item>
-      <item quantity="one">Apenas é possível criar um utilizador.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Só é possível criar um utilizador.}other{É possível adicionar até # utilizadores.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Remover o utilizador?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Serão eliminados todos os dados e todas as aplicações deste utilizador."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Remover"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Lembrar-me"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Anular"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Suspensa por <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d horas</item>
-      <item quantity="one">%d hora</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minutos</item>
-      <item quantity="one">%d minuto</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hora}=2{# horas}other{# horas}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuto}other{# minutos}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Poupança de bateria"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertas"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Bateria"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Capturas de ecrã"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mensagens gerais"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Apps instantâneas"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configuração"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Armazenamento"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Sugestões"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Apps instantâneas"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ativar/desativar"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controlos de dispositivos"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Escolha uma app para adicionar controlos"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controlos adicionados.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> controlo adicionado.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controlo adicionado.}other{# controlos adicionados.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado aos favoritos"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionados aos favoritos, posição <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adicionar mosaico"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Não adicion. mosaico"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Selecione utilizador"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps estão ativas</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app está ativa</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app está ativa}other{# apps estão ativas}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Novas informações"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativas"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Estas apps estão ativas e a funcionar, mesmo quando não as está a usar. Isto melhora a sua funcionalidade, mas também afeta a autonomia da bateria."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmara e o microfone estão desativados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}other{# notificações}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"A transmitir"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão da app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se transmitir a app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou alterar a saída, a sua transmissão atual é interrompida"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmita a app <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Altere a saída"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecida"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
index c8e557b..0a01020 100644
--- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Desativado"</item>
     <item msgid="460891964396502657">"Ativado"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Indisponível"</item>
+    <item msgid="8014986104355098744">"Desativado"</item>
+    <item msgid="5966994759929723339">"Ativado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 2f45ea8..d166901 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"A opção \"Sensores desativados\" está ativa"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Limpar todas as notificações."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"Mais <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Mais <xliff:g id="NUMBER_1">%s</xliff:g> notificações no grupo.</item>
-      <item quantity="other">Mais <xliff:g id="NUMBER_1">%s</xliff:g> notificações no grupo.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Mais # notificação no grupo.}one{Mais # notificação no grupo.}other{Mais # notificações no grupo.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"A tela está bloqueada na orientação paisagem."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"A tela está bloqueada na orientação retrato."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Mostruário de sobremesas"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Giro automático"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Giro automático da tela"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Protetor de tela"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acesso à câmera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acesso ao microfone"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponível"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Ponto de acesso"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Ativando…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Economia de dados ativada"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d dispositivo</item>
-      <item quantity="other">%d dispositivos</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispositivo}one{# dispositivo}other{# dispositivos}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lanterna"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Câmera em uso"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Dados móveis"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo visitante"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Você está no modo visitante"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ao adicionar um novo usuário, o dispositivo vai sair do modo visitante e excluir todos os apps e dados da Sessão de visitante atual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de usuários atingido"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">É possível adicionar até <xliff:g id="COUNT">%d</xliff:g> usuário.</item>
-      <item quantity="other">É possível adicionar até <xliff:g id="COUNT">%d</xliff:g> usuários.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Você só pode criar 1 usuário.}one{Você pode adicionar até # usuário.}other{Você pode adicionar até # usuários.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Remover usuário?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Todos os apps e dados deste usuário serão excluídos."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Remover"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Lembrete"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Desfazer"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Adiada para <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d hora</item>
-      <item quantity="other">%d horas</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minuto</item>
-      <item quantity="other">%d minutos</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hora}=2{# horas}one{# hora}other{# horas}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuto}one{# minuto}other{# minuto}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Economia de bateria"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertas"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Bateria"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Capturas de tela"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mensagens gerais"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configurar"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Armazenamento"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Dicas"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alternar"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> controle adicionado.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controles adicionados.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}other{# controles adicionados.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adicionar bloco"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Não adicionar bloco"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Selecionar usuário"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app está ativo</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> apps estão ativos</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app está ativo}one{# apps está ativo}other{# apps estão ativos}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nova informação"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Apps ativos"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Esses apps ficam ativos e em execução mesmo quando não estão em uso. Isso melhora a funcionalidade deles, mas também pode afetar a duração da bateria."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarme definido"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}other{# notificações}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitindo"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Mudar saída"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Desconhecido"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
index abf8749..bc7efe6 100644
--- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Desativado"</item>
     <item msgid="460891964396502657">"Ativado"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Indisponível"</item>
+    <item msgid="8014986104355098744">"Desativado"</item>
+    <item msgid="5966994759929723339">"Ativado"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index bebaf0d..88f9963 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -205,11 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Dezactivarea senzorilor este activă"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Ștergeți toate notificările."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="few">Încă <xliff:g id="NUMBER_1">%s</xliff:g> notificări în grup.</item>
-      <item quantity="other">Încă <xliff:g id="NUMBER_1">%s</xliff:g> de notificări în grup.</item>
-      <item quantity="one">Încă <xliff:g id="NUMBER_0">%s</xliff:g> notificare în grup.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Încă # notificare în grup.}few{Încă # notificări în grup.}other{Încă # de notificări în grup.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ecranul este blocat în orientarea de tip peisaj."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ecranul este blocat în orientarea de tip portret."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Vitrina cu dulciuri"</string>
@@ -227,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotire automată"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotirea automată a ecranului"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Locație"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screensaver"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acces la cameră"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acces la microfon"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponibil"</string>
@@ -256,11 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Se activează..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Economizor date activat"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="few">%d dispozitive</item>
-      <item quantity="other">%d de dispozitive</item>
-      <item quantity="one">%d dispozitiv</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispozitiv}few{# dispozitive}other{# de dispozitive}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Lanternă"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Se folosește camera foto"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Date mobile"</string>
@@ -353,12 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vreți să continuați sesiunea?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Începeți din nou"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, continuați"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modul pentru invitați"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Folosiți modul pentru invitați"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dacă adăugați un utilizator nou, veți ieși din modul pentru invitați și se vor șterge toate aplicațiile și datele din sesiunea pentru invitați actuală."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Ați atins limita de utilizatori"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="few">Puteți adăuga maximum <xliff:g id="COUNT">%d</xliff:g> utilizatori.</item>
-      <item quantity="other">Puteți adăuga maximum <xliff:g id="COUNT">%d</xliff:g> de utilizatori.</item>
-      <item quantity="one">Poate fi creat doar un utilizator.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Se poate crea doar un utilizator.}few{Puteți adăuga până la # utilizatori.}other{Puteți adăuga până la # de utilizatori.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Eliminați utilizatorul?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Toate aplicațiile și datele acestui utilizator vor fi șterse."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Eliminați"</string>
@@ -544,16 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Reamintește-mi"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Anulați"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Amânată <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="few">%d ore</item>
-      <item quantity="other">%d de ore</item>
-      <item quantity="one">%d oră</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="few">%d minute</item>
-      <item quantity="other">%d de minute</item>
-      <item quantity="one">%d minut</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# oră}=2{# ore}few{# ore}other{# de ore}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minut}few{# minute}other{# de minute}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Economisirea bateriei"</string>
     <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>
@@ -702,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alerte"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Baterie"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Capturi de ecran"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mesaje generale"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Aplicații instantanee"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Configurarea"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Stocare"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Indicii"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Aplicații instantanee"</string>
@@ -776,11 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"Activați / dezactivați"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Comenzile dispozitivelor"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Alegeți aplicația pentru a adăuga comenzi"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="few">S-au adăugat <xliff:g id="NUMBER_1">%s</xliff:g> comenzi.</item>
-      <item quantity="other">S-au adăugat <xliff:g id="NUMBER_1">%s</xliff:g> de comenzi.</item>
-      <item quantity="one">S-a adăugat <xliff:g id="NUMBER_0">%s</xliff:g> comandă.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S-a adăugat # comandă.}few{S-au adăugat # comenzi.}other{S-au adăugat # de comenzi.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Eliminată"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Marcată ca preferată"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Marcată ca preferată, poziția <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -937,11 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Adăugați un card"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nu adăugați un card"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Alegeți utilizatorul"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplicații sunt active</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> de aplicații sunt active</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplicație este activă</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplicație este activă}few{# aplicații sunt active}other{# de aplicații sunt active}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informații noi"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicații active"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Aceste aplicații sunt active și rulează, chiar dacă nu le folosiți. Astfel, funcțiile lor sunt îmbunătățite, dar autonomia bateriei poate fi afectată."</string>
@@ -970,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmă setată"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera și microfonul sunt dezactivate"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificare}few{# notificări}other{# de notificări}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Se difuzează"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Opriți difuzarea <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Dacă difuzați <xliff:g id="SWITCHAPP">%1$s</xliff:g> sau schimbați rezultatul, difuzarea actuală se va opri"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Difuzați <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Schimbați rezultatul"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Necunoscută"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
index 1ad0a75..7b7bb3a 100644
--- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Dezactivat"</item>
     <item msgid="460891964396502657">"Activat"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Indisponibil"</item>
+    <item msgid="8014986104355098744">"Dezactivat"</item>
+    <item msgid="5966994759929723339">"Activat"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 1cbb45f..fefdd81 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -205,12 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Датчики отключены"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Удалить все уведомления"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Ещё <xliff:g id="NUMBER_1">%s</xliff:g> уведомление.</item>
-      <item quantity="few">Ещё <xliff:g id="NUMBER_1">%s</xliff:g> уведомления.</item>
-      <item quantity="many">Ещё <xliff:g id="NUMBER_1">%s</xliff:g> уведомлений.</item>
-      <item quantity="other">Ещё <xliff:g id="NUMBER_1">%s</xliff:g> уведомления.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Доступно ещё # уведомление.}one{Доступно ещё # уведомление.}few{Доступны ещё # уведомления.}many{Доступно ещё # уведомлений.}other{Доступно ещё # уведомления.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Выбрана только альбомная ориентация экрана."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Выбрана только книжная ориентация экрана."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Коробка со сладостями"</string>
@@ -228,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоповорот"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоповорот экрана"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Геолокация"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Заставка"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ к камере"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Доступ к микрофону"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Доступно"</string>
@@ -257,12 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Точка доступа"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Включение…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Экономия трафика вкл."</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d устройство</item>
-      <item quantity="few">%d устройства</item>
-      <item quantity="many">%d устройств</item>
-      <item quantity="other">%d устройства</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# устройство}one{# устройство}few{# устройства}many{# устройств}other{# устройства}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Фонарик"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Используется камера"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мобильный интернет"</string>
@@ -355,13 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Продолжить сеанс?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Начать заново"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продолжить"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Гостевой режим"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Включен гостевой режим"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Добавив нового пользователя, вы выйдете из гостевого режима. Все приложения и данные в текущем гостевом сеансе будут удалены."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнут лимит"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Можно добавить не более <xliff:g id="COUNT">%d</xliff:g> пользователя.</item>
-      <item quantity="few">Можно добавить не более <xliff:g id="COUNT">%d</xliff:g> пользователей.</item>
-      <item quantity="many">Можно добавить не более <xliff:g id="COUNT">%d</xliff:g> пользователей.</item>
-      <item quantity="other">Можно добавить не более <xliff:g id="COUNT">%d</xliff:g> пользователя.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Можно создать только одного пользователя.}one{Вы можете добавить до # пользователя.}few{Вы можете добавить до # пользователей.}many{Вы можете добавить до # пользователей.}other{Вы можете добавить до # пользователя.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Удалить аккаунт?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Все приложения и данные этого пользователя будут удалены."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Удалить"</string>
@@ -547,18 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Добавить напоминание"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Отменить"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Отложено на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d час</item>
-      <item quantity="few">%d часа</item>
-      <item quantity="many">%d часов</item>
-      <item quantity="other">%d часа</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d минута</item>
-      <item quantity="few">%d минуты</item>
-      <item quantity="many">%d минут</item>
-      <item quantity="other">%d минуты</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# час}=2{# часа}one{# час}few{# часа}many{# часов}other{# часа}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# минута}one{# минута}few{# минуты}many{# минут}other{# минуты}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Режим энергосбережения"</string>
     <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>
@@ -707,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Оповещения"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Батарея"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Скриншоты"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Сообщения"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Приложения с мгновенным запуском"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Настройка"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Хранилище"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Подсказки"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Приложения с мгновенным запуском"</string>
@@ -781,12 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"включить или отключить"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Управление устройствами"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Чтобы добавить виджеты управления, выберите приложение"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one">Добавлен <xliff:g id="NUMBER_1">%s</xliff:g> элемент управления.</item>
-      <item quantity="few">Добавлено <xliff:g id="NUMBER_1">%s</xliff:g> элемента управления.</item>
-      <item quantity="many">Добавлено <xliff:g id="NUMBER_1">%s</xliff:g> элементов управления.</item>
-      <item quantity="other">Добавлено <xliff:g id="NUMBER_1">%s</xliff:g> элемента управления.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавлен # элемент управления.}one{Добавлен # элемент управления.}few{Добавлено # элемента управления.}many{Добавлено # элементов управления.}other{Добавлено # элемента управления.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Удалено"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Добавлено в избранное"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Добавлено в избранное на позицию <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -943,12 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Добавить параметр"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Не добавлять"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Выберите профиль"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one">Активно <xliff:g id="COUNT_1">%s</xliff:g> приложение</item>
-      <item quantity="few">Активно <xliff:g id="COUNT_1">%s</xliff:g> приложения</item>
-      <item quantity="many">Активно <xliff:g id="COUNT_1">%s</xliff:g> приложений</item>
-      <item quantity="other">Активно <xliff:g id="COUNT_1">%s</xliff:g> приложения</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# приложение активно}one{# приложение активно}few{# приложения активны}many{# приложений активно}other{# приложения активно}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Новая информация"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активные приложения"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Эти приложения работают и остаются активными, даже когда вы их не используете. Это дает дополнительные возможности, но может сократить время работы от батареи."</string>
@@ -977,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлен"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон отключены"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# уведомление}one{# уведомление}few{# уведомления}many{# уведомлений}other{# уведомления}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляция"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Остановить трансляцию \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Если вы начнете транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" или смените целевое устройство, текущая трансляция прервется."</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\""</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Транслировать на другое устройство"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Неизвестно"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
index e1ee39f..6255bd8 100644
--- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Отключен"</item>
     <item msgid="460891964396502657">"Включен"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Недоступно"</item>
+    <item msgid="8014986104355098744">"Отключено"</item>
+    <item msgid="5966994759929723339">"Включено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index be3a8ac..3c0d839 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"සංවේදක ක්‍රියාවිරහිතය සක්‍රියයි"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"සියලු දැනුම්දීම් හිස් කරන්න."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">ඇතුළත තව දැනුම්දීම් <xliff:g id="NUMBER_1">%s</xliff:g>ක් ඇත.</item>
-      <item quantity="other">ඇතුළත තව දැනුම්දීම් <xliff:g id="NUMBER_1">%s</xliff:g>ක් ඇත.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{ඇතුළත තව # දැනුම්දීමක් ඇත.}one{ඇතුළත තව දැනුම්දීම් #ක් ඇත.}other{ඇතුළත තව දැනුම්දීම් #ක් ඇත.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"තිරය තිරස් දිශානතියෙහි අගුළු දමා ඇත."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"තිරය සිරස් දිශානතිය තුළ අගුළු වැටී ඇත."</string>
     <string name="dessert_case" msgid="9104973640704357717">"අතුරුපස අවස්තාව"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ස්වයංක්‍රීය කරකැවීම"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ස්වයංක්‍රීයව-භ්‍රමණය වන තිරය"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ස්ථානය"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"තිර සුරැකුම"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"කැමරා ප්‍රවේශය"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"මයික් ප්‍රවේශය"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"තිබේ"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"හොට්ස්පොට්"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ක්‍රියාවිරහිත කරමින්…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"දත්ත සුරැකුම ක්‍රියාත්මකයි"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">උපාංග %d</item>
-      <item quantity="other">උපාංග %d</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# උපාංගයක්}one{උපාංග #ක්}other{උපාංග #ක්}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"සැණෙළි ආලෝකය"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"කැමරාව භාවිතයේ ඇත"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"ජංගම දත්ත"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ඔබගේ සැසිය දිගටම කරගෙන යෑමට ඔබට අවශ්‍යද?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"යළි මුල සිට අරඹන්න"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ඔව්, දිගටම කරගෙන යන්න"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"ආගන්තුක ප්‍රකාරය"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"ඔබ ආගන්තුක ප්‍රකාරයේ සිටී"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"නව පරිශීලකයෙකු එක් කිරීම ආගන්තුක මාදිලියෙන් පිටවී වත්මන් ආගන්තුක සැසියෙන් සියලුම යෙදුම් සහ දත්ත මකනු ඇත."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"පරිශීලක සීමාවට ළඟා විය"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">ඔබට පරිශීලකයින් <xliff:g id="COUNT">%d</xliff:g>ක් දක්වා එක් කළ හැකිය.</item>
-      <item quantity="other">ඔබට පරිශීලකයින් <xliff:g id="COUNT">%d</xliff:g>ක් දක්වා එක් කළ හැකිය.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{එක් පරිශීලකයෙක් පමණක් තැනීම කළ හැක.}one{ඔබට පරිශීලකයන් #ක් දක්වා එක් කළ හැක.}other{ඔබට පරිශීලකයන් #ක් දක්වා එක් කළ හැක.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"පරිශීලකයා ඉවත් කරන්නද?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"මෙම පරිශීලකයාගේ සියලු යෙදුම් සහ දත්ත මකනු ඇත."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"ඉවත් කරන්න"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"මට මතක් කරන්න"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"පසුගමනය කරන්න"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ක් මදක් නතර කරන ලදී"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">පැය %d</item>
-      <item quantity="other">පැය %d</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">මිනිත්තු %d</item>
-      <item quantity="other">මිනිත්තු %d</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{පැය #ක්}=2{පැය #ක්}one{පැය #ක්}other{පැය #ක්}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{මිනිත්තු #ක්}one{මිනිත්තු #ක්}other{මිනිත්තු #ක්}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"බැටරි සුරැකුම"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"ඇඟවීම්"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"බැටරිය"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"තිර රු"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"පොදු පණිවිඩ"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"ක්ෂණික යෙදුම්"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"පිහිටුවීම"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"ගබඩාව"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"ඉඟි"</string>
     <string name="instant_apps" msgid="8337185853050247304">"ක්ෂණික යෙදුම්"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ටොගල් කරන්න"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"උපාංග පාලන"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"පාලන එක් කිරීමට යෙදුම තෝරා ගන්න"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one">පාලන <xliff:g id="NUMBER_1">%s</xliff:g>ක් එක් කරන ලදී.</item>
-      <item quantity="other">පාලන <xliff:g id="NUMBER_1">%s</xliff:g>ක් එක් කරන ලදී.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# පාලනයක් එක් කර ඇත.}one{පාලන #ක් එක් කර ඇත.}other{පාලන #ක් එක් කර ඇත.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ඉවත් කළා"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ප්‍රියතම කළා"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ප්‍රියතම කළා, තත්ත්ව <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ටයිල් එක් කරන්න"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ටයිල් එක් නොකරන්න"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"පරිශීලක තෝරන්න"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one">යෙදුම් <xliff:g id="COUNT_1">%s</xliff:g>ක් සක්‍රියයි</item>
-      <item quantity="other">යෙදුම් <xliff:g id="COUNT_1">%s</xliff:g>ක් සක්‍රියයි</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# යෙදුමක් සක්‍රියයි}one{යෙදුම් #ක් සක්‍රියයි}other{යෙදුම් #ක් සක්‍රියයි}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"නව තොරතුරු"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"සක්‍රිය යෙදුම්"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"ඔබ මේවා භාවිත නොකරමින් සිටින විට පවා මෙම යෙදුම් ක්‍රියාකාරීව සහ ධාවනය වෙමින් පවතියි. මෙය මේවායේ කාර්යය වැඩිදියුණු කරයි, නමුත් බැටරි ආයු කාලයට ද බලපා හැකි ය."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"සීනුව සකසන ලදි"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"කැමරාව සහ මයික් ක්‍රියාවිරහිතයි"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{දැනුම්දීම් #ක්}one{දැනුම්දීම් #ක්}other{දැනුම්දීම් #ක්}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"විකාශනය කරමින්"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> විකාශනය කිරීම නවත්වන්නද?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ඔබ <xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය කළහොත් හෝ ප්‍රතිදානය වෙනස් කළහොත්, ඔබගේ වත්මන් විකාශනය නවතිනු ඇත."</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"ප්‍රතිදානය වෙනස් කරන්න"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"නොදනී"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml
index 8a16acb..327e0b9 100644
--- a/packages/SystemUI/res/values-si/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"ක්‍රියාවිරහිතයි"</item>
     <item msgid="460891964396502657">"ක්‍රියාත්මකයි"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"නොමැත"</item>
+    <item msgid="8014986104355098744">"ක්‍රියාවිරහිතයි"</item>
+    <item msgid="5966994759929723339">"ක්‍රියාත්මකයි"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 129f490..cbd4559 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -205,12 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Funkcia Senzory sú vypnuté je aktívna"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Vymazať všetky upozornenia."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="few">Skupina obsahuje ešte <xliff:g id="NUMBER_1">%s</xliff:g> upozornenia.</item>
-      <item quantity="many">Skupina obsahuje ešte <xliff:g id="NUMBER_1">%s</xliff:g> upozornenia.</item>
-      <item quantity="other">Skupina obsahuje ešte <xliff:g id="NUMBER_1">%s</xliff:g> upozornení.</item>
-      <item quantity="one">Skupina obsahuje ešte <xliff:g id="NUMBER_0">%s</xliff:g> upozornenie.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# ďalšie upozornenie v skupine.}few{# ďalšie upozornenia v skupine.}many{# more notifications inside.}other{# ďalších upozornení v skupine.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Obrazovka je uzamknutá v orientácii na šírku."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Obrazovka je uzamknutá v orientácii na výšku."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Pult s dezertami"</string>
@@ -228,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Automatické otáčanie"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatické otáčanie obrazovky"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Poloha"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Šetrič obrazovky"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Prístup ku kamere"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Prístup k mikrofónu"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"K dispozícii"</string>
@@ -257,12 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Zapína sa…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Šetrič dát – zapnutý"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="few">%d zariadenia</item>
-      <item quantity="many">%d zariadenia</item>
-      <item quantity="other">%d zariadení</item>
-      <item quantity="one">%d zariadenie</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# zariadenie}few{# zariadenia}many{# devices}other{# zariadení}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Baterka"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Fotoaparát sa používa"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobilné dáta"</string>
@@ -355,13 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relácii pokračovať?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začať odznova"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Áno, pokračovať"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Režim pre hostí"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Ste v režime pre hostí"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ak pridáte nového používatelia, ukončí sa režim pre hostí a odstránia sa všetky aplikácie a údaje z aktuálnej relácie hosťa."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dosiahnutý limit počtu používateľov"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="few">Môžete pridať maximálne <xliff:g id="COUNT">%d</xliff:g> používateľov.</item>
-      <item quantity="many">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
-      <item quantity="other">Môžete pridať maximálne <xliff:g id="COUNT">%d</xliff:g> používateľov.</item>
-      <item quantity="one">Môžete vytvoriť iba jedného používateľa.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Môžete vytvoriť iba jedného používateľa.}few{Môžete pridať až # používateľov.}many{You can add up to # users.}other{Môžete pridať až # používateľov.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Odstrániť používateľa?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Všetky aplikácie a údaje tohto používateľa budú odstránené."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Odstrániť"</string>
@@ -547,18 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Pripomenúť"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Späť"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Stlmené na <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="few">%d hodiny</item>
-      <item quantity="many">%d hodiny</item>
-      <item quantity="other">%d hodín</item>
-      <item quantity="one">%d hodina</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="few">%d minúty</item>
-      <item quantity="many">%d minúty</item>
-      <item quantity="other">%d minút</item>
-      <item quantity="one">%d minúta</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hodina}=2{# hodiny}few{# hodiny}many{# hodiny}other{# hodín}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minúta}few{# minúty}many{# minúty}other{# minút}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Šetrič batérie"</string>
     <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>
@@ -707,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Upozornenia"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batéria"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Snímky obrazovky"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Všeobecné správy"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Okamžité aplikácie"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Nastavenie"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Úložisko"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Tipy"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Okamžité aplikácie"</string>
@@ -781,12 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"prepínač"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Ovládanie zariadení"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Vyberte aplikáciu, ktorej ovládače si chcete pridať"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="few">Boli pridané <xliff:g id="NUMBER_1">%s</xliff:g> ovládacie prvky.</item>
-      <item quantity="many"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item>
-      <item quantity="other">Bolo pridaných <xliff:g id="NUMBER_1">%s</xliff:g> ovládacích prvkov.</item>
-      <item quantity="one">Bol pridaný <xliff:g id="NUMBER_0">%s</xliff:g> ovládací prvok.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Bol pridaný # ovládací prvok.}few{Boli pridané # ovládacie prvky.}many{# controls added.}other{Bolo pridaných # ovládacích prvkov.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Odstránené"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Pridané medzi obľúbené"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Pridané medzi obľúbené, pozícia <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -943,12 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Pridať kartu"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Nepridať kartu"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Vyberte používateľa"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikácie sú aktívne</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> apps are active</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikácií je aktívnych</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikácia je aktívna</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikácia je aktívna}few{# aplikácie sú aktívne}many{# apps are active}other{# aplikácií je aktívnych}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nové informácie"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktívne aplikácie"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Tieto aplikácie sú spustené a aktívne, aj keď ich nepoužívate. Zlepšuje to ich funkčnosť, ale môže to mať vplyv aj na výdrž batérie."</string>
@@ -977,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Budík je nastavený"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera a mikrofón sú vypnuté"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# upozornenie}few{# upozornenia}many{# notifications}other{# upozornení}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysiela"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Chcete zastaviť vysielanie aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ak vysielate aplikáciu <xliff:g id="SWITCHAPP">%1$s</xliff:g> alebo zmeníte výstup, aktuálne vysielanie bude zastavené"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Vysielanie aplikácie <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Zmena výstupu"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznáme"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
index dcdfb3a..3cbde1c 100644
--- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Vypnuté"</item>
     <item msgid="460891964396502657">"Zapnuté"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Nedostupné"</item>
+    <item msgid="8014986104355098744">"Vypnuté"</item>
+    <item msgid="5966994759929723339">"Zapnuté"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index dbb0942..e723b1b 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -205,12 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Izklop za tipala je aktiven"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Izbriši vsa obvestila."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"in <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Notri je še <xliff:g id="NUMBER_1">%s</xliff:g> obvestilo.</item>
-      <item quantity="two">Notri sta še <xliff:g id="NUMBER_1">%s</xliff:g> obvestili.</item>
-      <item quantity="few">Notri so še <xliff:g id="NUMBER_1">%s</xliff:g> obvestila.</item>
-      <item quantity="other">Notri je še <xliff:g id="NUMBER_1">%s</xliff:g> obvestil.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Notri je še # obvestilo.}one{Notri je še # obvestilo.}two{Notri sta še # obvestili.}few{Notri so še # obvestila.}other{Notri je še # obvestil.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Zaslon je zaklenjen v ležeči usmerjenosti."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Zaslon je zaklenjen v pokončni usmerjenosti."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Vitrina za sladice"</string>
@@ -228,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Samodejno sukanje"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Samodejno sukanje zaslona"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Ohranjevalnik zaslona"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Dostop do fotoaparata"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Dostop do mikrofona"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Na voljo"</string>
@@ -257,12 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Dostopna točka"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Vklapljanje …"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Varč. s pod. je vkl."</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d naprava</item>
-      <item quantity="two">%d napravi</item>
-      <item quantity="few">%d naprave</item>
-      <item quantity="other">%d naprav</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# naprava}one{# naprava}two{# napravi}few{# naprave}other{# naprav}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Svetilka"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Fotoaparat je v uporabi"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Prenos podatkov v mobilnem omrežju"</string>
@@ -355,13 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite nadaljevati sejo?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začni znova"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nadaljuj"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Način za goste"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Ste v načinu za goste"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Če dodate novega uporabnika, se bo način za goste zaprl, aplikacije in podatki v trenutni seji gosta pa bodo izbrisani."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Omejitev uporabnikov je dosežena"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Dodate lahko do <xliff:g id="COUNT">%d</xliff:g> uporabnika.</item>
-      <item quantity="two">Dodate lahko do <xliff:g id="COUNT">%d</xliff:g> uporabnika.</item>
-      <item quantity="few">Dodate lahko do <xliff:g id="COUNT">%d</xliff:g> uporabnike.</item>
-      <item quantity="other">Dodate lahko do <xliff:g id="COUNT">%d</xliff:g> uporabnikov.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Ustvariti je mogoče samo enega uporabnika.}one{Dodate lahko največ # uporabnika.}two{Dodate lahko največ # uporabnika.}few{Dodate lahko največ # uporabnike.}other{Dodate lahko največ # uporabnikov.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Želite odstraniti uporabnika?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Vse aplikacije in podatki tega uporabnika bodo izbrisani."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Odstrani"</string>
@@ -547,18 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Opomni me"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Razveljavi"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Preloženo za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d ura</item>
-      <item quantity="two">%d uri</item>
-      <item quantity="few">%d ure</item>
-      <item quantity="other">%d ur</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minuta</item>
-      <item quantity="two">%d minuti</item>
-      <item quantity="few">%d minute</item>
-      <item quantity="other">%d minut</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ura}=2{# uri}one{# ura}two{# uri}few{# ure}other{# ur}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuta}one{# minuta}two{# minuti}few{# minute}other{# minut}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Varčevanje z energijo baterije"</string>
     <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>
@@ -707,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Opozorila"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Baterija"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Posnetki zaslona"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Splošna sporočila"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Nenamestljive aplikacije"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Nastavitev"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Shramba"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Namigi"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Nenamestljive aplikacije"</string>
@@ -781,12 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"preklop"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrolniki naprave"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Izberite aplikacijo za dodajanje kontrolnikov"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> kontrolnik dodan.</item>
-      <item quantity="two"><xliff:g id="NUMBER_1">%s</xliff:g> kontrolnika dodana.</item>
-      <item quantity="few"><xliff:g id="NUMBER_1">%s</xliff:g> kontrolniki dodani.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontrolnikov dodanih.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrolnik je dodan.}one{# kontrolnik je dodan.}two{# kontrolnika sta dodana.}few{# kontrolniki so dodani.}other{# kontrolnikov je dodanih.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Odstranjeno"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano med priljubljene"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano med priljubljene, položaj <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -943,12 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Dodaj ploščico"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne dodaj ploščice"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Izberite uporabnika"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> aplikacija je aktivna</item>
-      <item quantity="two"><xliff:g id="COUNT_1">%s</xliff:g> aplikaciji sta aktivni</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> aplikacije so aktivne</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacij je aktivnih</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikacija je aktivna.}one{# aplikacija je aktivna.}two{# aplikaciji sta aktivni.}few{# aplikacije so aktivne.}other{# aplikacij je aktivnih.}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nove informacije"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktivne aplikacije"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Te aplikacije so aktivne in se izvajajo, tudi ko jih ne uporabljate. To sicer izboljša njihovo delovanje, vendar lahko hkrati vpliva na čas delovanja baterije."</string>
@@ -977,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm je nastavljen."</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat in mikrofon sta izklopljena."</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obvestilo}one{# obvestilo}two{# obvestili}few{# obvestila}other{# obvestil}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Oddajanje"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite ustaviti oddajanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Če oddajate aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g> ali spremenite izhod, bo trenutno oddajanje ustavljeno."</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Oddajaj aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Sprememba izhoda"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Neznano"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
index f1ebee4..e720819 100644
--- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Izklopljeno"</item>
     <item msgid="460891964396502657">"Vklopljeno"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Ni na voljo"</item>
+    <item msgid="8014986104355098744">"Izklopljeno"</item>
+    <item msgid="5966994759929723339">"Vklopljeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index c3c638a..4b19b36 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Çaktivizimi i sensorëve aktiv"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Pastro të gjitha njoftimet."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> njoftime të tjera në brendësi.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> njoftim tjetër në brendësi.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# njoftim tjetër në brendësi.}other{# njoftime të tjera në brendësi.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekrani është i kyçur në orientimin horizontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekrani është i kyçur në orientimin vertikal."</string>
     <string name="dessert_case" msgid="9104973640704357717">"\"Kutia e ëmbëlsirës\""</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rrotullim automatik"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rrotullimi automatik i ekranit"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Vendndodhja"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Mbrojtësi i ekranit"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Qasja te kamera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Qasja te mikrofoni"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"E disponueshme"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Qasje në zona publike interneti"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Po aktivizohet…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Kursyesi i të dhënave është aktiv"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d pajisje</item>
-      <item quantity="one">%d pajisje</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# pajisje}other{# pajisje}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Elektriku"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera në përdorim"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Të dhënat celulare"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Po, vazhdo"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modaliteti \"vizitor\""</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Je në modalitetin \"vizitor\""</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Shtimi i një përdoruesi të ri do të të nxjerrë nga modaliteti \"vizitor\" dhe do të fshijë të gjitha aplikacionet dhe të dhënat nga sesioni aktual për vizitorë."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"U arrit kufiri i përdoruesve"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Mund të shtosh deri në <xliff:g id="COUNT">%d</xliff:g> përdorues.</item>
-      <item quantity="one">Mund të krijohet vetëm një përdorues.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Mund të krijohet vetëm një përdorues.}other{Mund të shtosh deri në # përdorues.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Të hiqet ky përdorues?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Të gjitha aplikacionet dhe të dhënat e këtij përdoruesi do të fshihen."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Hiqe"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Më kujto"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Zhbëj"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"U shty për <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d orë</item>
-      <item quantity="one">%d orë</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minuta</item>
-      <item quantity="one">%d minutë</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# orë}=2{# orë}other{# orë}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minutë}other{# minuta}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Kursyesi i baterisë"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Sinjalizimet"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Bateria"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Pamje ekrani"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mesazhe të përgjithshme"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Aplikacionet e çastit"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Konfigurimi"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Hapësira ruajtëse"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Sugjerimet"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Aplikacionet e çastit"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"aktivizo/çaktivizo"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Kontrollet e pajisjes"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Zgjidh aplikacionin për të shtuar kontrollet"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">U shtuan <xliff:g id="NUMBER_1">%s</xliff:g> kontrolle.</item>
-      <item quantity="one">U shtua <xliff:g id="NUMBER_0">%s</xliff:g> kontroll.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{U shtua # kontroll.}other{U shtuan # kontrolle.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"E hequr"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"E shtuar te të preferuarat"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"E shtuar te të preferuarat, pozicioni <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Shto një pllakëz"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Mos e shto pllakëzën"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Zgjidh përdoruesin"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> aplikacione janë aktive</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> aplikacion është aktiv</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplikacion është aktiv}other{# aplikacione janë aktive}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informacion i ri"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplikacionet aktive"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Këto aplikacione janë aktive dhe funksionojnë edhe kur nuk i përdor ato. Kjo përmirëson funksionalitetin e tyre, por mund të ndikojë edhe te kohëzgjatja e baterisë."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmi është caktuar"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dhe mikrofoni janë joaktivë"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# njoftim}other{# njoftime}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Po transmeton"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Të ndalohet transmetimi i <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nëse transmeton <xliff:g id="SWITCHAPP">%1$s</xliff:g> ose ndryshon daljen, transmetimi yt aktual do të ndalojë"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Transmeto <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ndrysho daljen"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"I panjohur"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index e24abf6..7a09f24 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Joaktiv"</item>
     <item msgid="460891964396502657">"Aktiv"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Nuk ofrohet"</item>
+    <item msgid="8014986104355098744">"Joaktiv"</item>
+    <item msgid="5966994759929723339">"Aktiv"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index a06931c..15d31bd 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -205,11 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Сензори су искључени"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Обриши сва обавештења."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"и још <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Још <xliff:g id="NUMBER_1">%s</xliff:g> обавештење у групи.</item>
-      <item quantity="few">Још <xliff:g id="NUMBER_1">%s</xliff:g> обавештења у групи.</item>
-      <item quantity="other">Још <xliff:g id="NUMBER_1">%s</xliff:g> обавештења у групи.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Унутра је још # обавештење.}one{Унутра је још # обавештење.}few{Унутра су још # обавештења.}other{Унутра је још # обавештења.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Екран је закључан у хоризонталном положају."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Екран је закључан у вертикалном положају."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Витрина са посластицама"</string>
@@ -227,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аутоматска ротација"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аутоматско ротирање екрана"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Локација"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Чувар екрана"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Приступ камери"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Приступ микрофону"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Доступно"</string>
@@ -256,11 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Хотспот"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Укључује се..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Уштеда података је укључена"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d уређај</item>
-      <item quantity="few">%d уређаја</item>
-      <item quantity="other">%d уређаја</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# уређај}one{# уређај}few{# уређаја}other{# уређаја}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Лампа"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Користи се камера"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мобилни подаци"</string>
@@ -353,12 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Желите ли да наставите сесију?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни из почетка"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, настави"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Режим госта"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Користите режим госта"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Додавањем новог корисника изаћи ћете из режима госта и избрисаћете све апликације и податке из актуелне сесије госта."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнут максимални број корисника"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Можете да додате највише <xliff:g id="COUNT">%d</xliff:g> корисника.</item>
-      <item quantity="few">Можете да додате највише <xliff:g id="COUNT">%d</xliff:g> корисника.</item>
-      <item quantity="other">Можете да додате највише <xliff:g id="COUNT">%d</xliff:g> корисника.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Можете да направите само једног корисника.}one{Можете да додате највише # корисника.}few{Можете да додате највише # корисника.}other{Можете да додате највише # корисника.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Желите ли да уклоните корисника?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Све апликације и подаци овог корисника ће бити избрисани."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Уклони"</string>
@@ -544,16 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Подсети ме"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Опозови"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Одложено је за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d сат</item>
-      <item quantity="few">%d сата</item>
-      <item quantity="other">%d сати</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d минут</item>
-      <item quantity="few">%d минута</item>
-      <item quantity="other">%d минута</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# сат}=2{# сата}one{# сат}few{# сата}other{# сати}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# минут}one{# минут}few{# минута}other{# минута}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Уштеда батерије"</string>
     <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>
@@ -702,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Обавештења"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Батерија"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Снимци екрана"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Опште поруке"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Инстант апликације"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Подешавање"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Меморијски простор"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Савети"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Инстант апликације"</string>
@@ -776,11 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"укључите/искључите"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Контроле уређаја"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Одаберите апликацију за додавање контрола"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> контрола је додата.</item>
-      <item quantity="few"><xliff:g id="NUMBER_1">%s</xliff:g> контроле су додате.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> контрола је додато.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# контрола је додата.}one{# контрола је додата.}few{# контроле су додате.}other{# контрола је додато.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Уклоњено"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено је као омиљено"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено је као омиљено, <xliff:g id="NUMBER">%d</xliff:g>. позиција"</string>
@@ -937,11 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Додај плочицу"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Не додај плочицу"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Изаберите корисника"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> апликација је активна</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> апликације су активне</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> апликација је активно</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# апликација је активна}one{# апликација је активна}few{# апликације су активне}other{# апликација је активно}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нове информације"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активне апликације"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ове апликације су активне и раде чак и када их не користите. То им побољшава функционалност, али може да утиче и на трајање батерије."</string>
@@ -970,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Аларм је подешен"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон су искључени"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# обавештење}one{# обавештење}few{# обавештења}other{# обавештења}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитовање"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Желите да зауставите емитовање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитујете апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените излаз, актуелно емитовање ће се зауставити"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Емитујте апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Промените излаз"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Непознато"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
index 0cef5a6..dace491 100644
--- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Искључено"</item>
     <item msgid="460891964396502657">"Укључено"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Недоступно"</item>
+    <item msgid="8014986104355098744">"Искључено"</item>
+    <item msgid="5966994759929723339">"Укључено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 3c6d61d..effe9e5 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensorer har inaktiverats"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Ta bort alla meddelanden."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"<xliff:g id="NUMBER">%s</xliff:g> till"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> fler aviseringar i gruppen.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> till avisering i gruppen.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# till avisering i gruppen.}other{# till aviseringar i gruppen.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Bildskärmens riktning är nu låst i liggande format."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Bildskärmens riktning är nu låst i stående format."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessertdisken"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotera automatiskt"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotera skärmen automatiskt"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Plats"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Skärmsläckare"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameraåtkomst"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonåtkomst"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Tillgänglig"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Surfzon"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Aktiverar …"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Databesparing på"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d enheter</item>
-      <item quantity="one">%d enhet</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# enhet}other{# enheter}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Ficklampa"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kameran används"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobildata"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vill du fortsätta sessionen?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Börja om"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsätt"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Gästläge"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Du är i gästläge"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Om du lägger till en ny användare avslutas gästläget och alla appar och all data från den aktuella gästsessionen raderas."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Användargränsen har nåtts"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Det går att lägga till upp till <xliff:g id="COUNT">%d</xliff:g> användare.</item>
-      <item quantity="one">Det går bara att skapa en användare.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Högst en användare kan skapas.}other{Du kan lägga till upp till # användare.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Vill du ta bort användaren?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Alla appar och all data som tillhör den här användaren raderas."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Ta bort"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Påminn mig"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Ångra"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Snoozad i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d timmar</item>
-      <item quantity="one">%d timme</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d minuter</item>
-      <item quantity="one">%d minut</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# timme}=2{# timmar}other{# timmar}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minut}other{# minuter}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Batterisparläge"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Aviseringar"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batteri"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skärmbilder"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Allmänna meddelanden"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Konfigurering"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Lagring"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Tips"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Snabbappar"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"aktivera och inaktivera"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Enhetsstyrning"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Välj en app om du vill lägga till snabbkontroller"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontroller har lagts till.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontroll har lagts till.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll har lagts till.}other{# kontroller har lagts till.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Har tagits bort"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Har lagts till som favorit"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Har lagts till som favorit, plats <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Lägg till ruta"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Lägg inte till ruta"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Välj användare"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> appar är aktiva</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> app är aktiv</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# app är aktiv}other{# appar är aktiva}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Ny information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aktiva appar"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Dessa appar är aktiva och körs även när du inte använder dem. Detta hjälper dem att fungera bättre men batteritiden kan påverkas."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarmet är aktiverat"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kameran och mikrofonen är avstängda"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# avisering}other{# aviseringar}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sänder"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vill du sluta sända från <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Om en utsändning från <xliff:g id="SWITCHAPP">%1$s</xliff:g> pågår eller om du byter ljudutgång avbryts den nuvarande utsändningen"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Sänd från <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Byt ljudutgång"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Okänt"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
index 410a6bc..9e69b00 100644
--- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Av"</item>
     <item msgid="460891964396502657">"På"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Inte tillgängligt"</item>
+    <item msgid="8014986104355098744">"Av"</item>
+    <item msgid="5966994759929723339">"På"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 385f535..6c8e02f 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Kipengele cha kuzima vitambuzi kimewashwa"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Futa arifa zote."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Kuna arifa <xliff:g id="NUMBER_1">%s</xliff:g> zaidi katika kikundi.</item>
-      <item quantity="one">Kuna arifa <xliff:g id="NUMBER_0">%s</xliff:g> zaidi katika kikundi.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Kuna arifa # zaidi ndani ya kikundi.}other{Kuna arifa # zaidi ndani ya kikundi.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Skrini imefungwa sasa katika uelekezo wa mandhari."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Skrini imefungwa katika uelekeo wa picha."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Sanduku la Vitindamlo"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Zungusha kiotomatiki"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Skrini ijizungushe kiotomatiki"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Mahali"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Taswira ya skrini"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Ufikiaji wa kamera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Ufikiaji wa maikrofoni"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Unapatikana"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Mtandaopepe"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Inawasha..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Kiokoa Data kimewashwa"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">Vifaa %d</item>
-      <item quantity="one">Kifaa %d</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{Kifaa #}other{Vifaa #}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Tochi"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera inatumika"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Data ya simu"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Je, unataka kuendelea na kipindi chako?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Anza upya"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ndiyo, endelea"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Matumizi ya wageni"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Unatumia hali ya wageni"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Kuongeza mtumiaji mpya kutaondoa matumizi ya wageni yaliyopo na kufuta programu na data kutoka kwenye kipindi cha mgeni cha sasa."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Umefikia kima cha juu cha watumiaji"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Unaruhusiwa kuongeza hadi watumiaji <xliff:g id="COUNT">%d</xliff:g>.</item>
-      <item quantity="one">Unaruhusiwa kuongeza mtumiaji mmoja pekee.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Unaweza kuweka mtumiaji mmoja pekee.}other{Unaweza kuweka hadi watumiaji #.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Je, ungependa kuondoa mtumiaji?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Programu na data yote ya mtumiaji huyu itafutwa."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Ondoa"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Nikumbushe"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Tendua"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Imeahirishwa kwa <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">Saa %d</item>
-      <item quantity="one">Saa %d</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">Dakika %d</item>
-      <item quantity="one">Dakika %d</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{Saa #}=2{Saa #}other{Saa #}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{Dakika #}other{Dakika #}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Kiokoa Betri"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Arifa"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Betri"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Picha za skrini"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Ujumbe wa Jumla"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Programu zinazofunguka papo hapo"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Weka mipangilio"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Hifadhi"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Vidokezo"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Programu Zinazofunguka Papo Hapo"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"geuza"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Vidhibiti vya vifaa"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Chagua programu ili uweke vidhibiti"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">Umeweka vidhibiti <xliff:g id="NUMBER_1">%s</xliff:g>.</item>
-      <item quantity="one">Umeweka kidhibiti <xliff:g id="NUMBER_0">%s</xliff:g>.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Umeweka kidhibiti #.}other{Umeweka vidhibiti #.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Kimeondolewa"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Kimewekwa kwenye vipendwa"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kimewekwa kwenye vipendwa, nafasi ya <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Kiongeze"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Kisiongezwe"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Chagua mtumiaji"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other">Programu <xliff:g id="COUNT_1">%s</xliff:g> zinatumika</item>
-      <item quantity="one">Programu <xliff:g id="COUNT_0">%s</xliff:g> inatumika</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{Programu # inatumika}other{Programu # zinatumika}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Maelezo mapya"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Programu zinazotumika"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Programu hizi zinaendelea kufanya kazi, hata wakati huzitumii. Hali hii huboresha utendaji wa programu hizo, lakini pia inaweza kuathiri muda wa matumizi ya betri."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Kengele imewekwa"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera na maikrofoni zimezimwa"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Arifa #}other{Arifa #}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Inaarifu"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ungependa kusimamisha utangazaji kwenye <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ikiwa unatangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g> au unabadilisha maudhui, tangazo lako la sasa litasimamishwa"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Tangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Badilisha maudhui"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Haijulikani"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index 79d29ab..2f765ef 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Imezimwa"</item>
     <item msgid="460891964396502657">"Imewashwa"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Haipatikani"</item>
+    <item msgid="8014986104355098744">"Imezimwa"</item>
+    <item msgid="5966994759929723339">"Imewashwa"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 6c42073..d638c9d 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -47,6 +47,8 @@
 
     <dimen name="lockscreen_shade_max_over_scroll_amount">32dp</dimen>
 
+    <dimen name="status_view_margin_horizontal">8dp</dimen>
+
     <!-- Distance that the full shade transition takes in order to complete by tapping on a button
          like "expand". -->
     <dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
diff --git a/packages/SystemUI/res/values-sw600dp-port/dimens.xml b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
index 589d12f..347cf29 100644
--- a/packages/SystemUI/res/values-sw600dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
@@ -21,5 +21,10 @@
     <dimen name="keyguard_status_view_bottom_margin">40dp</dimen>
     <dimen name="bouncer_user_switcher_y_trans">20dp</dimen>
 
+    <!-- qs_tiles_page_horizontal_margin should be margin / 2, otherwise full space between two
+         pages is margin * 2, and that makes tiles page not appear immediately after user swipes to
+         the side -->
+    <dimen name="qs_tiles_page_horizontal_margin">32dp</dimen>
+
     <dimen name="qqs_layout_padding_bottom">16dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index f45f106d..868c003 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -25,6 +25,8 @@
 
     <dimen name="status_bar_header_height_keyguard">56dp</dimen>
 
+    <dimen name="status_view_margin_horizontal">24dp</dimen>
+
     <dimen name="qs_media_session_height_expanded">251dp</dimen>
     <dimen name="qs_content_horizontal_padding">40dp</dimen>
     <dimen name="qs_horizontal_margin">40dp</dimen>
diff --git a/packages/SystemUI/res/values-sw720dp-port/dimens.xml b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
index 2abc9e3..a0bf072 100644
--- a/packages/SystemUI/res/values-sw720dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
@@ -25,9 +25,16 @@
     <dimen name="keyguard_status_view_bottom_margin">80dp</dimen>
     <dimen name="bouncer_user_switcher_y_trans">90dp</dimen>
 
+    <dimen name="large_screen_shade_header_left_padding">24dp</dimen>
     <dimen name="qqs_layout_padding_bottom">40dp</dimen>
 
     <dimen name="notification_panel_margin_horizontal">80dp</dimen>
     <dimen name="notification_side_paddings">40dp</dimen>
+
+    <!-- qs_tiles_page_horizontal_margin should be margin / 2, otherwise full space between two
+     pages is margin * 2, and that makes tiles page not appear immediately after user swipes to the
+     side -->
+    <dimen name="qs_tiles_page_horizontal_margin">60dp</dimen>
+
     <dimen name="notification_section_divider_height">16dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 934800e..36767ea 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"’சென்சார்கள் ஆஃப்’ செயலில் உள்ளது"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"எல்லா அறிவிப்புகளையும் அழி."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">உள்ளே மேலும் <xliff:g id="NUMBER_1">%s</xliff:g> அறிவிப்புகள் உள்ளன.</item>
-      <item quantity="one">உள்ளே மேலும் <xliff:g id="NUMBER_0">%s</xliff:g> அறிவிப்பு உள்ளது.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{குழுவில் மேலும் # அறிவிப்பு உள்ளது.}other{குழுவில் மேலும் # அறிவிப்புகள் உள்ளன.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"நிலத்தோற்ற திசையமைப்பில் திரைப் பூட்டப்பட்டுள்ளது."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"உருவப்பட திசையமைப்பில் திசை பூட்டப்பட்டுள்ளது."</string>
     <string name="dessert_case" msgid="9104973640704357717">"இனிப்பு வடிவங்கள்"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"தானாகச் சுழற்று"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"திரையைத் தானாகச் சுழற்று"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"இருப்பிடம்"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"ஸ்கிரீன் சேவர்"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"கேமரா அணுகல்"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"மைக் அணுகல்"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"கிடைக்கிறது"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ஹாட்ஸ்பாட்"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ஆன் செய்கிறது…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"டேட்டா சேவர்: ஆன்"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d சாதனங்கள்</item>
-      <item quantity="one">%d சாதனம்</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# சாதனம்}other{# சாதனங்கள்}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"டார்ச் லைட்"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"கேமரா உபயோகத்திலுள்ளது"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"மொபைல் டேட்டா"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"உங்கள் அமர்வைத் தொடர விருப்பமா?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"மீண்டும் தொடங்கு"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"தொடரவும்"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"கெஸ்ட் பயன்முறை"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"கெஸ்ட் பயன்முறையில் உள்ளீர்கள்"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"புதிய பயனரைச் சேர்த்தால் கெஸ்ட் பயன்முறையில் இருந்து வெளியேற்றப்படுவீர்கள். மேலும் தற்போதைய கெஸ்ட் அமர்வின் ஆப்ஸ் மற்றும் தரவு அனைத்தும் நீக்கப்படும்."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"பயனர் வரம்பை அடைந்துவிட்டீர்கள்"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> பயனர்கள் வரை சேர்க்க முடியும்.</item>
-      <item quantity="one">ஒரு பயனரை மட்டுமே சேர்க்க முடியும்.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{ஒரு பயனரை மட்டுமே சேர்க்க முடியும்.}other{# பயனர்கள் வரை சேர்க்கலாம்.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"பயனரை அகற்றவா?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"இந்தப் பயனரின் எல்லா பயன்பாடுகளும் தரவும் நீக்கப்படும்."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"அகற்று"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"எனக்கு நினைவூட்டு"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"செயல்தவிர்"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"உறக்கநிலையில் வைத்திருந்த நேரம்: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d மணிநேரம்</item>
-      <item quantity="one">%d மணிநேரம்</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d நிமிடங்கள்</item>
-      <item quantity="one">%d நிமிடம்</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# மணிநேரம்}=2{# மணிநேரம்}other{# மணிநேரம்}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# நிமிடம்}other{# நிமிடங்கள்}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"பேட்டரி சேமிப்பு"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"விழிப்பூட்டல்கள்"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"பேட்டரி"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"ஸ்கிரீன் ஷாட்டுகள்"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"பொதுச் செய்திகள்"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"இன்ஸ்டண்ட் ஆப்ஸ்"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"அமைவு"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"சேமிப்பிடம்"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"குறிப்புகள்"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"நிலைமாற்று"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"சாதனக் கட்டுப்பாடுகள்"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"கட்டுப்பாடுகளைச் சேர்க்க வேண்டிய ஆப்ஸைத் தேர்ந்தெடுங்கள்"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> கட்டுப்பாடுகள் சேர்க்கப்பட்டன.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> கட்டுப்பாடு சேர்க்கப்பட்டது.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# கட்டுப்பாடு சேர்க்கப்பட்டது.}other{# கட்டுப்பாடுகள் சேர்க்கப்பட்டன.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"அகற்றப்பட்டது"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"பிடித்தவற்றில் சேர்க்கப்பட்டது"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"பிடித்தவற்றில் சேர்க்கப்பட்டது, நிலை <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"கட்டத்தைச் சேர்"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"கட்டத்தை சேர்க்காதே"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"பயனரைத் தேர்வுசெய்க"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ஆப்ஸ் செயலிலுள்ளன</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ஆப்ஸ் செயலிலுள்ளது</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ஆப்ஸ் செயலிலுள்ளது}other{# ஆப்ஸ் செயலிலுள்ளன}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"புதிய தகவல்கள்"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"செயலிலுள்ள ஆப்ஸ்"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"இந்த ஆப்ஸை நீங்கள் பயன்படுத்தாதபோதும் அவை செயலில் இருப்பதோடு இயங்கிக் கொண்டிருக்கும். இது அவற்றின் செயல்பாட்டை மேம்படுத்தும். ஆனால், அதே சமயம் பேட்டரி ஆயுளைக் குறைக்கக்கூடும்."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"அலாரம் அமைக்கப்பட்டுள்ளது"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"கேமராவும் மைக்கும் ஆஃப் செய்யப்பட்டுள்ளன"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# அறிவிப்பு}other{# அறிவிப்புகள்}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ஒலிபரப்புதல்"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் ஒலிபரப்பப்படுவதை நிறுத்தவா?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"நீங்கள் <xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பினாலோ அவுட்புட்டை மாற்றினாலோ உங்களின் தற்போதைய ஒலிபரப்பு நிறுத்தப்படும்"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பு"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"அவுட்புட்டை மாற்று"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"தெரியவில்லை"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
index 52fca12..41f6412 100644
--- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"முடக்கப்பட்டுள்ளது"</item>
     <item msgid="460891964396502657">"இயக்கப்பட்டுள்ளது"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"கிடைக்கவில்லை"</item>
+    <item msgid="8014986104355098744">"முடக்கப்பட்டுள்ளது"</item>
+    <item msgid="5966994759929723339">"இயக்கப்பட்டுள்ளது"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 49a8562..4d124f5 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"సెన్సార్‌లు ఆఫ్ యాక్టివ్‌లో ఉంది"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"అన్ని నోటిఫికేషన్‌లను క్లియర్ చేయండి."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">లోపల మరో <xliff:g id="NUMBER_1">%s</xliff:g> నోటిఫికేషన్‌లు ఉన్నాయి.</item>
-      <item quantity="one">లోపల మరో <xliff:g id="NUMBER_0">%s</xliff:g> నోటిఫికేషన్ ఉంది.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{లోపల మరో # నోటిఫికేషన్ ఉంది.}other{లోపల మరో # నోటిఫికేషన్‌లు ఉన్నాయి.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"స్క్రీన్ ల్యాండ్‌స్కేప్ దృగ్విన్యాసంలో లాక్ చేయబడుతుంది."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"స్క్రీన్ పోర్ట్రెయిట్ దృగ్విన్యాసంలో లాక్ చేయబడుతుంది."</string>
     <string name="dessert_case" msgid="9104973640704357717">"డెజర్ట్ కేస్"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ఆటో-రొటేట్‌"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"స్క్రీన్ ఆటో-రొటేట్‌"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"లొకేషన్"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"స్క్రీన్ సేవర్"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"కెమెరా యాక్సెస్"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"మైక్ యాక్సెస్"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"అందుబాటులో ఉంది"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"హాట్‌స్పాట్"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"ఆన్ చేస్తోంది…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"డేటా సేవర్ ఆన్‌లో ఉంది"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d పరికరాలు</item>
-      <item quantity="one">%d పరికరం</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# పరికరం}other{# పరికరాలు}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ఫ్లాష్‌లైట్"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"కెమెరా ఉపయోగంలో ఉంది"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"మొబైల్ డేటా"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"మీరు మీ సెషన్‌ని కొనసాగించాలనుకుంటున్నారా?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"మొదటి నుండి ప్రారంభించు"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"అవును, కొనసాగించు"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"గెస్ట్ మోడ్"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"మీరు గెస్ట్ మోడ్‌లో ఉన్నారు"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"కొత్త యూజర్‌ను జోడించడం వలన గెస్ట్ మోడ్ నుండి వైదొలుగుతుంది. అలాగే ప్రస్తుత గెస్ట్ సెషన్ నుండి అన్ని యాప్‌లతో పాటు మొత్తం డేటా తొలగించబడుతుంది."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"వినియోగదారు పరిమితిని చేరుకున్నారు"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">మీరు <xliff:g id="COUNT">%d</xliff:g> వినియోగదారుల వరకు జోడించవచ్చు.</item>
-      <item quantity="one">ఒక్క వినియోగదారుని మాత్రమే సృష్టించవచ్చు.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{ఒక యూజర్‌ను మాత్రమే క్రియేట్ చేయవచ్చు.}other{మీరు గరిష్టంగా # మంది యూజర్‌లను జోడించవచ్చు.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"వినియోగదారుని తీసివేయాలా?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"ఈ వినియోగదారుకు సంబంధించిన అన్ని యాప్‌లు మరియు డేటా తొలగించబడతాయి."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"తీసివేయి"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"నాకు గుర్తు చేయి"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"చర్య రద్దు చేయండి"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> వరకు తాత్కాలికంగా ఆపివేయబడింది"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d గంటలు</item>
-      <item quantity="one">%d గంట</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d నిమిషాలు</item>
-      <item quantity="one">%d నిమిషం</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# గంట}=2{# గంటలు}other{# గంటలు}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# నిమిషం}other{# నిమిషాలు}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"బ్యాటరీ సేవర్"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"అలర్ట్‌లు"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"బ్యాటరీ"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"స్క్రీన్‌షాట్‌లు"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"సాధారణ మెసేజ్‌లు"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"ఇన్‌స్టంట్ యాప్‌లు"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"సెటప్ చేయండి"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"స్టోరేజ్"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"సూచనలు"</string>
     <string name="instant_apps" msgid="8337185853050247304">"ఇన్‌స్టంట్ యాప్‌లు"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"టోగుల్ చేయి"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"డివైజ్ కంట్రోల్స్"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"కంట్రోల్స్‌ను యాడ్ చేయడానికి యాప్‌ను ఎంచుకోండి"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> కంట్రోల్‌లు యాడ్ అయ్యాయి.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> కంట్రోల్ యాడ్ అయింది.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# కంట్రోల్ జోడించబడింది.}other{# కంట్రోల్స్ జోడించబడ్డాయి.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"తీసివేయబడింది"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>వ స్థానంలో ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"టైల్‌ను జోడించండి"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"టైల్‌ను జోడించవద్దు"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"యూజర్‌ను ఎంచుకోండి"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> యాప్‌లు యాక్టివ్‌గా ఉన్నాయి</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> యాప్ యాక్టివ్‌గా ఉంది</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# యాప్ యాక్టివ్‌గా ఉంది}other{# యాప్‌లు యాక్టివ్‌గా ఉన్నాయి}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"కొత్త సమాచారం"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"యాక్టివ్‌గా ఉన్న యాప్‌లు"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"మీరు వాటిని ఉపయోగించనప్పటికీ, ఈ యాప్‌లు యాక్టివ్‌గా ఉంటాయి, రన్ అవుతాయి. ఇది వారి ఫంక్షనాలిటీని మెరుగుపరుస్తుంది, అయితే ఇది బ్యాటరీ జీవితకాలాన్ని కూడా ప్రభావితం చేయవచ్చు."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"అలారం సెట్ చేశాను"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"కెమెరా, మైక్ ఆఫ్‌లో ఉన్నాయి"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# నోటిఫికేషన్}other{# నోటిఫికేషన్‌లు}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ప్రసారం చేస్తోంది"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రసారం చేయడాన్ని ఆపివేయాలా?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"మీరు <xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేస్తే లేదా అవుట్‌పుట్‌ను మార్చినట్లయితే, మీ ప్రస్తుత ప్రసారం ఆగిపోతుంది"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేయండి"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"అవుట్‌పుట్‌ను మార్చండి"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"తెలియదు"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml
index 6099792..44ba477 100644
--- a/packages/SystemUI/res/values-te/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"ఆఫ్"</item>
     <item msgid="460891964396502657">"ఆన్"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"అందుబాటులో లేరు"</item>
+    <item msgid="8014986104355098744">"ఆఫ్"</item>
+    <item msgid="5966994759929723339">"ఆన్"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 2d003db..8daf4b5 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"\"ปิดเซ็นเซอร์\" เปิดใช้งานอยู่"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"ล้างการแจ้งเตือนทั้งหมด"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">มีการแจ้งเตือนอีก <xliff:g id="NUMBER_1">%s</xliff:g> รายการด้านใน</item>
-      <item quantity="one">มีการแจ้งเตือนอีก <xliff:g id="NUMBER_0">%s</xliff:g> รายการด้านใน</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{มีการแจ้งเตือนอีก # รายการด้านใน}other{มีการแจ้งเตือนอีก # รายการด้านใน}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"ขณะนี้หน้าจอถูกล็อกให้วางในแนวนอน"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"ขณะนี้หน้าจอถูกล็อกให้วางในแนวตั้ง"</string>
     <string name="dessert_case" msgid="9104973640704357717">"ชั้นแสดงของหวาน"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"หมุนอัตโนมัติ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"หมุนหน้าจออัตโนมัติ"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"ตำแหน่ง"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"โปรแกรมรักษาหน้าจอ"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"สิทธิ์เข้าถึงกล้อง"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"สิทธิ์เข้าถึงไมโครโฟน"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"พร้อมให้ใช้งาน"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ฮอตสปอต"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"กำลังเปิด..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"เปิดการประหยัดเน็ตอยู่"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">อุปกรณ์ %d เครื่อง</item>
-      <item quantity="one">อุปกรณ์ %d เครื่อง</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{อุปกรณ์ # เครื่อง}other{อุปกรณ์ # เครื่อง}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"ไฟฉาย"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"ใช้กล้องอยู่"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"เน็ตมือถือ"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"คุณต้องการอยู่ในเซสชันต่อไปไหม"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"เริ่มต้นใหม่"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ใช่ ดำเนินการต่อ"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"โหมดผู้ใช้ชั่วคราว"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"คุณอยู่ในโหมดผู้ใช้ชั่วคราว"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"การเพิ่มผู้ใช้ใหม่จะเป็นการออกจากโหมดผู้ใช้ชั่วคราว และจะลบแอปและข้อมูลทั้งหมดจากเซสชันผู้ใช้ชั่วคราวในปัจจุบัน"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ถึงขีดจำกัดผู้ใช้แล้ว"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">คุณเพิ่มผู้ใช้ได้สูงสุด <xliff:g id="COUNT">%d</xliff:g> คน</item>
-      <item quantity="one">สร้างผู้ใช้ได้เพียง 1 คนเท่านั้น</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{สร้างผู้ใช้ได้เพียง 1 คนเท่านั้น}other{คุณเพิ่มผู้ใช้ได้สูงสุด # คน}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"นำผู้ใช้ออกใช่ไหม"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"แอปและข้อมูลทั้งหมดของผู้ใช้นี้จะถูกลบ"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"นำออก"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"เตือนฉัน"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"เลิกทำ"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"ปิดเสียงเตือนชั่วคราวไว้เป็นเวลา <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d ชั่วโมง</item>
-      <item quantity="one">%d ชั่วโมง</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d นาที</item>
-      <item quantity="one">%d นาที</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# ชั่วโมง}=2{# ชั่วโมง}other{# ชั่วโมง}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# นาที}other{# นาที}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"โหมดประหยัดแบตเตอรี่"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"การแจ้งเตือน"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"แบตเตอรี"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"ภาพหน้าจอ"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"ข้อความทั่วไป"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"ตั้งค่า"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"พื้นที่เก็บข้อมูล"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"คำแนะนำ"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant App"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"สลับ"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"ระบบควบคุมอุปกรณ์"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"เลือกแอปเพื่อเพิ่มตัวควบคุม"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">เพิ่มตัวควบคุม <xliff:g id="NUMBER_1">%s</xliff:g> ตัวแล้ว</item>
-      <item quantity="one">เพิ่มตัวควบคุม <xliff:g id="NUMBER_0">%s</xliff:g> ตัวแล้ว</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{เพิ่มตัวควบคุม # ตัวแล้ว}other{เพิ่มตัวควบคุม # ตัวแล้ว}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"นำออกแล้ว"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ตั้งเป็นรายการโปรดแล้ว"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ตั้งเป็นรายการโปรดแล้ว โดยอยู่ลำดับที่ <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -928,15 +915,12 @@
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"เพื่อปรับปรุงประสบการณ์การใช้อุปกรณ์ แอปและบริการต่างๆ จะยังคงสแกนหาเครือข่าย Wi‑Fi ได้ทุกเมื่อแม้ว่า Wi‑Fi จะปิดอยู่ คุณเปลี่ยนตัวเลือกนี้ได้ในการตั้งค่าการสแกนหา Wi-Fi "<annotation id="link">"เปลี่ยนการตั้งค่า"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"ปิดโหมดบนเครื่องบิน"</string>
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> ต้องการเพิ่มองค์ประกอบต่อไปนี้ในการตั้งค่าด่วน"</string>
-    <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"เพิ่มองค์ประกอบ"</string>
-    <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ไม่เพิ่มองค์ประกอบ"</string>
+    <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"เพิ่มชิ้นส่วน"</string>
+    <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ไม่ต้องเพิ่มชิ้นส่วน"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"เลือกผู้ใช้"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other">ทำงานอยู่ <xliff:g id="COUNT_1">%s</xliff:g> แอป</item>
-      <item quantity="one">ทำงานอยู่ <xliff:g id="COUNT_0">%s</xliff:g> แอป</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{ทำงานอยู่ # แอป}other{ทำงานอยู่ # แอป}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"ข้อมูลใหม่"</string>
-    <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ทำงานอยู่"</string>
+    <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"แอปที่ใช้งานอยู่"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"แอปเหล่านี้กำลังทำงานแม้ว่าคุณจะไม่ได้ใช้งานอยู่ก็ตาม วิธีนี้ช่วยให้ฟังก์ชันการทำงานของแอปมีประสิทธิภาพมากขึ้น แต่ก็อาจส่งผลต่ออายุการใช้งานแบตเตอรี่ด้วย"</string>
     <string name="fgs_manager_app_item_stop_button_label" msgid="7188317969020801156">"หยุด"</string>
     <string name="fgs_manager_app_item_stop_button_stopped_label" msgid="6950382004441263922">"หยุดแล้ว"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ตั้งปลุกแล้ว"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"กล้องและไมค์ปิดอยู่"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{การแจ้งเตือน # รายการ}other{การแจ้งเตือน # รายการ}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"กำลังออกอากาศ"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"หยุดการออกอากาศ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"หากคุณออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g> หรือเปลี่ยนแปลงเอาต์พุต การออกอากาศในปัจจุบันจะหยุดลง"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"ออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"เปลี่ยนเอาต์พุต"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"ไม่ทราบ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml
index 4565f35..9cd060f 100644
--- a/packages/SystemUI/res/values-th/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"ปิด"</item>
     <item msgid="460891964396502657">"เปิด"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"ไม่พร้อมใช้งาน"</item>
+    <item msgid="8014986104355098744">"ปิด"</item>
+    <item msgid="5966994759929723339">"เปิด"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 5e2fb53..e8c191b 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Aktibo ang i-off ang mga sensor"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"I-clear ang lahat ng notification."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">May <xliff:g id="NUMBER_1">%s</xliff:g> pang notification sa loob.</item>
-      <item quantity="other">May <xliff:g id="NUMBER_1">%s</xliff:g> pang notification sa loob.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{May # pang notification sa loob.}one{May # pang notification sa loob.}other{May # pang notification sa loob.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Naka-lock ang screen sa pahigang oryentasyon."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Naka-lock ang screen sa patayong oryentasyon."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"I-auto rotate"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Awtomatikong i-rotate ang screen"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokasyon"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Screen saver"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Access sa camera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Access sa mic"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Available"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Ino-on…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Na-on ang Data Saver"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d device</item>
-      <item quantity="other">%d na device</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# device}one{# device}other{# na device}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Flashlight"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Ginagamit na camera"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobile data"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Gusto mo bang ipagpatuloy ang iyong session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Magsimulang muli"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oo, magpatuloy"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Naka-guest mode ka"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Kapag nagdagdag ka ng bagong user, aalis sa guest mode at made-delete ang lahat ng app at data mula sa kasalukuyang session ng bisita."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Naabot na ang limitasyon sa user"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Maaari kang magdagdag ng hanggang <xliff:g id="COUNT">%d</xliff:g> user.</item>
-      <item quantity="other">Maaari kang magdagdag ng hanggang <xliff:g id="COUNT">%d</xliff:g> na user.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Isang user lang ang puwedeng gawin.}one{Puwede kang magdagdag ng hanggang # user.}other{Puwede kang magdagdag ng hanggang # na user.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Gusto mo bang alisin ang user?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Made-delete ang lahat ng app at data ng user na ito."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Alisin"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Paalalahanan ako"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"I-undo"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Na-snooze ng <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d oras</item>
-      <item quantity="other">%d na oras</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d minuto</item>
-      <item quantity="other">%d na minuto</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# oras}=2{# oras}one{# oras}other{# na oras}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minuto}one{# minuto}other{# na minuto}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Pantipid ng Baterya"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Mga Alerto"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Baterya"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Mga Screenshot"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Mga Pangkalahatang Mensahe"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Setup"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Storage"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Mga Hint"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Instant Apps"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"i-toggle"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Mga kontrol ng device"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Pumili ng app para magdagdag ng mga kontrol"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> kontrol ang naidagdag.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> na kontrol ang naidagdag.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Nagdagdag ng # kontrol.}one{Nagdagdag ng # kontrol.}other{Nagdagdag ng # na kontrol.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Inalis"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ginawang paborito"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ginawang paborito, posisyon <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Idagdag ang tile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Huwag idagdag"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Pumili ng user"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> app ang aktibo</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> na app ang aktibo</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{Aktibo ang # app}one{Aktibo ang # app}other{Aktibo ang # na app}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Bagong impormasyon"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Mga aktibong app"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Aktibo at tumatakbo ang mga app na ito kahit na hindi mo ginagamit. Pinapahusay nito ang functionality ng mga app, pero posible rin itong makaapekto sa tagal ng baterya."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Nakatakda ang alarm"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Naka-off ang camera at mikropono"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# na notification}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Nagbo-broadcast"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ihinto ang pag-broadcast ng <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kung magbo-broadcast ka ng <xliff:g id="SWITCHAPP">%1$s</xliff:g> o babaguhin mo ang output, hihinto ang iyong kasalukuyang broadcast"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"I-broadcast ang <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Baguhin ang output"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Hindi alam"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
index 59fed0f..cd7dcf5 100644
--- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Naka-off"</item>
     <item msgid="460891964396502657">"Naka-on"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Hindi available"</item>
+    <item msgid="8014986104355098744">"Naka-off"</item>
+    <item msgid="5966994759929723339">"Naka-on"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index b52d41d..adb3fb4 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensörler kapalı ayarı etkin"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Tüm bildirimleri temizle"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Grup içinde <xliff:g id="NUMBER_1">%s</xliff:g> bildirim daha var.</item>
-      <item quantity="one">Grup içinde <xliff:g id="NUMBER_0">%s</xliff:g> bildirim daha var.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Grup içinde # bildirim daha var.}other{Grup içinde # bildirim daha var.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekran yatay yönde kilitlendi."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekran dikey yönde kilitlendi."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Tatlı Kutusu"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Otomatik döndür"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranı otomatik döndür"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Konum"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Ekran koruyucu"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kamera erişimi"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofon erişimi"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Kullanılabilir"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Açılıyor…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Veri Tasarrufu açık"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d cihaz</item>
-      <item quantity="one">%d cihaz</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# cihaz}other{# cihaz}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Fener"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera kullanımda"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobil veri"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Oturumunuza devam etmek istiyor musunuz?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Baştan başla"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Evet, devam et"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Misafir modu"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Misafir modundasınız"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Yeni bir kullanıcı eklendiğinde misafir modundan çıkılarak mevcut misafir oturumundaki tüm uygulamalar ve veriler silinir."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Kullanıcı sınırına ulaşıldı"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">En fazla <xliff:g id="COUNT">%d</xliff:g> kullanıcı ekleyebilirsiniz.</item>
-      <item quantity="one">Yalnızca bir kullanıcı oluşturulabilir.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Yalnızca bir kullanıcı oluşturulabilir.}other{En çok # kullanıcı ekleyebilirsiniz.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Kullanıcı kaldırılsın mı?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Bu kullanıcının tüm uygulamaları ve verileri silinecek."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Kaldır"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Bana hatırlat"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Geri al"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> süreyle ertelendi"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d saat</item>
-      <item quantity="one">%d saat</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d dakika</item>
-      <item quantity="one">%d dakika</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# saat}=2{# saat}other{# saat}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# dakika}other{# dakika}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Pil Tasarrufu"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Uyarılar"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Pil"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Ekran görüntüleri"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Genel Mesajlar"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Hazır Uygulamalar"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Kurulum"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Depolama alanı"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"İpuçları"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Hazır Uygulamalar"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"değiştir"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Cihaz denetimleri"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Denetim eklemek için uygulama seçin"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontrol eklendi.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontrol eklendi.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol eklendi.}other{# kontrol eklendi.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Kaldırıldı"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoriler listesine eklendi"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorilere eklendi, konum: <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Kart ekle"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Kart ekleme"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Kullanıcı seçin"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> uygulama etkin</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> uygulama etkin</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# uygulama etkin}other{# uygulama etkin}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Yeni bilgi"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Etkin uygulamalar"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Bu uygulamalar, kullanmadığınız zamanlarda bile etkin ve çalışır durumdadır. Bu durum daha iyi çalışmalarını sağlar ancak pil ömrünü de olumsuz etkileyebilir."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Alarm kuruldu"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ve mikrofon kapalı"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildirim}other{# bildirim}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayınlama"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında anons durdurulsun mu?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapar veya çıkışı değiştirirseniz mevcut anonsunuz duraklatılır"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapın"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Çıkışı değiştirme"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Bilinmiyor"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
index d06d727..28ba7dcb 100644
--- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Kapalı"</item>
     <item msgid="460891964396502657">"Açık"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Kullanılamıyor"</item>
+    <item msgid="8014986104355098744">"Kapalı"</item>
+    <item msgid="5966994759929723339">"Açık"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 51c61ce..66fb209 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -205,12 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Активовано вимкнення датчиків"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Очистити всі сповіщення."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one">Ще <xliff:g id="NUMBER_1">%s</xliff:g> сповіщення в групі.</item>
-      <item quantity="few">Ще <xliff:g id="NUMBER_1">%s</xliff:g> сповіщення в групі.</item>
-      <item quantity="many">Ще <xliff:g id="NUMBER_1">%s</xliff:g> сповіщень у групі.</item>
-      <item quantity="other">Ще <xliff:g id="NUMBER_1">%s</xliff:g> сповіщення в групі.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Ще # сповіщення в групі.}one{Ще # сповіщення в групі.}few{Ще # сповіщення в групі.}many{Ще # сповіщень у групі.}other{Ще # сповіщення в групі.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Екран заблоковано в альбомній орієнтації."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Екран заблоковано в книжковій орієнтації."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Вітрина десертів"</string>
@@ -228,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Автоматичне обертання"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично обертати екран"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Геодані"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Заставка"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ до камери"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Доступ до мікрофона"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Дозволено"</string>
@@ -257,12 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Точка доступу"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Увімкнення…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Заощадження трафіку ввімкнено"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d пристрій</item>
-      <item quantity="few">%d пристрої</item>
-      <item quantity="many">%d пристроїв</item>
-      <item quantity="other">%d пристрою</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# пристрій}one{# пристрій}few{# пристрої}many{# пристроїв}other{# пристрою}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Ліхтарик"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Використовується камера"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Мобільне передавання даних"</string>
@@ -355,13 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Продовжити сеанс?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почати знову"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Так, продовжити"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Режим гостя"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Ви ввійшли в режимі гостя"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Якщо додати нового користувача, ви вийдете з режиму гостя, а всі додатки й дані з поточного сеансу цього режиму буде видалено."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Ви досягли ліміту користувачів"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Можна додати до <xliff:g id="COUNT">%d</xliff:g> користувача.</item>
-      <item quantity="few">Можна додати до <xliff:g id="COUNT">%d</xliff:g> користувачів.</item>
-      <item quantity="many">Можна додати до <xliff:g id="COUNT">%d</xliff:g> користувачів.</item>
-      <item quantity="other">Можна додати до <xliff:g id="COUNT">%d</xliff:g> користувача.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Можна створити лише одного користувача.}one{Можна додати щонайбільше # користувача.}few{Можна додати щонайбільше # користувачів.}many{Можна додати щонайбільше # користувачів.}other{Можна додати щонайбільше # користувача.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Видалити користувача?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Усі додатки й дані цього користувача буде видалено."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Видалити"</string>
@@ -547,18 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Нагадати"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Відмінити"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Відкладено на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d година</item>
-      <item quantity="few">%d години</item>
-      <item quantity="many">%d годин</item>
-      <item quantity="other">%d години</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d хвилина</item>
-      <item quantity="few">%d хвилини</item>
-      <item quantity="many">%d хвилин</item>
-      <item quantity="other">%d хвилини</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# година}=2{# години}one{# година}few{# години}many{# годин}other{# години}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# хвилина}one{# хвилина}few{# хвилини}many{# хвилин}other{# хвилини}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Режим енергозбереження"</string>
     <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>
@@ -707,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Сповіщення"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Акумулятор"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Знімки екрана"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Загальні повідомлення"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Додатки з миттєвим запуском"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Налаштування"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Пам’ять"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Поради"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Додатки з миттєвим запуском"</string>
@@ -781,12 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"перемкнути"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Керування пристроями"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Виберіть, для якого додатка налаштувати елементи керування"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one">Додано <xliff:g id="NUMBER_1">%s</xliff:g> елемент керування.</item>
-      <item quantity="few">Додано <xliff:g id="NUMBER_1">%s</xliff:g> елементи керування.</item>
-      <item quantity="many">Додано <xliff:g id="NUMBER_1">%s</xliff:g> елементів керування.</item>
-      <item quantity="other">Додано <xliff:g id="NUMBER_1">%s</xliff:g> елемента керування.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Додано # елемент керування.}one{Додано # елемент керування.}few{Додано # елементи керування.}many{Додано # елементів керування.}other{Додано # елемента керування.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Вилучено"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Додано у вибране"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Додано у вибране, позиція <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -943,12 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Додати параметр"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Не додавати параметр"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Виберіть користувача"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one"><xliff:g id="COUNT_1">%s</xliff:g> додаток активний</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%s</xliff:g> додатки активні</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%s</xliff:g> додатків активні</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> додатка активні</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# додаток активний}one{# додаток активний}few{# додатки активні}many{# додатків активні}other{# додатка активні}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Нова інформація"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Активні додатки"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Навіть якщо ви не використовуєте ці додатки, вони залишаються активними й продовжують працювати. Це покращує їх функціональні можливості, але може впливати на час роботи акумулятора."</string>
@@ -977,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Будильник установлено"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камеру й мікрофон вимкнено"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# сповіщення}one{# сповіщення}few{# сповіщення}many{# сповіщень}other{# сповіщення}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляція"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Зупинити трансляцію з додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Якщо ви зміните додаток (<xliff:g id="SWITCHAPP">%1$s</xliff:g>) або аудіовихід, поточну трансляцію буде припинено"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Змінити додаток для трансляції на <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Змінити аудіовихід"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Невідомо"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
index 040fb4d..3f6ca46 100644
--- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Вимкнено"</item>
     <item msgid="460891964396502657">"Увімкнено"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Недоступно"</item>
+    <item msgid="8014986104355098744">"Вимкнено"</item>
+    <item msgid="5966994759929723339">"Увімкнено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index d2abb7a..c40927e 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"سینسرز آف فعال ہے"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"سبھی اطلاعات صاف کریں۔"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"<xliff:g id="NUMBER">%s</xliff:g> +"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">اندر <xliff:g id="NUMBER_1">%s</xliff:g> مزید اطلاعات ہیں۔ </item>
-      <item quantity="one">اندر <xliff:g id="NUMBER_0">%s</xliff:g> مزید اطلاع ہے۔</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{گروپ میں # مزید اطلاع ہے۔}other{گروپ میں # مزید اطلاعات ہے۔}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"اسکرین لینڈ اسکیپ سمت بندی میں مقفل ہے۔"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"اسکرین پورٹریٹ سمت بندی میں مقفل ہے۔"</string>
     <string name="dessert_case" msgid="9104973640704357717">"ڈیزرٹ کیس"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"خود کار طور پر گھمائیں"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"اسکرین کو خود کار طور پر گھمائیں"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"مقام"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"اسکرین سیور"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"کیمرا تک رسائی"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"مائیکروفون تک رسائی"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"دستیاب ہے"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"ہاٹ اسپاٹ"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"آن ہو رہا ہے…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"ڈیٹا سیور آن ہے"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">‏%d آلات</item>
-      <item quantity="one">‏%d آلہ</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# آلہ}other{# آلات}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"فلیش لائٹ"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"کیمرا زیر استعمال ہے"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"موبائل ڈیٹا"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"کیا آپ اپنا سیشن جاری رکھنا چاہتے ہیں؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"دوبارہ شروع کریں"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ہاں، جاری رکھیں"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"مہمان وضع"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"آپ مہمان وضع میں ہیں"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"نئے صارف کو شامل کرنے سے مہمان وضع سے باہر نکل جائے گا اور موجودہ مہمان سیشن سے تمام ایپس اور ڈیٹا حذف ہو جائیں گے۔"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"صارف کی حد مکمل ہو گئی"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">صرف <xliff:g id="COUNT">%d</xliff:g> صارفین بنائے جا سکتے ہیں۔</item>
-      <item quantity="one">صرف ایک صارف بنایا جا سکتا ہے۔</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{صرف ایک صارف بنایا جا سکتا ہے۔}other{آپ # تک صارفین شامل کر سکتے ہیں۔}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"صارف کو ہٹائیں؟"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"اس صارف کی سبھی ایپس اور ڈیٹا حذف کر دیا جائے گا۔"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"ہٹائیں"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"مجھے یاد دلائیں"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"کالعدم کریں"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> کیلئے اسنوز کیا گیا"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">‏‎%d گھنٹے</item>
-      <item quantity="one">‏‎%d گھنٹہ</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">‏‎%d منٹ</item>
-      <item quantity="one">‏‎%d منٹ</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# گھنٹہ}=2{# گھنٹے}other{# گھنٹے}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# منٹ}other{# منٹ}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"بیٹری سیور"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"الرٹس"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"بیٹری"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"اسکرین شاٹس"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"عمومی پیغامات"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"فوری ایپس"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"سیٹ اپ"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"اسٹوریج"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"اشارات"</string>
     <string name="instant_apps" msgid="8337185853050247304">"فوری ایپس"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ٹوگل کریں"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"آلہ کے کنٹرولز"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"کنٹرولز شامل کرنے کے لیے ایپ منتخب کریں"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> کنٹرولز شامل کر دیے گئے۔</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> کنٹرول شامل کر دیا گیا۔</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنٹرول کو شامل کیا گیا۔}other{# کنٹرولز کو شامل کیا گیا۔}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ہٹا دیا گیا"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"پسند کردہ"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"پسند کردہ، پوزیشن <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ٹائل شامل کریں"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ٹائل شامل نہ کریں"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"صارف منتخب کریں"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ایپس فعال ہیں</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ایپ فعال ہے</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ایپ فعال ہے}other{# ایپس فعال ہیں}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"نئی معلومات"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"فعال ایپس"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"یہ ایپس فعال اور چل رہی ہوتی ہیں، تب بھی جب آپ انہیں استعمال نہ کر رہے ہوں۔ اس سے ان کی فعالیت بہتر ہو جاتی ہے لیکن اس سے بیٹری لائف بھی متاثر ہو سکتی ہے۔"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"الارم سیٹ ہوگیا"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"کیمرا اور مائیک آف ہیں"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اطلاع}other{# اطلاعات}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"نشریات"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> براڈکاسٹنگ روکیں؟"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر آپ <xliff:g id="SWITCHAPP">%1$s</xliff:g> براڈکاسٹ کرتے ہیں یا آؤٹ پٹ کو تبدیل کرتے ہیں تو آپ کا موجودہ براڈکاسٹ رک جائے گا"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> پر براڈکاسٹ کریں"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"آؤٹ پٹ تبدیل کریں"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"نامعلوم"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
index 79d2cf6..05aa4e9 100644
--- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"آف"</item>
     <item msgid="460891964396502657">"آن"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"غیر دستیاب"</item>
+    <item msgid="8014986104355098744">"آف"</item>
+    <item msgid="5966994759929723339">"آن"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 293677a..f9ad0b7 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensorlar nofaol ishlayapti"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Barcha eslatmalarni tozalash."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Guruhda yana <xliff:g id="NUMBER_1">%s</xliff:g> ta bildirishnoma.</item>
-      <item quantity="one">Guruhda yana <xliff:g id="NUMBER_0">%s</xliff:g> ta bildirishnoma.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{Ichida yana # ta bildirishnoma bor.}other{Ichida yana # ta bildirishnoma bor.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Ekran eniga holatida qulflandi."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Ekran bo‘yiga holatida qulflandi."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Avto-burilish"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Ekranning avtomatik burilishi"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Joylashuv"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Ekran lavhasi"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Kameraga ruxsat"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Mikrofonga ruxsat"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Mavjud"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Yoqilmoqda…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Trafik tejash yoniq"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d ta qurilma</item>
-      <item quantity="one">%d ta qurilma</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# ta qurilma}other{# ta qurilma}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Fonar"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Kamera ishlatilmoqda"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Mobil internet"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Seansni davom ettirmoqchimisiz?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Boshidan boshlansin"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ha, davom ettirilsin"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Mehmon rejimi"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Mehmon rejimidasiz"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Yangi foydalanuvchi kiritilsa, mehmon rejimi tark etiladi va joriy mehmon seansidagi barcha ilova va ularning maʼlumotlari tozalanadi."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limitga yetib keldi"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> tagacha foydalanuvchi qo‘shish mumkin.</item>
-      <item quantity="one">Faqat bitta foydalanuvchi yaratish mumkin.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Faqat bitta foydalanuvchi yaratish mumkin.}other{# tagacha foydalanuvchi kiritishingiz mumkin.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Foydalanuvchi olib tashlansinmi?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Ushbu foydalanuvchining barcha ilovalari va ma’lumotlari o‘chirib tashlanadi."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Olib tashlash"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Menga eslatilsin"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Qaytarish"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> muddatga kechiktirildi"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d soat</item>
-      <item quantity="one">%d soat</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d daqiqa</item>
-      <item quantity="one">%d daqiqa</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# soat}=2{# soat}other{# soat}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# daqiqa}other{# daqiqa}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Quvvat tejash"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Bildirishnomalar"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batareya"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skrinshotlar"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Umumiy xabarlar"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Darhol ochiladigan ilovalar"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Sozlash"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Xotira"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Maslahatlar"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Darhol ochiladigan ilovalar"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"oʻzgartirish"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Qurilmalarni boshqarish"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Boshqaruv elementlarini kiritish uchun ilovani tanlang"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ta nazorat kiritilgan.</item>
-      <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> ta nazorat kiritilgan.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ta boshqaruv elementi kiritildi.}other{# ta boshqaruv elementi kiritildi.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Olib tashlandi"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Saralanganlarga kiritilgan"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Saralanganlarga kiritilgan, <xliff:g id="NUMBER">%d</xliff:g>-joy"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tugma kiritish"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Tugma kiritilmasin"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Foydalanuvchini tanlang"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> ta ilova faol</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> ta ilova faol</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ta ilova faol}other{# ta ilova faol}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Yangi axborot"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Faol ilovalar"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Bu ilovalardan foydalanmasangiz ham ular faol va ishlamoqda. Bu ularning ishlashini yaxshilaydi, lekin batareya quvvatiga ham taʼsir qilishi mumkin."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Signal oʻrnatildi"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera va mikrofon yoqilmagan"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ta bildirishnoma}other{# ta bildirishnoma}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Signal uzatish"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga translatsiya toʻxtatilsinmi?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Agar <xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya qilsangiz yoki ovoz chiqishini oʻzgartirsangiz, joriy translatsiya toʻxtab qoladi"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Ovoz chiqishini oʻzgartirish"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Noaniq"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
index b687597..a84f769 100644
--- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Oʻchiq"</item>
     <item msgid="460891964396502657">"Yoniq"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Bandman"</item>
+    <item msgid="8014986104355098744">"Oʻchiq"</item>
+    <item msgid="5966994759929723339">"Yoniq"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index af4bf0f..7df4339 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Tùy chọn tắt cảm biến đang hoạt động"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Xóa tất cả thông báo."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">Còn <xliff:g id="NUMBER_1">%s</xliff:g> thông báo nữa bên trong.</item>
-      <item quantity="one">Còn <xliff:g id="NUMBER_0">%s</xliff:g> thông báo nữa bên trong.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# thông báo khác bên trong.}other{# thông báo khác bên trong.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Màn hình hiện bị khóa theo hướng ngang."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Màn hình hiện bị khóa theo hướng dọc."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Tủ trưng bày bánh ngọt"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Tự động xoay"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Tự động xoay màn hình"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Vị trí"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Trình bảo vệ màn hình"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Truy cập máy ảnh"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Truy cập micrô"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Được phép"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Điểm phát sóng"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Đang bật…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Trình tiết kiệm dữ liệu đang bật"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d thiết bị</item>
-      <item quantity="one">%d thiết bị</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# thiết bị}other{# thiết bị}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Đèn pin"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Máy ảnh đang được sử dụng"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Dữ liệu di động"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Bạn có muốn tiếp tục phiên của mình không?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Bắt đầu lại"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Có, tiếp tục"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Chế độ khách"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Bạn đang ở chế độ khách"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Khi thêm người dùng mới, chế độ khách sẽ bị thoát và mọi ứng dụng cũng như dữ liệu trong phiên khách hiện tại sẽ bị xoá."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Đã đạt đến giới hạn người dùng"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">Bạn có thể thêm tối đa <xliff:g id="COUNT">%d</xliff:g> người dùng.</item>
-      <item quantity="one">Chỉ có thể tạo một người dùng.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Bạn chỉ có thể tạo một người dùng.}other{Bạn có thể thêm tối đa # người dùng.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Xóa người dùng?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Tất cả các ứng dụng và dữ liệu của người dùng này sẽ bị xóa."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Xóa"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Nhắc tôi"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Hủy"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Báo lại sau <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d giờ</item>
-      <item quantity="one">%d giờ</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d phút</item>
-      <item quantity="one">%d phút</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# giờ}=2{# giờ}other{# giờ}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# phút}other{# phút}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Trình tiết kiệm pin"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Cảnh báo"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Pin"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Ảnh chụp màn hình"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Thông báo chung"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Ứng dụng tức thì"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Thiết lập"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Bộ nhớ"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Gợi ý"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Ứng dụng tức thì"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"bật/tắt"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Điều khiển thiết bị"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Chọn ứng dụng để thêm các tùy chọn điều khiển"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">Đã thêm <xliff:g id="NUMBER_1">%s</xliff:g> tùy chọn điều khiển.</item>
-      <item quantity="one">Đã thêm <xliff:g id="NUMBER_0">%s</xliff:g> tùy chọn điều khiển.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Đã thêm # chế độ điều khiển.}other{Đã thêm # chế độ điều khiển.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Đã xóa"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Được yêu thích"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Được yêu thích, vị trí số <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Thêm ô"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Không thêm ô"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Chọn người dùng"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other">Ứng dụng <xliff:g id="COUNT_1">%s</xliff:g> đang hoạt động</item>
-      <item quantity="one">Ứng dụng <xliff:g id="COUNT_0">%s</xliff:g> đang hoạt động</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{Ứng dụng # đang hoạt động}other{Ứng dụng # đang hoạt động}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Thông tin mới"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ứng dụng đang hoạt động"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Các ứng dụng này vẫn hoạt động và đang chạy ngay cả khi bạn không sử dụng chúng. Việc này giúp cải thiện các chức năng nhưng đồng thời cũng có thể ảnh hưởng đến thời lượng pin."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"Đã đặt chuông báo"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Máy ảnh và micrô đang tắt"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# thông báo}other{# thông báo}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Phát sóng"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Dừng phát <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nếu bạn phát <xliff:g id="SWITCHAPP">%1$s</xliff:g> hoặc thay đổi đầu ra, phiên truyền phát hiện tại sẽ dừng"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Phát <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Thay đổi đầu ra"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Không xác định"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
index 827c72a..482a32f 100644
--- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Đang tắt"</item>
     <item msgid="460891964396502657">"Đang bật"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Không có sẵn"</item>
+    <item msgid="8014986104355098744">"Tắt"</item>
+    <item msgid="5966994759929723339">"Đang bật"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 9724a2e..62b1bd8 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"传感器已关闭"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"清除所有通知。"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">此群组内还有 <xliff:g id="NUMBER_1">%s</xliff:g> 条通知。</item>
-      <item quantity="one">此群组内还有 <xliff:g id="NUMBER_0">%s</xliff:g> 条通知。</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{此群组内还有 # 条通知。}other{此群组内还有 # 条通知。}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"屏幕锁定为横屏模式。"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"屏幕锁定为纵向模式。"</string>
     <string name="dessert_case" msgid="9104973640704357717">"甜品盒"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自动旋转屏幕"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自动旋转屏幕"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"位置信息"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"屏保"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"摄像头使用权限"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"麦克风使用权限"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"已允许"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"热点"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"正在开启…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"流量节省程序已开启"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d 台设备</item>
-      <item quantity="one">%d 台设备</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# 部设备}other{# 部设备}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"手电筒"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"相机正在使用中"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"移动数据"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"要继续您的会话吗?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新开始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是,继续"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"访客模式"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"您当前处于访客模式"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"如果添加新用户,系统将退出访客模式并删除当前访客会话中的所有应用和数据。"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"已达到用户数上限"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">您最多可以添加 <xliff:g id="COUNT">%d</xliff:g> 位用户。</item>
-      <item quantity="one">您只能创建一位用户。</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{您只能创建一位用户。}other{您最多可添加 # 位用户。}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"是否移除用户?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"此用户的所有应用和数据均将被删除。"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"移除"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"提醒我"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"撤消"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"已延后 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d 小时</item>
-      <item quantity="one">%d 小时</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d 分钟</item>
-      <item quantity="one">%d 分钟</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# 小时}=2{# 小时}other{# 小时}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# 分钟}other{# 分钟}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"省电模式"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"提醒"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"电池"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"屏幕截图"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"常规消息"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"免安装应用"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"设置"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"存储空间"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"提示"</string>
     <string name="instant_apps" msgid="8337185853050247304">"免安装应用"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"开启/关闭"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"设备控制器"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"选择要添加控制器的应用"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">已添加 <xliff:g id="NUMBER_1">%s</xliff:g> 个控件。</item>
-      <item quantity="one">已添加 <xliff:g id="NUMBER_0">%s</xliff:g> 个控件。</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已添加 # 个控件。}other{已添加 # 个控件。}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"已移除"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"已收藏"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已收藏,位置:<xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"添加图块"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"不添加图块"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"选择用户"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> 个应用正在运行</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> 个应用正在运行</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# 个应用处于活动状态}other{# 个应用处于活动状态}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"新信息"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"已开启的应用"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"这些应用正在保持活跃运行状态,即使您没有在使用它们。这可以改进它们的功能,但可能会影响到电池续航时间。"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"闹钟已设置"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"摄像头和麦克风已关闭"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 条通知}other{# 条通知}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"正在广播"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止广播“<xliff:g id="APP_NAME">%1$s</xliff:g>”的内容吗?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容或更改输出来源,当前的广播就会停止"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"更改输出来源"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"未知"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index 3c62872..b476255 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"已关闭"</item>
     <item msgid="460891964396502657">"已开启"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"不可用"</item>
+    <item msgid="8014986104355098744">"关闭"</item>
+    <item msgid="5966994759929723339">"开启"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 468661f..2ac494a 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"已啟用「感應器關閉」"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"清除所有通知。"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">裡面還有 <xliff:g id="NUMBER_1">%s</xliff:g> 個通知。</item>
-      <item quantity="one">裡面還有 <xliff:g id="NUMBER_0">%s</xliff:g> 個通知。</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{裡面還有 # 個通知。}other{裡面還有 # 個通知。}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"螢幕已鎖定為橫向模式。"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"螢幕已鎖定為垂直模式。"</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動旋轉"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自動旋轉螢幕"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"位置"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"螢幕保護程式"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"相機存取權"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"麥克風存取權"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"允許"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"熱點"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"正在開啟…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"數據節省模式已開啟"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d 部裝置</item>
-      <item quantity="one">%d 部裝置</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# 部裝置}other{# 部裝置}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"電筒"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"相機使用中"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"流動數據"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"您要繼續您的工作階段嗎?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是的,請繼續"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"訪客模式"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"您正在使用訪客模式"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"新增使用者後,系統就會結束訪客模式,並刪除目前訪客工作階段中的所有應用程式和資料。"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"已達到使用者上限"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">您可以加入多達 <xliff:g id="COUNT">%d</xliff:g> 個使用者。</item>
-      <item quantity="one">只可以建立一個使用者。</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{只可建立一位使用者。}other{您可以加入多達 # 位使用者。}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"移除使用者?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"系統將會刪除這個使用者的所有應用程式和資料。"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"移除"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"提醒我"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"復原"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d 個小時</item>
-      <item quantity="one">%d 個小時</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d 分鐘</item>
-      <item quantity="one">%d 分鐘</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# 小時}=2{# 小時}other{# 小時}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# 分鐘}other{# 分鐘}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"省電模式"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"通知"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"電池"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"螢幕擷取畫面"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"一般訊息"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"免安裝應用程式"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"設定"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"儲存空間"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"提示"</string>
     <string name="instant_apps" msgid="8337185853050247304">"免安裝應用程式"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"切換"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"裝置控制"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"選擇要新增控制項的應用程式"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">已新增 <xliff:g id="NUMBER_1">%s</xliff:g> 個控制項。</item>
-      <item quantity="one">已新增 <xliff:g id="NUMBER_0">%s</xliff:g> 個控制項。</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已新增 # 個控制項。}other{已新增 # 個控制項。}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"已移除"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已加入至收藏位置 <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"新增圖塊"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"不要新增圖塊"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"選取使用者"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other">已啟用 <xliff:g id="COUNT_1">%s</xliff:g> 個應用程式</item>
-      <item quantity="one">已啟用 <xliff:g id="COUNT_0">%s</xliff:g> 個應用程式</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{已啟用 # 個應用程式}other{已啟用 # 個應用程式}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"新資料"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的應用程式"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"這些應用程式已啟用並執行 (即使您沒有使用)。這會提升應用程式的功能,但也可影響電池壽命。"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"已設定鬧鐘"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"相機和麥克風已關閉"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}other{# 則通知}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止廣播「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如要廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止廣播目前的內容"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"變更輸出來源"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
index ee41066..ab8e961a 100644
--- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"關閉"</item>
     <item msgid="460891964396502657">"開啟"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"無法使用"</item>
+    <item msgid="8014986104355098744">"已關閉"</item>
+    <item msgid="5966994759929723339">"已開啟"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 32d48ce..a0fe941 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"感應器已關閉"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"清除所有通知。"</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="other">群組中還有 <xliff:g id="NUMBER_1">%s</xliff:g> 則通知。</item>
-      <item quantity="one">群組中還有 <xliff:g id="NUMBER_0">%s</xliff:g> 則通知。</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{其中還有 # 則通知。}other{其中還有 # 則通知。}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"螢幕已鎖定為橫向模式。"</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"螢幕已鎖定為垂直模式。"</string>
     <string name="dessert_case" msgid="9104973640704357717">"Dessert Case"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"自動旋轉"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"自動旋轉螢幕"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"定位"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"螢幕保護程式"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"相機存取權"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"麥克風存取權"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"可以使用"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"無線基地台"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"開啟中…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"數據節省模式已開啟"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="other">%d 個裝置</item>
-      <item quantity="one">%d 個裝置</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# 部裝置}other{# 部裝置}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"手電筒"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"正在使用相機"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"行動數據"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"你要繼續這個工作階段嗎?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是,繼續"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"訪客模式"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"你目前處於訪客模式"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"新增使用者後,系統就會結束訪客模式,並刪除目前訪客工作階段中的所有應用程式和資料。"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"已達使用者數量上限"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="other">最多可新增 <xliff:g id="COUNT">%d</xliff:g> 位使用者。</item>
-      <item quantity="one">只能建立 1 位使用者。</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{只能建立 1 位使用者。}other{最#多可新增 # 位使用者。}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"要移除使用者嗎?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"系統將刪除這個使用者的所有應用程式和資料。"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"移除"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"提醒我"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"復原"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="other">%d 小時</item>
-      <item quantity="one">%d 小時</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="other">%d 分鐘</item>
-      <item quantity="one">%d 分鐘</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# 小時}=2{# 小時}other{# 小時}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# 分鐘}other{# 分鐘}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"省電模式"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"快訊"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"電池"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"螢幕截圖"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"一般訊息"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"免安裝應用程式"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"設定"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"儲存空間"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"提示"</string>
     <string name="instant_apps" msgid="8337185853050247304">"免安裝應用程式"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"切換"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"裝置控制"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"選擇應用程式以新增控制項"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="other">已新增 <xliff:g id="NUMBER_1">%s</xliff:g> 個控制項。</item>
-      <item quantity="one">已新增 <xliff:g id="NUMBER_0">%s</xliff:g> 個控制項。</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已新增 # 個控制項。}other{已新增 # 個控制項。}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"已移除"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已加入收藏,位置 <xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"新增設定方塊"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"不要新增設定方塊"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"選取使用者"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="other"><xliff:g id="COUNT_1">%s</xliff:g> 個應用程式正在運作</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%s</xliff:g> 個應用程式正在運作</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# 個應用程式使用中}other{# 個應用程式使用中}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"新資訊"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"使用中的應用程式"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"即使您並未使用,這些應用程式仍會持續啟用並執行。這可提升其功能,但也可能影響電池續航力。"</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"鬧鐘設定成功"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"已關閉相機和麥克風"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}other{# 則通知}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止播送「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止播送目前的內容"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"變更輸出來源"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"不明"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
index 1f70740..3d6a546 100644
--- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"已關閉"</item>
     <item msgid="460891964396502657">"已開啟"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"無法使用"</item>
+    <item msgid="8014986104355098744">"已關閉"</item>
+    <item msgid="5966994759929723339">"已開啟"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 6545d72..47de98e 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -205,10 +205,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Izinzwa zivalwe kokusebenzayo"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Susa zonke izaziso."</string>
     <string name="notification_group_overflow_indicator" msgid="7605120293801012648">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <plurals name="notification_group_overflow_description" formatted="false" msgid="91483442850649192">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> izaziso eziningi ngaphakathi.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> izaziso eziningi ngaphakathi.</item>
-    </plurals>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{isaziso esingu-# esengeziwe ngaphakathi.}one{izaziso ezingu-# ezengeziwe ngaphakathi.}other{izaziso ezingu-# ezengeziwe ngaphakathi.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"Isikrini sikhiyelwe ngomumo we-landscape."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"Isikrini sikhiyelwe ngomumo we-portrait."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Isikhwama soswidi"</string>
@@ -226,6 +223,7 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Ukuphenduka okuzenzakalelayo"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Phendula iskrini ngokuzenzakalela"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Indawo"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Isilondolozi sesikrini"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Ukufinyelela kwekhamera"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Ukufinyelela kwe-mic"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Iyatholakala"</string>
@@ -255,10 +253,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"I-Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Iyavula..."</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Iseva yedatha ivuliwe"</string>
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
-      <item quantity="one">%d amadivayisi</item>
-      <item quantity="other">%d amadivayisi</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{idivayisi engu-#}one{amadivayisi angu-#}other{amadivayisi angu-#}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"I-Flashlight"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Ikhamera esetshenziswayo"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Idatha yeselula"</string>
@@ -351,11 +346,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ingabe ufuna ukuqhubeka ngesikhathi sakho?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Qala phansi"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yebo, qhubeka"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Imodi yesivakashi"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Usemodini yesivakashi"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Ukwengeza umsebenzisi omusha kuzokhipha imodi yesivakashi futhi kusule wonke ama-app nedatha kusuka esikhathini sesihambeli samanje."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Kufinyelelwe kumkhawulo womsebenzisi"</string>
-    <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
-      <item quantity="one">Ungangeza kufikela kubasebenzisi abangu-<xliff:g id="COUNT">%d</xliff:g>.</item>
-      <item quantity="other">Ungangeza kufikela kubasebenzisi abangu-<xliff:g id="COUNT">%d</xliff:g>.</item>
-    </plurals>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Umsebenzisi oyedwa kuphela ongasungulwa.}one{Ungangeza kufikela kubasebenzisi abangu-#.}other{Ungangeza kufikela kubasebenzisi abangu-#.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Susa umsebenzisi?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Zonke izinhlelo zokusebenza nedatha yalo msebenzisi kuzosuswa."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Susa"</string>
@@ -541,14 +536,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Ngikhumbuze"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Susa"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"Kusnuzwe u-<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <plurals name="snoozeHourOptions" formatted="false" msgid="2066838694120718170">
-      <item quantity="one">%d amahora</item>
-      <item quantity="other">%d amahora</item>
-    </plurals>
-    <plurals name="snoozeMinuteOptions" formatted="false" msgid="8998483159208055980">
-      <item quantity="one">%d amaminithi</item>
-      <item quantity="other">%d amaminithi</item>
-    </plurals>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{ihora elingu-#}=2{amahora angu-#}one{amahora angu-#}other{amahora angu-#}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{umzuzu ongu-#}one{imizuzu engu-#}other{imizuzu engu-#}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Isilondolozi sebhethri"</string>
     <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>
@@ -697,7 +686,8 @@
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Izexwayiso"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Ibhethri"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Izithombe-skrini"</string>
-    <string name="notification_channel_general" msgid="4384774889645929705">"Imilayezo ejwayelekile"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Ama-App Asheshayo"</string>
+    <string name="notification_channel_setup" msgid="7660580986090760350">"Ukusetha"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Isitoreji"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Ukubonisa"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Izinhlelo zokusebenza ezisheshayo"</string>
@@ -771,10 +761,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"guqula"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Izilawuli zezinsiza"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Khetha uhlelo lokusebenza ukwengeza izilawuli"</string>
-    <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
-      <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> ukulawulwa okwengeziwe.</item>
-      <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ukulawulwa okwengeziwe.</item>
-    </plurals>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ulawulo olu-# olwengeziwe.}one{ukulawulwa okungu-# okwengeziwe.}other{ukulawulwa okungu-# okwengeziwe.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Isusiwe"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Kwenziwe intandokazi"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kwenziwe intandokazi, isimo esiyi-<xliff:g id="NUMBER">%d</xliff:g>"</string>
@@ -931,10 +918,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Engeza ithayela"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ungafaki ithayela"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Khetha umsebenzisi"</string>
-    <plurals name="fgs_manager_footer_label" formatted="false" msgid="790443735462280164">
-      <item quantity="one">Ama-app angu-<xliff:g id="COUNT_1">%s</xliff:g> ayasebenza</item>
-      <item quantity="other">Ama-app angu-<xliff:g id="COUNT_1">%s</xliff:g> ayasebenza</item>
-    </plurals>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{I-app e-# iyasebenza}one{Ama-app angu-# ayasebenza}other{Ama-app angu-# ayasebenza}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Ulwazi olusha"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Ama-app asebenzayo"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Lama-app ayaqhubeka esebenza, ngisho nalapho ungawasebenzisi. Lokhu kuthuthukisa ukusebenza kwawo, kodwa kungase kuthinte impilo yawo yebhethri."</string>
@@ -963,4 +947,10 @@
     <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"I-alamu isethiwe"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Ikhamera nemakrofoni kuvaliwe"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Isaziso esingu-#}one{Izaziso ezingu-#}other{Izaziso ezingu-#}}"</string>
+    <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Ukusakaza"</string>
+    <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Misa ukusakaza i-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Uma usakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g> noma ushintsha okuphumayo, ukusakaza kwakho kwamanje kuzoma"</string>
+    <string name="bt_le_audio_broadcast_dialog_switch_app" msgid="6098768269397105733">"Sakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
+    <string name="bt_le_audio_broadcast_dialog_different_output" msgid="7885102097302562674">"Shintsha okuphumayo"</string>
+    <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Akwaziwa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
index cc8bbb0..81c4636 100644
--- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
@@ -171,4 +171,9 @@
     <item msgid="146088982397753810">"Valiwe"</item>
     <item msgid="460891964396502657">"Vuliwe"</item>
   </string-array>
+  <string-array name="tile_states_dream">
+    <item msgid="6184819793571079513">"Ayitholakali"</item>
+    <item msgid="8014986104355098744">"Valiwe"</item>
+    <item msgid="5966994759929723339">"Vuliwe"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 3228c3c..9a71995 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -108,12 +108,6 @@
         <attr name="android:layout" />
     </declare-styleable>
 
-    <declare-styleable name="HybridNotificationTheme">
-        <attr name="hybridNotificationStyle" format="reference" />
-        <attr name="hybridNotificationTitleStyle" format="reference" />
-        <attr name="hybridNotificationTextStyle" format="reference" />
-    </declare-styleable>
-
     <declare-styleable name="PluginInflateContainer">
         <attr name="viewType" format="string" />
     </declare-styleable>
@@ -193,5 +187,9 @@
     <declare-styleable name="DreamOverlayDotImageView">
         <attr name="dotColor" format="color" />
     </declare-styleable>
+
+    <declare-styleable name="DelayableMarqueeTextView">
+        <attr name="marqueeDelay" format="integer" />
+    </declare-styleable>
 </resources>
 
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 02ba271..ccf18d2 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -233,4 +233,13 @@
     <color name="connected_network_secondary_color">#41493D</color>
 
     <color name="dream_overlay_camera_mic_off_dot_color">#FCBE03</color>
+
+    <!-- Air Quality -->
+    <color name="dream_overlay_aqi_good">#689F38</color>
+    <color name="dream_overlay_aqi_moderate">#FBC02D</color>
+    <color name="dream_overlay_aqi_unhealthy_sensitive">#F57C00</color>
+    <color name="dream_overlay_aqi_unhealthy">#C53929</color>
+    <color name="dream_overlay_aqi_very_unhealthy">#AD1457</color>
+    <color name="dream_overlay_aqi_hazardous">#880E4F</color>
+    <color name="dream_overlay_aqi_unknown">#BDC1C6</color>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 597e880..eff4e00 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -87,7 +87,7 @@
 
     <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
     <string name="quick_settings_tiles_stock" translatable="false">
-        internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction
+        internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream
     </string>
 
     <!-- The tiles to display in QuickSettings -->
@@ -438,6 +438,9 @@
          they were added. -->
     <integer name="config_smart_replies_in_notifications_onclick_init_delay">200</integer>
 
+    <!-- Smartspace trampoline activity that is used when the user taps smartspace. -->
+    <string name="config_smartspaceTrampolineActivityComponent" translatable="false">com.google.android.apps.gsa.staticplugins.opa.smartspace.ExportedSmartspaceTrampolineActivity</string>
+
     <!-- Screenshot editing default activity.  Must handle ACTION_EDIT image/png intents.
          Blank sends the user to the Chooser first.
          This name is in the ComponentName flattened format (package/class)  -->
@@ -629,11 +632,11 @@
 
     <!-- This value is used when calculating whether the device is in ambient light mode. It is
         light mode when the light sensor sample value exceeds above this value. -->
-    <integer name="config_ambientLightModeThreshold">5</integer>
+    <integer name="config_ambientLightModeThreshold">10</integer>
 
     <!-- This value is used when calculating whether the device is in ambient dark mode. It is
         dark mode when the light sensor sample value drops below this value. -->
-    <integer name="config_ambientDarkModeThreshold">2</integer>
+    <integer name="config_ambientDarkModeThreshold">5</integer>
 
     <!-- This value is used when calculating whether the device is in ambient light mode. Each
         sample contains light sensor events from this span of time duration. -->
@@ -690,14 +693,11 @@
     <!-- Flag to enable privacy dot views, it shall be true for normal case -->
     <bool name="config_enablePrivacyDot">true</bool>
 
-    <!-- Flag to enable dream overlay service and its registration -->
-    <bool name="config_dreamOverlayServiceEnabled">false</bool>
-
     <!-- Class for the communal source connector to be used -->
     <string name="config_communalSourceConnector" translatable="false"></string>
 
     <!-- How often in milliseconds to jitter the dream overlay in order to avoid burn-in. -->
-    <integer name="config_dreamOverlayBurnInProtectionUpdateIntervalMillis">500</integer>
+    <integer name="config_dreamOverlayBurnInProtectionUpdateIntervalMillis">1000</integer>
 
     <!-- How long in milliseconds before full burn-in protection is achieved. -->
     <integer name="config_dreamOverlayMillisUntilFullJitter">240000</integer>
@@ -727,4 +727,25 @@
         <item>com.android.keyguard</item>
         <item>com.android.systemui</item>
     </string-array>
+
+    <!-- The thresholds which determine the color used by the AQI dream overlay.
+         NOTE: This must always be kept sorted from low to high -->
+    <integer-array name="config_dreamAqiThresholds">
+        <item>-1</item>
+        <item>50</item>
+        <item>100</item>
+        <item>150</item>
+        <item>200</item>
+        <item>300</item>
+    </integer-array>
+
+    <!-- The color values which correspond to the thresholds above -->
+    <integer-array name="config_dreamAqiColorValues">
+        <item>@color/dream_overlay_aqi_good</item>
+        <item>@color/dream_overlay_aqi_moderate</item>
+        <item>@color/dream_overlay_aqi_unhealthy_sensitive</item>
+        <item>@color/dream_overlay_aqi_unhealthy</item>
+        <item>@color/dream_overlay_aqi_very_unhealthy</item>
+        <item>@color/dream_overlay_aqi_hazardous</item>
+    </integer-array>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6648841..4d36541 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -44,11 +44,52 @@
     <!-- The threshold to drag to trigger the edge action -->
     <dimen name="navigation_edge_action_drag_threshold">16dp</dimen>
     <!-- The threshold to progress back animation for edge swipe -->
-    <dimen name="navigation_edge_action_progress_threshold">400dp</dimen>
+    <dimen name="navigation_edge_action_progress_threshold">412dp</dimen>
     <!-- The minimum display position of the arrow on the screen -->
     <dimen name="navigation_edge_arrow_min_y">64dp</dimen>
     <!-- The amount by which the arrow is shifted to avoid the finger-->
-    <dimen name="navigation_edge_finger_offset">48dp</dimen>
+    <dimen name="navigation_edge_finger_offset">64dp</dimen>
+
+    <!-- The thickness of the arrow -->
+    <dimen name="navigation_edge_arrow_thickness">4dp</dimen>
+    <!-- The minimum delta needed to change direction / stop triggering back -->
+    <dimen name="navigation_edge_minimum_x_delta_for_switch">32dp</dimen>
+
+    <!-- entry state -->
+    <dimen name="navigation_edge_entry_margin">4dp</dimen>
+    <dimen name="navigation_edge_entry_background_width">8dp</dimen>
+    <dimen name="navigation_edge_entry_background_height">60dp</dimen>
+    <dimen name="navigation_edge_entry_edge_corners">6dp</dimen>
+    <dimen name="navigation_edge_entry_far_corners">6dp</dimen>
+    <dimen name="navigation_edge_entry_arrow_length">10dp</dimen>
+    <dimen name="navigation_edge_entry_arrow_height">7dp</dimen>
+
+    <!-- pre-threshold -->
+    <dimen name="navigation_edge_pre_threshold_margin">4dp</dimen>
+    <dimen name="navigation_edge_pre_threshold_background_width">64dp</dimen>
+    <dimen name="navigation_edge_pre_threshold_background_height">60dp</dimen>
+    <dimen name="navigation_edge_pre_threshold_edge_corners">22dp</dimen>
+    <dimen name="navigation_edge_pre_threshold_far_corners">26dp</dimen>
+
+    <!-- post-threshold / active -->
+    <dimen name="navigation_edge_active_margin">14dp</dimen>
+    <dimen name="navigation_edge_active_background_width">60dp</dimen>
+    <dimen name="navigation_edge_active_background_height">60dp</dimen>
+    <dimen name="navigation_edge_active_edge_corners">30dp</dimen>
+    <dimen name="navigation_edge_active_far_corners">30dp</dimen>
+    <dimen name="navigation_edge_active_arrow_length">8dp</dimen>
+    <dimen name="navigation_edge_active_arrow_height">9dp</dimen>
+
+    <dimen name="navigation_edge_stretch_margin">18dp</dimen>
+    <dimen name="navigation_edge_stretch_background_width">74dp</dimen>
+    <dimen name="navigation_edge_stretch_background_height">60dp</dimen>
+    <dimen name="navigation_edge_stretch_edge_corners">30dp</dimen>
+    <dimen name="navigation_edge_stretch_far_corners">30dp</dimen>
+    <dimen name="navigation_edge_stretched_arrow_length">7dp</dimen>
+    <dimen name="navigation_edge_stretched_arrow_height">10dp</dimen>
+
+    <dimen name="navigation_edge_cancelled_arrow_length">12dp</dimen>
+    <dimen name="navigation_edge_cancelled_arrow_height">0dp</dimen>
 
     <!-- Height of notification icons in the status bar -->
     <dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
@@ -366,6 +407,7 @@
     <!-- Height of status bar in split shade mode - visible only on large screens -->
     <dimen name="large_screen_shade_header_height">@*android:dimen/quick_qs_offset_height</dimen>
     <dimen name="large_screen_shade_header_min_height">@dimen/qs_header_row_min_height</dimen>
+    <dimen name="large_screen_shade_header_left_padding">@dimen/qs_horizontal_margin</dimen>
 
     <!-- The top margin of the panel that holds the list of notifications.
          On phones it's always 0dp but it's overridden in Car UI
@@ -452,7 +494,7 @@
     <dimen name="navigation_key_padding">0dp</dimen>
 
     <!-- Floating rotation button -->
-    <dimen name="floating_rotation_button_diameter">40dp</dimen>
+    <dimen name="floating_rotation_button_diameter">52dp</dimen>
     <dimen name="floating_rotation_button_min_margin">20dp</dimen>
     <dimen name="floating_rotation_button_taskbar_left_margin">20dp</dimen>
     <dimen name="floating_rotation_button_taskbar_bottom_margin">10dp</dimen>
@@ -1204,6 +1246,15 @@
     <!-- Maximum overshoot for the pulse expansion -->
     <dimen name="pulse_expansion_max_top_overshoot">32dp</dimen>
 
+    <!-- The drag amount required for the split shade to fully expand. -->
+    <dimen name="split_shade_full_transition_distance">200dp</dimen>
+    <!--
+        The drag amount required for the scrim to fully fade in when expanding the split shade.
+        Currently setting it a little longer than the full shade transition distance, to avoid
+        having a state where the screen is fully black without any content showing.
+    -->
+    <dimen name="split_shade_scrim_transition_distance">300dp</dimen>
+
     <!-- Alpha in duration in ms for the auth ripple to become fully vislble. If set to 0,
          it is immediately visible. -->
     <integer name="auth_ripple_alpha_in_duration">100</integer>
@@ -1452,6 +1503,10 @@
 
     <dimen name="dream_overlay_y_offset">80dp</dimen>
 
+    <dimen name="dream_aqi_badge_corner_radius">28dp</dimen>
+    <dimen name="dream_aqi_badge_padding_vertical">6dp</dimen>
+    <dimen name="dream_aqi_badge_padding_horizontal">16dp</dimen>
+
     <dimen name="status_view_margin_horizontal">0dp</dimen>
 
     <!-- Media output broadcast dialog QR code picture size -->
@@ -1464,4 +1519,18 @@
     <dimen name="media_output_broadcast_info_title_height">24dp</dimen>
     <dimen name="media_output_broadcast_info_summary_height">20dp</dimen>
     <dimen name="media_output_broadcast_info_edit">18dp</dimen>
+
+    <!-- Broadcast dialog -->
+    <dimen name="broadcast_dialog_title_img_margin_top">18dp</dimen>
+    <dimen name="broadcast_dialog_title_text_size">24sp</dimen>
+    <dimen name="broadcast_dialog_title_text_margin">16dp</dimen>
+    <dimen name="broadcast_dialog_title_text_margin_top">18dp</dimen>
+    <dimen name="broadcast_dialog_subtitle_text_size">14sp</dimen>
+    <dimen name="broadcast_dialog_icon_size">24dp</dimen>
+    <dimen name="broadcast_dialog_icon_margin_top">25dp</dimen>
+    <dimen name="broadcast_dialog_btn_radius">100dp</dimen>
+    <dimen name="broadcast_dialog_btn_margin_bottom">4dp</dimen>
+    <dimen name="broadcast_dialog_btn_text_size">16sp</dimen>
+    <dimen name="broadcast_dialog_btn_minHeight">44dp</dimen>
+    <dimen name="broadcast_dialog_margin">16dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e144b43..343ec4f6 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -505,10 +505,10 @@
     <string name="notification_group_overflow_indicator">+ <xliff:g id="number" example="3">%s</xliff:g></string>
 
     <!-- Content description describing how many more notifications are in a group [CHAR LIMIT=NONE] -->
-    <plurals name="notification_group_overflow_description">
-        <item quantity="one"><xliff:g id="number" example="1">%s</xliff:g> more notification inside.</item>
-        <item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> more notifications inside.</item>
-    </plurals>
+    <string name="notification_group_overflow_description">{count, plural,
+        =1 {# more notification inside.}
+        other {# more notifications inside.}
+    }</string>
 
     <!-- Format to use to summarize a message from a contact in a single line of text. For example: "Julia: How's it going?". [CHAR LIMIT=NONE] -->
 
@@ -578,6 +578,8 @@
     <!-- QuickSettings: Location [CHAR LIMIT=NONE] -->
     <string name="quick_settings_location_label">Location</string>
     <!-- QuickSettings: Location (Off) [CHAR LIMIT=NONE] -->
+    <!-- QuickSettings: Screen saver [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_screensaver_label">Screen saver</string>
     <!-- QuickSettings: Camera [CHAR LIMIT=NONE] -->
     <string name="quick_settings_camera_label">Camera access</string>
     <!-- QuickSettings: Microphone [CHAR LIMIT=NONE] -->
@@ -652,10 +654,10 @@
          the user why they can't toggle the hotspot tile. [CHAR LIMIT=20] -->
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled">Data Saver is on</string>
     <!-- QuickSettings: Hotspot: Secondary label for how many devices are connected to the hotspot [CHAR LIMIT=NONE] -->
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices">
-        <item quantity="one">%d device</item>
-        <item quantity="other">%d devices</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices">{count, plural,
+        =1 {# device}
+        other {# devices}
+    }</string>
     <!-- QuickSettings: Notifications [CHAR LIMIT=NONE] -->
     <!-- QuickSettings: Flashlight [CHAR LIMIT=NONE] -->
     <string name="quick_settings_flashlight_label">Flashlight</string>
@@ -911,14 +913,25 @@
     <!-- Notification when resuming an existing guest session: Action that continues with the current session [CHAR LIMIT=35] -->
     <string name="guest_wipe_session_dontwipe">Yes, continue</string>
 
+    <!-- App name of the notification when guest mode is entered [CHAR LIMIT=35] -->
+    <string name="guest_notification_app_name">Guest mode</string>
+    <!-- Title of the notification when guest mode is entered [CHAR LIMIT=35] -->
+    <string name="guest_notification_session_active">You are in guest mode</string>
+
+    <!-- Additional message for add user confirmation dialog that is appended when current user is
+         guest and guest is ephemeral. This is to warn users that current guest session
+         would get removed after a new user is added and switched to [CHAR LIMIT=none] -->
+    <string name="user_add_user_message_guest_remove">\n\nAdding a new user will exit guest mode
+        and delete all apps and data from the current guest session.</string>
+
     <!-- Title for the dialog that lets users know that the maximum allowed number of users on the device has been reached. [CHAR LIMIT=35]-->
     <string name="user_limit_reached_title">User limit reached</string>
 
     <!-- Message that tells people what's the maximum number of uses allowed on the device. [CHAR_LIMIT=NONE]-->
-    <plurals name="user_limit_reached_message">
-        <item quantity="one">Only one user can be created.</item>
-        <item quantity="other">You can add up to <xliff:g id="count" example="3">%d</xliff:g> users.</item>
-    </plurals>
+    <string name="user_limit_reached_message">{count, plural,
+        =1 {Only one user can be created.}
+        other {You can add up to # users.}
+    }</string>
 
     <!-- Title of the confirmation dialog for deleting a user [CHAR LIMIT=NONE] -->
     <string name="user_remove_user_title">Remove user?</string>
@@ -1473,20 +1486,20 @@
     <!-- Notification: Snooze panel: message indicating how long the notification was snoozed for. [CHAR LIMIT=100]-->
     <string name="snoozed_for_time">Snoozed for <xliff:g id="time_amount" example="15 minutes">%1$s</xliff:g></string>
 
-    <!-- Notification:Snooze panel: Snooze options for hours -->
-    <plurals name="snoozeHourOptions">
-        <item quantity="one">%d hour</item>
-        <item quantity="two">%d hours</item>
-        <item quantity="few">%d hours</item>
-        <item quantity="other">%d hours</item>
-    </plurals>
+    <!-- Notification:Snooze panel: Snooze options for hours [CHAR LIMIT=NONE]-->
+    <string name="snoozeHourOptions">{count, plural,
+        =1 {# hour}
+        =2 {# hours}
+        few {# hours}
+        other {# hours}
+    }</string>
 
-   <!--  Notification: Snooze panel: Snooze options for minutes -->
-   <plurals name="snoozeMinuteOptions">
-        <item quantity="one">%d minute</item>
-        <item quantity="few">%d minutes</item>
-        <item quantity="other">%d minutes</item>
-    </plurals>
+   <!--  Notification: Snooze panel: Snooze options for minutes [CHAR LIMIT=NONE]-->
+   <string name="snoozeMinuteOptions">{count, plural,
+        =1 {# minute}
+        few {# minutes}
+        other {# minutes}
+    }</string>
 
     <!-- Summary of battery saver not available [CHAR LIMIT=NONE] -->
 
@@ -1896,8 +1909,10 @@
     <string name="notification_channel_battery">Battery</string>
     <!-- Title for the notification channel dedicated to screenshot progress. [CHAR LIMIT=NONE] -->
     <string name="notification_channel_screenshot">Screenshots</string>
-    <!-- Title for the notification channel for miscellaneous notices. [CHAR LIMIT=NONE] -->
-    <string name="notification_channel_general">General Messages</string>
+    <!-- Title for the notification channel for instant app notices. [CHAR LIMIT=NONE] -->
+    <string name="notification_channel_instant">Instant Apps</string>
+    <!-- Title for the notification channel for setup notices. [CHAR LIMIT=NONE] -->
+    <string name="notification_channel_setup">Setup</string>
     <!-- Title for the notification channel for problems with storage (i.e. low disk). [CHAR LIMIT=NONE] -->
     <string name="notification_channel_storage">Storage</string>
     <!-- Title for the notification channel for hints and suggestions. [CHAR LIMIT=NONE] -->
@@ -2121,10 +2136,10 @@
     <!-- Controls management providers screen title [CHAR LIMIT=60]-->
     <string name="controls_providers_title">Choose app to add controls</string>
     <!-- Number of favorites for controls management screen [CHAR LIMIT=NONE]-->
-    <plurals name="controls_number_of_favorites">
-        <item quantity="one"><xliff:g id="number" example="1">%s</xliff:g> control added.</item>
-        <item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> controls added.</item>
-    </plurals>
+    <string name="controls_number_of_favorites">{count, plural,
+        =1 {# control added.}
+        other {# controls added.}
+    }</string>
 
     <!-- Removed control in management screen [CHAR LIMIT=20] -->
     <string name="controls_removed">Removed</string>
@@ -2480,10 +2495,10 @@
     <string name="qs_user_switch_dialog_title">Select user</string>
 
     <!-- Label for the entry point to open the dialog which shows currently running applications [CHAR LIMIT=NONE]-->
-    <plurals name="fgs_manager_footer_label">
-        <item quantity="one"><xliff:g id="count" example="1">%s</xliff:g> app is active</item>
-        <item quantity="other"><xliff:g id="count" example="2">%s</xliff:g> apps are active</item>
-    </plurals>
+    <string name="fgs_manager_footer_label">{count, plural,
+        =1 {# app is active}
+        other {# apps are active}
+    }</string>
     <!-- Content description for a dot indicator in the running application indicating that there
     is new information [CHAR LIMIT=NONE] -->
     <string name="fgs_dot_content_description">New information</string>
@@ -2552,4 +2567,26 @@
     =1 {# notification}
     other {# notifications}
     }</string>
+
+    <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, media app is broadcasting -->
+    <string name="broadcasting_description_is_broadcasting">Broadcasting</string>
+    <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, title -->
+    <string name="bt_le_audio_broadcast_dialog_title">Stop broadcasting <xliff:g id="app_name" example="App Name 1">%1$s</xliff:g>?</string>
+    <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, sub-title -->
+    <string name="bt_le_audio_broadcast_dialog_sub_title">If you broadcast <xliff:g id="switchApp" example="App Name 2">%1$s</xliff:g> or change the output, your current broadcast will stop</string>
+    <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, switch to others app. -->
+    <string name="bt_le_audio_broadcast_dialog_switch_app">Broadcast <xliff:g id="switchApp" example="App Name 2">%1$s</xliff:g></string>
+    <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, different output. -->
+    <string name="bt_le_audio_broadcast_dialog_different_output">Change output</string>
+    <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, media app is unknown -->
+    <string name="bt_le_audio_broadcast_dialog_unknown_name">Unknown</string>
+
+    <!-- Date format for the Dream Date Complication [CHAR LIMIT=NONE] -->
+    <string name="dream_date_complication_date_format">EEE, MMM d</string>
+
+    <!-- Time format for the Dream Time Complication for 12-hour time format [CHAR LIMIT=NONE] -->
+    <string name="dream_time_complication_12_hr_time_format">h:mm</string>
+
+    <!-- Time format for the Dream Time Complication for 24-hour time format [CHAR LIMIT=NONE] -->
+    <string name="dream_time_complication_24_hr_time_format">kk:mm</string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 0c25f54..f954bc9 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -17,30 +17,6 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
 
-    <!-- HybridNotification themes and styles -->
-
-    <style name="HybridNotification">
-        <item name="hybridNotificationStyle">@style/hybrid_notification</item>
-        <item name="hybridNotificationTitleStyle">@style/hybrid_notification_title</item>
-        <item name="hybridNotificationTextStyle">@style/hybrid_notification_text</item>
-    </style>
-
-    <style name="hybrid_notification">
-        <item name="android:paddingStart">@*android:dimen/notification_content_margin_start</item>
-        <item name="android:paddingEnd">12dp</item>
-    </style>
-
-    <style name="hybrid_notification_title">
-        <item name="android:paddingEnd">4dp</item>
-        <item name="android:textAppearance">@*android:style/TextAppearance.DeviceDefault.Notification.Title</item>
-    </style>
-
-    <style name="hybrid_notification_text"
-           parent="@*android:style/Widget.DeviceDefault.Notification.Text">
-        <item name="android:paddingEnd">4dp</item>
-    </style>
-
-
     <style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon">
         <item name="android:textSize">@dimen/status_bar_clock_size</item>
         <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
@@ -1196,4 +1172,48 @@
         <item name="android:shadowColor">@color/keyguard_shadow_color</item>
         <item name="android:shadowRadius">?attr/shadowRadius</item>
     </style>
+
+    <style name="BroadcastDialogTitleStyle">
+        <item name="android:textAppearance">@style/TextAppearanceBroadcastDialogTitle</item>
+        <item name="android:layout_marginStart">@dimen/broadcast_dialog_title_text_margin</item>
+        <item name="android:layout_marginEnd">@dimen/broadcast_dialog_title_text_margin</item>
+        <item name="android:layout_marginTop">@dimen/broadcast_dialog_title_text_margin_top</item>
+        <item name="android:layout_marginBottom">18dp</item>
+    </style>
+
+    <style name="TextAppearanceBroadcastDialogTitle" parent="@android:style/TextAppearance.DeviceDefault.Headline">
+        <item name="android:textSize">@dimen/broadcast_dialog_title_text_size</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textDirection">locale</item>
+        <item name="android:ellipsize">end</item>
+    </style>
+
+    <style name="BroadcastDialogBodyStyle">
+        <item name="android:textAppearance">@style/TextAppearanceBroadcastDialogSubTitle</item>
+        <item name="android:layout_margin">@dimen/broadcast_dialog_title_text_margin</item>
+    </style>
+
+    <style name="TextAppearanceBroadcastDialogSubTitle" parent="@android:style/TextAppearance.DeviceDefault.Headline">
+        <item name="android:textSize">@dimen/broadcast_dialog_subtitle_text_size</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+        <item name="android:textDirection">locale</item>
+        <item name="android:ellipsize">end</item>
+    </style>
+
+    <style name="BroadcastDialogButtonStyle">
+        <item name="android:textAppearance">@style/TextAppearanceBroadcastDialogButton</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_gravity">center</item>
+        <item name="android:gravity">center</item>
+        <item name="android:stateListAnimator">@null</item>
+        <item name="android:elevation">0dp</item>
+        <item name="android:minHeight">@dimen/broadcast_dialog_btn_minHeight</item>
+        <item name="android:background">@drawable/broadcast_dialog_btn_bg</item>
+    </style>
+
+    <style name="TextAppearanceBroadcastDialogButton" parent="@android:style/TextAppearance.DeviceDefault.Headline">
+        <item name="android:textColor">?androidprv:attr/textColorOnAccent</item>
+        <item name="android:textSize">@dimen/broadcast_dialog_btn_text_size</item>
+    </style>
 </resources>
diff --git a/packages/SystemUI/res/values/tiles_states_strings.xml b/packages/SystemUI/res/values/tiles_states_strings.xml
index e273416..c809551 100644
--- a/packages/SystemUI/res/values/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values/tiles_states_strings.xml
@@ -308,4 +308,14 @@
         <item>Off</item>
         <item>On</item>
     </string-array>
+
+    <!-- State names for dream (screensaver) tile: unavailable, off, on.
+         This subtitle is shown when the tile is in that particular state but does not set its own
+         subtitle, so some of these may never appear on screen. They should still be translated as
+         if they could appear. [CHAR LIMIT=32] -->
+    <string-array name="tile_states_dream">
+        <item>Unavailable</item>
+        <item>Off</item>
+        <item>On</item>
+    </string-array>
 </resources>
\ No newline at end of file
diff --git a/packages/SystemUI/screenshot/Android.bp b/packages/SystemUI/screenshot/Android.bp
new file mode 100644
index 0000000..a79fd9040d
--- /dev/null
+++ b/packages/SystemUI/screenshot/Android.bp
@@ -0,0 +1,48 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"],
+}
+
+android_library {
+    name: "SystemUIScreenshotLib",
+    manifest: "AndroidManifest.xml",
+
+    srcs: [
+        // All files in this library should be in Kotlin besides some exceptions.
+        "src/**/*.kt",
+
+        // This file was forked from google3, so exceptionally it can be in Java.
+        "src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java",
+    ],
+
+    resource_dirs: [
+        "res",
+    ],
+
+    static_libs: [
+        "SystemUI-core",
+        "androidx.test.espresso.core",
+        "androidx.appcompat_appcompat",
+        "platform-screenshot-diff-core",
+    ],
+
+    kotlincflags: ["-Xjvm-default=all"],
+}
diff --git a/packages/SystemUI/screenshot/AndroidManifest.xml b/packages/SystemUI/screenshot/AndroidManifest.xml
new file mode 100644
index 0000000..3b703be
--- /dev/null
+++ b/packages/SystemUI/screenshot/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.systemui.testing.screenshot">
+    <application>
+        <activity
+            android:name="com.android.systemui.testing.screenshot.ScreenshotActivity"
+            android:exported="true"
+            android:theme="@style/Theme.SystemUI.Screenshot" />
+    </application>
+
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+</manifest>
diff --git a/packages/SystemUI/screenshot/res/values/themes.xml b/packages/SystemUI/screenshot/res/values/themes.xml
new file mode 100644
index 0000000..40e50bb
--- /dev/null
+++ b/packages/SystemUI/screenshot/res/values/themes.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <style name="Theme.SystemUI.Screenshot" parent="Theme.SystemUI">
+        <item name="android:windowActionBar">false</item>
+        <item name="android:windowNoTitle">true</item>
+
+        <!-- Make sure that device specific cutouts don't impact the outcome of screenshot tests -->
+        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java
new file mode 100644
index 0000000..96ec4c5
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/DynamicColorsTestUtils.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.testing.screenshot;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.provider.Settings;
+import android.util.Log;
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.ColorRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.core.content.ContextCompat;
+import androidx.test.espresso.Espresso;
+import androidx.test.espresso.IdlingRegistry;
+import androidx.test.espresso.IdlingResource;
+
+import org.json.JSONObject;
+import org.junit.function.ThrowingRunnable;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/*
+ * Note: This file was forked from
+ * google3/third_party/java_src/android_libs/material_components/screenshot_tests/java/android/
+ * support/design/scuba/color/DynamicColorsTestUtils.java.
+ */
+
+/** Utility that helps change the dynamic system colors for testing. */
+@RequiresApi(32)
+public class DynamicColorsTestUtils {
+
+    private static final String TAG = DynamicColorsTestUtils.class.getSimpleName();
+
+    private static final String THEME_CUSTOMIZATION_KEY = "theme_customization_overlay_packages";
+    private static final String THEME_CUSTOMIZATION_SYSTEM_PALETTE_KEY =
+            "android.theme.customization.system_palette";
+
+    private static final int ORANGE_SYSTEM_SEED_COLOR = 0xA66800;
+    private static final int ORANGE_EXPECTED_SYSTEM_ACCENT1_600_COLOR = -8235756;
+
+    private DynamicColorsTestUtils() {
+    }
+
+    /**
+     * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on an orange
+     * seed color, and then wait for the change to propagate to the app by comparing
+     * android.R.color.system_accent1_600 to the expected orange value.
+     */
+    public static void updateSystemColorsToOrange() {
+        updateSystemColors(ORANGE_SYSTEM_SEED_COLOR, ORANGE_EXPECTED_SYSTEM_ACCENT1_600_COLOR);
+    }
+
+    /**
+     * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on the provided
+     * {@code seedColor}, and then wait for the change to propagate to the app by comparing
+     * android.R.color.system_accent1_600 to {@code expectedSystemAccent1600}.
+     */
+    public static void updateSystemColors(
+            @ColorInt int seedColor, @ColorInt int expectedSystemAccent1600) {
+        Context context = getInstrumentation().getTargetContext();
+
+        int actualSystemAccent1600 =
+                ContextCompat.getColor(context, android.R.color.system_accent1_600);
+
+        if (expectedSystemAccent1600 == actualSystemAccent1600) {
+            String expectedColorString = Integer.toHexString(expectedSystemAccent1600);
+            Log.d(
+                    TAG,
+                    "Skipped updating system colors since system_accent1_600 is already equal to "
+                            + "expected: "
+                            + expectedColorString);
+            return;
+        }
+
+        updateSystemColors(seedColor);
+    }
+
+    /**
+     * Update system dynamic colors (e.g., android.R.color.system_accent1_600) based on the provided
+     * {@code seedColor}, and then wait for the change to propagate to the app by checking
+     * android.R.color.system_accent1_600 for any change.
+     */
+    public static void updateSystemColors(@ColorInt int seedColor) {
+        Context context = getInstrumentation().getTargetContext();
+
+        // Initialize system color idling resource with original system_accent1_600 value.
+        ColorChangeIdlingResource systemColorIdlingResource =
+                new ColorChangeIdlingResource(context, android.R.color.system_accent1_600);
+
+        // Update system theme color setting to trigger fabricated resource overlay.
+        runWithShellPermissionIdentity(
+                () ->
+                        Settings.Secure.putString(
+                                context.getContentResolver(),
+                                THEME_CUSTOMIZATION_KEY,
+                                buildThemeCustomizationString(seedColor)));
+
+        // Wait for system color update to propagate to app.
+        IdlingRegistry idlingRegistry = IdlingRegistry.getInstance();
+        idlingRegistry.register(systemColorIdlingResource);
+        Espresso.onIdle();
+        idlingRegistry.unregister(systemColorIdlingResource);
+
+        Log.d(TAG,
+                Settings.Secure.getString(context.getContentResolver(), THEME_CUSTOMIZATION_KEY));
+    }
+
+    private static String buildThemeCustomizationString(@ColorInt int seedColor) {
+        String seedColorHex = Integer.toHexString(seedColor);
+        Map<String, String> themeCustomizationMap = new HashMap<>();
+        themeCustomizationMap.put(THEME_CUSTOMIZATION_SYSTEM_PALETTE_KEY, seedColorHex);
+        return new JSONObject(themeCustomizationMap).toString();
+    }
+
+    private static void runWithShellPermissionIdentity(@NonNull ThrowingRunnable runnable) {
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        uiAutomation.adoptShellPermissionIdentity();
+        try {
+            runnable.run();
+        } catch (Throwable e) {
+            throw new RuntimeException(e);
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
+    }
+
+    private static class ColorChangeIdlingResource implements IdlingResource {
+
+        private final Context mContext;
+        private final int mColorResId;
+        private final int mInitialColorInt;
+
+        private ResourceCallback mResourceCallback;
+        private boolean mIdleNow;
+
+        ColorChangeIdlingResource(Context context, @ColorRes int colorResId) {
+            this.mContext = context;
+            this.mColorResId = colorResId;
+            this.mInitialColorInt = ContextCompat.getColor(context, colorResId);
+        }
+
+        @Override
+        public String getName() {
+            return ColorChangeIdlingResource.class.getName();
+        }
+
+        @Override
+        public boolean isIdleNow() {
+            if (mIdleNow) {
+                return true;
+            }
+
+            int currentColorInt = ContextCompat.getColor(mContext, mColorResId);
+
+            String initialColorString = Integer.toHexString(mInitialColorInt);
+            String currentColorString = Integer.toHexString(currentColorInt);
+            Log.d(TAG, String.format("Initial=%s, Current=%s", initialColorString,
+                    currentColorString));
+
+            mIdleNow = currentColorInt != mInitialColorInt;
+            Log.d(TAG, String.format("idleNow=%b", mIdleNow));
+
+            if (mIdleNow) {
+                mResourceCallback.onTransitionToIdle();
+            }
+            return mIdleNow;
+        }
+
+        @Override
+        public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
+            this.mResourceCallback = resourceCallback;
+        }
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotActivity.kt
similarity index 66%
copy from packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
copy to packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotActivity.kt
index 5b187b3..2a55a80 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotActivity.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,9 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.unfold.config
 
-interface UnfoldTransitionConfig {
-    val isEnabled: Boolean
-    val isHingeAngleEnabled: Boolean
-}
+package com.android.systemui.testing.screenshot
+
+import androidx.activity.ComponentActivity
+
+/** The Activity that is launched and whose content is set for screenshot tests. */
+class ScreenshotActivity : ComponentActivity()
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt
new file mode 100644
index 0000000..363ce10
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestRule.kt
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.testing.screenshot
+
+import android.app.UiModeManager
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.os.UserHandle
+import android.view.Display
+import android.view.View
+import android.view.WindowManagerGlobal
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+import platform.test.screenshot.GoldenImagePathManager
+import platform.test.screenshot.PathConfig
+import platform.test.screenshot.PathElementNoContext
+import platform.test.screenshot.ScreenshotTestRule
+import platform.test.screenshot.matchers.PixelPerfectMatcher
+
+/**
+ * A base rule for screenshot diff tests.
+ *
+ * This rules takes care of setting up the activity according to [testSpec] by:
+ * - emulating the display size and density.
+ * - setting the dark/light mode.
+ * - setting the system (Material You) colors to a fixed value.
+ *
+ * @see ComposeScreenshotTestRule
+ * @see ViewScreenshotTestRule
+ */
+class ScreenshotTestRule(private val testSpec: ScreenshotTestSpec) : TestRule {
+    private var currentDisplay: DisplaySpec? = null
+    private var currentGoldenIdentifier: String? = null
+
+    private val pathConfig =
+        PathConfig(
+            PathElementNoContext("model", isDir = true) {
+                currentDisplay?.name ?: error("currentDisplay is null")
+            },
+        )
+    private val defaultMatcher = PixelPerfectMatcher()
+
+    private val screenshotRule =
+        ScreenshotTestRule(
+            SystemUIGoldenImagePathManager(
+                pathConfig,
+                currentGoldenIdentifier = {
+                    currentGoldenIdentifier ?: error("currentGoldenIdentifier is null")
+                },
+            )
+        )
+
+    override fun apply(base: Statement, description: Description): Statement {
+        // The statement which call beforeTest() before running the test and afterTest() afterwards.
+        val statement =
+            object : Statement() {
+                override fun evaluate() {
+                    try {
+                        beforeTest()
+                        base.evaluate()
+                    } finally {
+                        afterTest()
+                    }
+                }
+            }
+
+        return screenshotRule.apply(statement, description)
+    }
+
+    private fun beforeTest() {
+        // Update the system colors to a fixed color, so that tests don't depend on the host device
+        // extracted colors. Note that we don't restore the default device colors at the end of the
+        // test because changing the colors (and waiting for them to be applied) is costly and makes
+        // the screenshot tests noticeably slower.
+        DynamicColorsTestUtils.updateSystemColorsToOrange()
+
+        // Emulate the display size and density.
+        val display = testSpec.display
+        val density = display.densityDpi
+        val wm = WindowManagerGlobal.getWindowManagerService()
+        val (width, height) = getEmulatedDisplaySize()
+        wm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, density, UserHandle.myUserId())
+        wm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, width, height)
+
+        // Force the dark/light theme.
+        val uiModeManager =
+            InstrumentationRegistry.getInstrumentation()
+                .targetContext
+                .getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
+        uiModeManager.setApplicationNightMode(
+            if (testSpec.isDarkTheme) {
+                UiModeManager.MODE_NIGHT_YES
+            } else {
+                UiModeManager.MODE_NIGHT_NO
+            }
+        )
+    }
+
+    private fun afterTest() {
+        // Reset the density and display size.
+        val wm = WindowManagerGlobal.getWindowManagerService()
+        wm.clearForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, UserHandle.myUserId())
+        wm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY)
+
+        // Reset the dark/light theme.
+        val uiModeManager =
+            InstrumentationRegistry.getInstrumentation()
+                .targetContext
+                .getSystemService(Context.UI_MODE_SERVICE) as UiModeManager
+        uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_AUTO)
+    }
+
+    /**
+     * Compare the content of [view] with the golden image identified by [goldenIdentifier] in the
+     * context of [testSpec].
+     */
+    fun screenshotTest(goldenIdentifier: String, view: View) {
+        val bitmap = drawIntoBitmap(view)
+
+        // Compare bitmap against golden asset.
+        val isDarkTheme = testSpec.isDarkTheme
+        val isLandscape = testSpec.isLandscape
+        val identifierWithSpec = buildString {
+            append(goldenIdentifier)
+            if (isDarkTheme) append("_dark")
+            if (isLandscape) append("_landscape")
+        }
+
+        // TODO(b/230832101): Provide a way to pass a PathConfig and override the file name on
+        // device to assertBitmapAgainstGolden instead?
+        currentDisplay = testSpec.display
+        currentGoldenIdentifier = goldenIdentifier
+        screenshotRule.assertBitmapAgainstGolden(bitmap, identifierWithSpec, defaultMatcher)
+        currentDisplay = null
+        currentGoldenIdentifier = goldenIdentifier
+    }
+
+    /** Draw [view] into a [Bitmap]. */
+    private fun drawIntoBitmap(view: View): Bitmap {
+        val bitmap =
+            Bitmap.createBitmap(
+                view.measuredWidth,
+                view.measuredHeight,
+                Bitmap.Config.ARGB_8888,
+            )
+        val canvas = Canvas(bitmap)
+        view.draw(canvas)
+        return bitmap
+    }
+
+    /** Get the emulated display size for [testSpec]. */
+    private fun getEmulatedDisplaySize(): Pair<Int, Int> {
+        val display = testSpec.display
+        val isPortraitNaturalPosition = display.width < display.height
+        return if (testSpec.isLandscape) {
+            if (isPortraitNaturalPosition) {
+                display.height to display.width
+            } else {
+                display.width to display.height
+            }
+        } else {
+            if (isPortraitNaturalPosition) {
+                display.width to display.height
+            } else {
+                display.height to display.width
+            }
+        }
+    }
+}
+
+private class SystemUIGoldenImagePathManager(
+    pathConfig: PathConfig,
+    private val currentGoldenIdentifier: () -> String,
+) :
+    GoldenImagePathManager(
+        appContext = InstrumentationRegistry.getInstrumentation().context,
+        deviceLocalPath =
+            InstrumentationRegistry.getInstrumentation()
+                .targetContext
+                .filesDir
+                .absolutePath
+                .toString() + "/sysui_screenshots",
+        pathConfig = pathConfig,
+    ) {
+    // This string is appended to all actual/expected screenshots on the device. We append the
+    // golden identifier so that our pull_golden.py scripts can map a screenshot on device to its
+    // asset (and automatically update it, if necessary).
+    override fun toString() = currentGoldenIdentifier()
+}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt
new file mode 100644
index 0000000..7fc6245
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ScreenshotTestSpec.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.testing.screenshot
+
+/** The specification of a device display to be used in a screenshot test. */
+data class DisplaySpec(
+    val name: String,
+    val width: Int,
+    val height: Int,
+    val densityDpi: Int,
+)
+
+/** The specification of a screenshot diff test. */
+class ScreenshotTestSpec(
+    val display: DisplaySpec,
+    val isDarkTheme: Boolean = false,
+    val isLandscape: Boolean = false,
+) {
+    companion object {
+        /**
+         * Return a list of [ScreenshotTestSpec] for each of the [displays].
+         *
+         * If [isDarkTheme] is null, this will create a spec for both light and dark themes, for
+         * each of the orientation.
+         *
+         * If [isLandscape] is null, this will create a spec for both portrait and landscape, for
+         * each of the light/dark themes.
+         */
+        fun forDisplays(
+            vararg displays: DisplaySpec,
+            isDarkTheme: Boolean? = null,
+            isLandscape: Boolean? = null,
+        ): List<ScreenshotTestSpec> {
+            return displays.flatMap { display ->
+                buildList {
+                    fun addDisplay(isLandscape: Boolean) {
+                        if (isDarkTheme != true) {
+                            add(ScreenshotTestSpec(display, isDarkTheme = false, isLandscape))
+                        }
+
+                        if (isDarkTheme != false) {
+                            add(ScreenshotTestSpec(display, isDarkTheme = true, isLandscape))
+                        }
+                    }
+
+                    if (isLandscape != true) {
+                        addDisplay(isLandscape = false)
+                    }
+
+                    if (isLandscape != false) {
+                        addDisplay(isLandscape = true)
+                    }
+                }
+            }
+        }
+    }
+
+    override fun toString(): String = buildString {
+        // This string is appended to PNGs stored in the device, so let's keep it simple.
+        append(display.name)
+        if (isDarkTheme) append("_dark")
+        if (isLandscape) append("_landscape")
+    }
+}
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
new file mode 100644
index 0000000..35812e3
--- /dev/null
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
@@ -0,0 +1,80 @@
+package com.android.systemui.testing.screenshot
+
+import android.app.Activity
+import android.app.Dialog
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewGroup.LayoutParams
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import org.junit.Assert.assertEquals
+import org.junit.rules.RuleChain
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/** A rule for View screenshot diff tests. */
+class ViewScreenshotTestRule(testSpec: ScreenshotTestSpec) : TestRule {
+    private val activityRule = ActivityScenarioRule(ScreenshotActivity::class.java)
+    private val screenshotRule = ScreenshotTestRule(testSpec)
+
+    private val delegate = RuleChain.outerRule(screenshotRule).around(activityRule)
+
+    override fun apply(base: Statement, description: Description): Statement {
+        return delegate.apply(base, description)
+    }
+
+    /**
+     * Compare the content of the view provided by [viewProvider] with the golden image identified
+     * by [goldenIdentifier] in the context of [testSpec].
+     */
+    fun screenshotTest(
+        goldenIdentifier: String,
+        layoutParams: LayoutParams =
+            LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT),
+        viewProvider: (Activity) -> View,
+    ) {
+        activityRule.scenario.onActivity { activity ->
+            // Make sure that the activity draws full screen and fits the whole display instead of
+            // the system bars.
+            activity.window.setDecorFitsSystemWindows(false)
+            activity.setContentView(viewProvider(activity), layoutParams)
+        }
+
+        // We call onActivity again because it will make sure that our Activity is done measuring,
+        // laying out and drawing its content (that we set in the previous onActivity lambda).
+        activityRule.scenario.onActivity { activity ->
+            // Check that the content is what we expected.
+            val content = activity.requireViewById<ViewGroup>(android.R.id.content)
+            assertEquals(1, content.childCount)
+            screenshotRule.screenshotTest(goldenIdentifier, content.getChildAt(0))
+        }
+    }
+
+    /**
+     * Compare the content of the dialog provided by [dialogProvider] with the golden image
+     * identified by [goldenIdentifier] in the context of [testSpec].
+     */
+    fun dialogScreenshotTest(
+        goldenIdentifier: String,
+        dialogProvider: (Activity) -> Dialog,
+    ) {
+        var dialog: Dialog? = null
+        activityRule.scenario.onActivity { activity ->
+            // Make sure that the dialog draws full screen and fits the whole display instead of the
+            // system bars.
+            dialog =
+                dialogProvider(activity).apply {
+                    window.setDecorFitsSystemWindows(false)
+                    show()
+                }
+        }
+
+        // We call onActivity again because it will make sure that our Dialog is done measuring,
+        // laying out and drawing its content (that we set in the previous onActivity lambda).
+        activityRule.scenario.onActivity {
+            // Check that the content is what we expected.
+            val dialog = dialog ?: error("dialog is null")
+            screenshotRule.screenshotTest(goldenIdentifier, dialog.window.decorView)
+        }
+    }
+}
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index 3cf5bc1..9f790c6 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -47,6 +47,7 @@
     ],
     static_libs: [
         "PluginCoreLib",
+        "SystemUIUnfoldLib",
         "androidx.dynamicanimation_dynamicanimation",
         "androidx.concurrent_concurrent-futures",
         "dagger2",
diff --git a/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt b/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
index 19a5309..b4646ae 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
@@ -36,6 +36,12 @@
     val resourceId: Int
 }
 
+interface DeviceConfigFlag<T> : Flag<T> {
+    val name: String
+    val namespace: String
+    val default: T
+}
+
 interface SysPropFlag<T> : Flag<T> {
     val name: String
     val default: T
@@ -74,6 +80,14 @@
     override val teamfood: Boolean = false
 ) : ResourceFlag<Boolean>
 
+data class DeviceConfigBooleanFlag @JvmOverloads constructor(
+    override val id: Int,
+    override val name: String,
+    override val namespace: String,
+    override val default: Boolean = false,
+    override val teamfood: Boolean = false
+) : DeviceConfigFlag<Boolean>
+
 data class SysPropBooleanFlag @JvmOverloads constructor(
     override val id: Int,
     override val name: String,
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
index 88fe034..203b236 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/pip/PipSurfaceTransactionHelper.java
@@ -80,7 +80,8 @@
 
     public PictureInPictureSurfaceTransaction scaleAndCrop(
             SurfaceControl.Transaction tx, SurfaceControl leash,
-            Rect sourceRectHint, Rect sourceBounds, Rect destinationBounds, Rect insets) {
+            Rect sourceRectHint, Rect sourceBounds, Rect destinationBounds, Rect insets,
+            float progress) {
         mTmpSourceRectF.set(sourceBounds);
         mTmpDestinationRect.set(sourceBounds);
         mTmpDestinationRect.inset(insets);
@@ -93,9 +94,13 @@
                     : (float) destinationBounds.height() / sourceBounds.height();
         } else {
             // scale by sourceRectHint if it's not edge-to-edge
-            scale = sourceRectHint.width() <= sourceRectHint.height()
+            final float endScale = sourceRectHint.width() <= sourceRectHint.height()
                     ? (float) destinationBounds.width() / sourceRectHint.width()
                     : (float) destinationBounds.height() / sourceRectHint.height();
+            final float startScale = sourceRectHint.width() <= sourceRectHint.height()
+                    ? (float) destinationBounds.width() / sourceBounds.width()
+                    : (float) destinationBounds.height() / sourceBounds.height();
+            scale = (1 - progress) * startScale + progress * endScale;
         }
         final float left = destinationBounds.left - (insets.left + sourceBounds.left) * scale;
         final float top = destinationBounds.top - (insets.top + sourceBounds.top) * scale;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index e743c4e..a030bf6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -42,12 +42,6 @@
     void onOverviewShown(boolean fromHome) = 6;
 
     /**
-     * Get the secondary split screen app's rectangle when not minimized.
-     * @deprecated
-     */
-    Rect getNonMinimizedSplitScreenSecondaryBounds() = 7;
-
-    /**
      * Control the {@param alpha} of the option nav bar button (back-button in 2 button mode
      * and home handle & background in gestural mode).  The {@param animate} is currently only
      * supported for 2 button mode.
@@ -94,21 +88,6 @@
      */
     void stopScreenPinning() = 17;
 
-    /**
-     * Handle the provided image as if it was a screenshot.
-     *
-     * Deprecated, use handleImageBundleAsScreenshot with image bundle and UserTask
-     * @deprecated
-     */
-    void handleImageAsScreenshot(in Bitmap screenImage, in Rect locationInScreen,
-              in Insets visibleInsets, int taskId) = 21;
-
-    /**
-     * Sets the split-screen divider minimized state
-     * @deprecated
-     */
-    void setSplitScreenMinimized(boolean minimized) = 22;
-
     /*
      * Notifies that the swipe-to-home (recents animation) is finished.
      */
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
index 675dc9b5..e9c1acb 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
@@ -243,7 +243,7 @@
         return new Task(taskKey,
                 td != null ? td.getPrimaryColor() : 0,
                 td != null ? td.getBackgroundColor() : 0,
-                taskInfo.supportsSplitScreenMultiWindow, isLocked, td, taskInfo.topActivity);
+                taskInfo.supportsMultiWindow, isLocked, td, taskInfo.topActivity);
     }
 
     public Task(TaskKey key) {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
index 01f417f..b29dc83 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
@@ -20,6 +20,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static com.android.internal.view.RotationPolicy.NATURAL_ROTATION;
+import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -97,6 +98,7 @@
     @SuppressLint("InlinedApi")
     private @WindowInsetsController.Behavior
     int mBehavior = WindowInsetsController.BEHAVIOR_DEFAULT;
+    private int mNavBarMode;
     private boolean mSkipOverrideUserLockPrefsOnce;
     private final int mLightIconColor;
     private final int mDarkIconColor;
@@ -397,6 +399,10 @@
         if (rotateSuggestionsDisabled) onRotationSuggestionsDisabled();
     }
 
+    public void onNavigationModeChanged(int mode) {
+        mNavBarMode = mode;
+    }
+
     public void onBehaviorChanged(int displayId, @WindowInsetsController.Behavior int behavior) {
         if (DEFAULT_DISPLAY != displayId) {
             return;
@@ -433,7 +439,8 @@
      */
     @SuppressLint("InlinedApi")
     private boolean canShowRotationButton() {
-        return mIsNavigationBarShowing || mBehavior == WindowInsetsController.BEHAVIOR_DEFAULT;
+        return mIsNavigationBarShowing || mBehavior == WindowInsetsController.BEHAVIOR_DEFAULT
+                || isGesturalMode(mNavBarMode);
     }
 
     @DrawableRes
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java
index 06f5372..9265f07 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java
@@ -114,6 +114,8 @@
     private static IRemoteTransition.Stub wrapRemoteTransition(
             final RemoteAnimationRunnerCompat remoteAnimationAdapter) {
         return new IRemoteTransition.Stub() {
+            final ArrayMap<IBinder, Runnable> mFinishRunnables = new ArrayMap<>();
+
             @Override
             public void startAnimation(IBinder token, TransitionInfo info,
                     SurfaceControl.Transaction t,
@@ -137,6 +139,8 @@
                 float displayH = 0;
                 for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                     final TransitionInfo.Change change = info.getChanges().get(i);
+                    // skip changes that we didn't wrap
+                    if (!leashMap.containsKey(change.getLeash())) continue;
                     if (change.getTaskInfo() != null
                             && change.getTaskInfo().getActivityType() == ACTIVITY_TYPE_HOME) {
                         isReturnToHome = change.getMode() == TRANSIT_OPEN
@@ -173,6 +177,8 @@
                     for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                         final TransitionInfo.Change change = info.getChanges().get(i);
                         final SurfaceControl leash = leashMap.get(change.getLeash());
+                        // skip changes that we didn't wrap
+                        if (leash == null) continue;
                         final int mode = info.getChanges().get(i).getMode();
                         // Only deal with independent layers
                         if (!TransitionInfo.isIndependent(change, info)) continue;
@@ -214,9 +220,9 @@
                         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                             info.getChanges().get(i).getLeash().release();
                         }
-                        for (int i = leashMap.size() - 1; i >= 0; --i) {
-                            leashMap.valueAt(i).release();
-                        }
+                        // Don't release here since launcher might still be using them. Instead
+                        // let launcher release them (eg. via RemoteAnimationTargets)
+                        leashMap.clear();
                         try {
                             finishCallback.onTransitionFinished(null /* wct */, finishTransaction);
                         } catch (RemoteException e) {
@@ -225,19 +231,32 @@
                         }
                     }
                 };
+                synchronized (mFinishRunnables) {
+                    mFinishRunnables.put(token, animationFinishedCallback);
+                }
                 // TODO(bc-unlcok): Pass correct transit type.
-                remoteAnimationAdapter.onAnimationStart(
-                        TRANSIT_OLD_NONE,
-                        appsCompat, wallpapersCompat, nonAppsCompat,
-                        animationFinishedCallback);
+                remoteAnimationAdapter.onAnimationStart(TRANSIT_OLD_NONE,
+                        appsCompat, wallpapersCompat, nonAppsCompat, () -> {
+                            synchronized (mFinishRunnables) {
+                                if (mFinishRunnables.remove(token) == null) return;
+                            }
+                            animationFinishedCallback.run();
+                        });
             }
 
             @Override
             public void mergeAnimation(IBinder token, TransitionInfo info,
                     SurfaceControl.Transaction t, IBinder mergeTarget,
                     IRemoteTransitionFinishedCallback finishCallback) {
-                // TODO: hook up merge to recents onTaskAppeared if applicable. Until then, ignore
-                //       any incoming merges.
+                // TODO: hook up merge to recents onTaskAppeared if applicable. Until then, adapt
+                //       to legacy cancel.
+                final Runnable finishRunnable;
+                synchronized (mFinishRunnables) {
+                    finishRunnable = mFinishRunnables.remove(mergeTarget);
+                }
+                if (finishRunnable == null) return;
+                remoteAnimationAdapter.onAnimationCancelled();
+                finishRunnable.run();
             }
         };
     }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
index 9cf482f..249133a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
@@ -17,7 +17,6 @@
 package com.android.systemui.shared.system;
 
 import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
-import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
@@ -32,7 +31,6 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.ArrayMap;
-import android.util.IntArray;
 import android.util.SparseArray;
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
@@ -142,21 +140,12 @@
         // changes should be ordered top-to-bottom in z
         final int mode = change.getMode();
 
-        // Don't move anything that isn't independent within its parents
-        if (!TransitionInfo.isIndependent(change, info)) {
-            if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT || mode == TRANSIT_CHANGE) {
-                t.setPosition(leash, change.getEndRelOffset().x, change.getEndRelOffset().y);
-            }
-            return;
-        }
+        t.reparent(leash, info.getRootLeash());
+        final Rect absBounds =
+                (mode == TRANSIT_OPEN) ? change.getEndAbsBounds() : change.getStartAbsBounds();
+        t.setPosition(leash, absBounds.left - info.getRootOffset().x,
+                absBounds.top - info.getRootOffset().y);
 
-        final boolean hasParent = change.getParent() != null;
-
-        if (!hasParent) {
-            t.reparent(leash, info.getRootLeash());
-            t.setPosition(leash, change.getStartAbsBounds().left - info.getRootOffset().x,
-                    change.getStartAbsBounds().top - info.getRootOffset().y);
-        }
         // Put all the OPEN/SHOW on top
         if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
             if (isOpening) {
@@ -196,8 +185,7 @@
                 .setContainerLayer()
                 // Initial the surface visible to respect the visibility of the original surface.
                 .setHidden(false)
-                .setParent(change.getParent() == null ? info.getRootLeash()
-                        : info.getChange(change.getParent()).getLeash())
+                .setParent(info.getRootLeash())
                 .build();
         // Copied Transitions setup code (which expects bottom-to-top order, so we swap here)
         setupLeash(leashSurface, change, info.getChanges().size() - order, info, t);
@@ -269,58 +257,32 @@
     public static RemoteAnimationTargetCompat[] wrap(TransitionInfo info, boolean wallpapers,
             SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
         final ArrayList<RemoteAnimationTargetCompat> out = new ArrayList<>();
-        final SparseArray<RemoteAnimationTargetCompat> childTaskTargets = new SparseArray<>();
-        final IntArray excludedParentTaskIds = new IntArray();
+        final SparseArray<TransitionInfo.Change> childTaskTargets = new SparseArray<>();
         for (int i = 0; i < info.getChanges().size(); i++) {
             final TransitionInfo.Change change = info.getChanges().get(i);
             final boolean changeIsWallpaper =
                     (change.getFlags() & TransitionInfo.FLAG_IS_WALLPAPER) != 0;
             if (wallpapers != changeIsWallpaper) continue;
 
+            if (!wallpapers) {
+                final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+                // Children always come before parent since changes are in top-to-bottom z-order.
+                if (taskInfo != null) {
+                    if (childTaskTargets.contains(taskInfo.taskId)) {
+                        // has children, so not a leaf. Skip.
+                        continue;
+                    }
+                    if (taskInfo.hasParentTask()) {
+                        childTaskTargets.put(taskInfo.parentTaskId, change);
+                    }
+                }
+            }
+
             final RemoteAnimationTargetCompat targetCompat =
                     new RemoteAnimationTargetCompat(change, info.getChanges().size() - i, info, t);
             if (leashMap != null) {
                 leashMap.put(change.getLeash(), targetCompat.leash);
             }
-            final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
-            if (taskInfo != null) {
-                // Skip wrapping excluded parent task animate target since it will animate its child
-                // tasks instead.
-                if (excludedParentTaskIds.binarySearch(taskInfo.taskId) != -1) {
-                    continue;
-                }
-
-                // Check if there's a matching child task target in cache.
-                RemoteAnimationTargetCompat childTaskTarget = childTaskTargets.get(taskInfo.taskId);
-                if (childTaskTarget != null) {
-                    // Launcher monitors leaf task ids to perform animation, override the target
-                    // with its child task information so Launcher can animate this parent surface
-                    // directly with leaf task information.
-                    targetCompat.taskInfo = childTaskTarget.taskInfo;
-                    targetCompat.taskId = childTaskTarget.taskId;
-                    childTaskTargets.remove(taskInfo.taskId);
-                }
-
-                // Check if it has a parent task, cache its information for later use.
-                if (taskInfo.parentTaskId != -1
-                        && excludedParentTaskIds.binarySearch(taskInfo.parentTaskId) == -1) {
-                    if (!childTaskTargets.contains(taskInfo.parentTaskId)) {
-                        // Cache the target amd skip wrapping it info the final animation targets.
-                        // Otherwise, the child task might get transformed multiple-times with the
-                        // flow like RecentsView#redrawLiveTile.
-                        childTaskTargets.put(taskInfo.parentTaskId, targetCompat);
-                        continue;
-                    }
-
-                    // There is another child task target cached with the same parent task id.
-                    // Which means the parent having multiple child tasks in transition. Stop
-                    // propagate child task info.
-                    childTaskTarget = childTaskTargets.removeReturnOld(taskInfo.parentTaskId);
-                    out.add(childTaskTarget);
-                    excludedParentTaskIds.add(taskInfo.parentTaskId);
-                }
-            }
-
             out.add(targetCompat);
         }
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
index de35514..db41601 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
@@ -21,12 +21,14 @@
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
 import static android.window.TransitionFilter.CONTAINER_ORDER_TOP;
 
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_RECENTS;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -132,16 +134,17 @@
                 // TODO(b/177438007): Move this set-up logic into launcher's animation impl.
                 mToken = transition;
                 // This transition is for opening recents, so recents is on-top. We want to draw
-                // the current going-away task on top of recents, though, so move it to front
+                // the current going-away tasks on top of recents, though, so move them to front.
+                // Note that we divide up the "layer space" into 3 regions each the size of
+                // the change count. This way we can easily move changes into above/below/between
+                // while maintaining their relative ordering.
                 final ArrayList<WindowContainerToken> pausingTasks = new ArrayList<>();
                 WindowContainerToken pipTask = null;
                 WindowContainerToken recentsTask = null;
-                for (int i = info.getChanges().size() - 1; i >= 0; --i) {
-                    final TransitionInfo.Change change = info.getChanges().get(i);
-                    final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
-                    if (change.getMode() == TRANSIT_CLOSE || change.getMode() == TRANSIT_TO_BACK) {
-                        t.setLayer(leashMap.get(change.getLeash()),
-                                info.getChanges().size() * 3 - i);
+                for (int i = apps.length - 1; i >= 0; --i) {
+                    final ActivityManager.RunningTaskInfo taskInfo = apps[i].taskInfo;
+                    if (apps[i].mode == MODE_CLOSING) {
+                        t.setLayer(apps[i].leash, info.getChanges().size() * 3 - i);
                         if (taskInfo == null) {
                             continue;
                         }
@@ -154,8 +157,7 @@
                     } else if (taskInfo != null
                             && taskInfo.topActivityType == ACTIVITY_TYPE_RECENTS) {
                         // This task is for recents, keep it on top.
-                        t.setLayer(leashMap.get(change.getLeash()),
-                                info.getChanges().size() * 3 - i);
+                        t.setLayer(apps[i].leash, info.getChanges().size() * 3 - i);
                         recentsTask = taskInfo.token;
                     } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
                         recentsTask = taskInfo.token;
@@ -167,7 +169,8 @@
                 }
                 t.apply();
                 mRecentsSession.setup(controller, info, finishedCallback, pausingTasks, pipTask,
-                        recentsTask, leashMap, mToken);
+                        recentsTask, leashMap, mToken,
+                        (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0);
                 recents.onAnimationStart(mRecentsSession, apps, wallpapers, new Rect(0, 0, 0, 0),
                         new Rect());
             }
@@ -183,6 +186,8 @@
                 } catch (RemoteException e) {
                     Log.e(TAG, "Error merging transition.", e);
                 }
+                // commit taskAppeared after merge transition finished.
+                mRecentsSession.commitTasksAppearedIfNeeded(recents);
             }
         };
         mTransition = new RemoteTransition(remote, appThread);
@@ -222,12 +227,14 @@
         private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null;
         private PictureInPictureSurfaceTransaction mPipTransaction = null;
         private IBinder mTransition = null;
+        private boolean mKeyguardLocked = false;
+        private RemoteAnimationTargetCompat[] mAppearedTargets;
 
         void setup(RecentsAnimationControllerCompat wrapped, TransitionInfo info,
                 IRemoteTransitionFinishedCallback finishCB,
                 ArrayList<WindowContainerToken> pausingTasks, WindowContainerToken pipTask,
                 WindowContainerToken recentsTask, ArrayMap<SurfaceControl, SurfaceControl> leashMap,
-                IBinder transition) {
+                IBinder transition, boolean keyguardLocked) {
             if (mInfo != null) {
                 throw new IllegalStateException("Trying to run a new recents animation while"
                         + " recents is already active.");
@@ -240,12 +247,14 @@
             mRecentsTask = recentsTask;
             mLeashMap = leashMap;
             mTransition = transition;
+            mKeyguardLocked = keyguardLocked;
         }
 
         @SuppressLint("NewApi")
         boolean merge(TransitionInfo info, SurfaceControl.Transaction t,
                 RecentsAnimationListener recents) {
             SparseArray<TransitionInfo.Change> openingTasks = null;
+            mAppearedTargets = null;
             boolean cancelRecents = false;
             boolean homeGoingAway = false;
             boolean hasChangingApp = false;
@@ -326,10 +335,17 @@
                 targets[i] = target;
             }
             t.apply();
-            recents.onTasksAppeared(targets);
+            mAppearedTargets = targets;
             return true;
         }
 
+        private void commitTasksAppearedIfNeeded(RecentsAnimationListener recents) {
+            if (mAppearedTargets != null) {
+                recents.onTasksAppeared(mAppearedTargets);
+                mAppearedTargets = null;
+            }
+        }
+
         @Override public ThumbnailData screenshotTask(int taskId) {
             try {
                 final TaskSnapshot snapshot =
@@ -374,6 +390,10 @@
             final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
             final WindowContainerTransaction wct = new WindowContainerTransaction();
 
+            if (mKeyguardLocked && mRecentsTask != null) {
+                if (toHome) wct.reorder(mRecentsTask, true /* toTop */);
+                else wct.restoreTransientOrder(mRecentsTask);
+            }
             if (!toHome && mPausingTasks != null && mOpeningLeashes == null) {
                 // The gesture went back to opening the app rather than continuing with
                 // recents, so end the transition by moving the app back to the top (and also
@@ -383,16 +403,21 @@
                     wct.reorder(mPausingTasks.get(i), true /* onTop */);
                     t.show(mInfo.getChange(mPausingTasks.get(i)).getLeash());
                 }
-                if (mRecentsTask != null) {
+                if (!mKeyguardLocked && mRecentsTask != null) {
                     wct.restoreTransientOrder(mRecentsTask);
                 }
             } else {
-                if (!sendUserLeaveHint) {
-                    for (int i = 0; i < mPausingTasks.size(); ++i) {
+                for (int i = 0; i < mPausingTasks.size(); ++i) {
+                    if (!sendUserLeaveHint) {
                         // This means recents is not *actually* finishing, so of course we gotta
                         // do special stuff in WMCore to accommodate.
                         wct.setDoNotPip(mPausingTasks.get(i));
                     }
+                    // Since we will reparent out of the leashes, pre-emptively hide the child
+                    // surface to match the leash. Otherwise, there will be a flicker before the
+                    // visibility gets committed in Core when using split-screen (in splitscreen,
+                    // the leaf-tasks are not "independent" so aren't hidden by normal setup).
+                    t.hide(mInfo.getChange(mPausingTasks.get(i)).getLeash());
                 }
                 if (mPipTask != null && mPipTransaction != null && sendUserLeaveHint) {
                     t.show(mInfo.getChange(mPipTask).getLeash());
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index 5bd81a4..b894b10 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -28,6 +28,7 @@
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.InsetsController;
+import android.view.InsetsFrameProvider;
 import android.view.InsetsState;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
@@ -105,7 +106,11 @@
      */
     public void setProvidesInsetsTypes(WindowManager.LayoutParams params,
             int[] providesInsetsTypes) {
-        params.providesInsetsTypes = providesInsetsTypes;
+        final int length = providesInsetsTypes.length;
+        params.providedInsets = new InsetsFrameProvider[length];
+        for (int i = 0; i < length; i++) {
+            params.providedInsets[i] = new InsetsFrameProvider(providesInsetsTypes[i]);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
deleted file mode 100644
index d1b0639..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
+++ /dev/null
@@ -1,49 +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.unfold.config
-
-import android.content.Context
-import android.os.SystemProperties
-
-internal class ResourceUnfoldTransitionConfig(private val context: Context) :
-    UnfoldTransitionConfig {
-
-    override val isEnabled: Boolean
-        get() = readIsEnabledResource() && isPropertyEnabled
-
-    override val isHingeAngleEnabled: Boolean
-        get() = readIsHingeAngleEnabled()
-
-    private val isPropertyEnabled: Boolean
-        get() =
-            SystemProperties.getInt(
-                UNFOLD_TRANSITION_MODE_PROPERTY_NAME, UNFOLD_TRANSITION_PROPERTY_ENABLED) ==
-                UNFOLD_TRANSITION_PROPERTY_ENABLED
-
-    private fun readIsEnabledResource(): Boolean =
-        context.resources.getBoolean(com.android.internal.R.bool.config_unfoldTransitionEnabled)
-
-    private fun readIsHingeAngleEnabled(): Boolean =
-        context.resources.getBoolean(com.android.internal.R.bool.config_unfoldTransitionHingeAngle)
-}
-
-/**
- * Temporary persistent property to control unfold transition mode.
- *
- * See [com.android.unfold.config.AnimationMode].
- */
-private const val UNFOLD_TRANSITION_MODE_PROPERTY_NAME = "persist.unfold.transition_enabled"
-private const val UNFOLD_TRANSITION_PROPERTY_ENABLED = 1
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
new file mode 100644
index 0000000..7f2933e
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.system
+
+import android.app.ActivityManager
+import android.app.WindowConfiguration
+import com.android.systemui.unfold.util.CurrentActivityTypeProvider
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class ActivityManagerActivityTypeProvider @Inject constructor(
+    private val activityManager: ActivityManager
+) : CurrentActivityTypeProvider {
+
+    override val isHomeActivity: Boolean?
+        get() {
+            val activityType = activityManager.getRunningTasks(/* maxNum= */ 1)
+                    ?.getOrNull(0)?.topActivityType ?: return null
+
+            return activityType == WindowConfiguration.ACTIVITY_TYPE_HOME
+        }
+}
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
new file mode 100644
index 0000000..3b8d318
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.system
+
+import android.content.Context
+import android.hardware.devicestate.DeviceStateManager
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
+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 {
+
+    private val callbacks: MutableMap<FoldCallback,
+            DeviceStateManager.DeviceStateCallback> = hashMapOf()
+
+    override fun registerCallback(callback: FoldCallback, executor: Executor) {
+        val listener = FoldStateListener(context, callback)
+        deviceStateManager.registerCallback(executor, listener)
+        callbacks[callback] = listener
+    }
+
+    override fun unregisterCallback(callback: FoldCallback) {
+        val listener = callbacks.remove(callback)
+        listener?.let {
+            deviceStateManager.unregisterCallback(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
new file mode 100644
index 0000000..24ae42a
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.system
+
+import android.os.Handler
+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.UnfoldBackground
+import com.android.systemui.unfold.dagger.UnfoldMain
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.util.CurrentActivityTypeProvider
+import dagger.Binds
+import dagger.Module
+import java.util.concurrent.Executor
+
+/**
+ * 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 {
+
+    @Binds
+    abstract fun activityTypeProvider(executor: ActivityManagerActivityTypeProvider):
+            CurrentActivityTypeProvider
+
+    @Binds
+    abstract fun config(config: ResourceUnfoldTransitionConfig): UnfoldTransitionConfig
+
+    @Binds
+    abstract fun foldState(provider: DeviceStateManagerFoldProvider): FoldProvider
+
+    @Binds
+    @UnfoldMain
+    abstract fun mainExecutor(@Main executor: Executor): Executor
+
+    @Binds
+    @UnfoldMain
+    abstract fun mainHandler(@Main handler: Handler): Handler
+
+    @Binds
+    @UnfoldBackground
+    abstract fun backgroundExecutor(@UiBackground executor: Executor): Executor
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/EmptyHingeAngleProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/EmptyHingeAngleProvider.kt
deleted file mode 100644
index b351585..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/EmptyHingeAngleProvider.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.android.systemui.unfold.updates.hinge
-
-import androidx.core.util.Consumer
-
-internal object EmptyHingeAngleProvider : HingeAngleProvider {
-    override fun start() {}
-
-    override fun stop() {}
-
-    override fun removeCallback(listener: Consumer<Float>) {}
-
-    override fun addCallback(listener: Consumer<Float>) {}
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeAngleProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeAngleProvider.kt
deleted file mode 100644
index 48a5b12..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeAngleProvider.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.android.systemui.unfold.updates.hinge
-
-import androidx.core.util.Consumer
-import com.android.systemui.statusbar.policy.CallbackController
-
-/**
- * Emits device hinge angle values (angle between two integral parts of the device).
- *
- * The hinge angle could be from 0 to 360 degrees inclusive. For foldable devices usually 0
- * corresponds to fully closed (folded) state and 180 degrees corresponds to fully open (flat)
- * state.
- */
-interface HingeAngleProvider : CallbackController<Consumer<Float>> {
-    fun start()
-    fun stop()
-}
-
-const val FULLY_OPEN_DEGREES = 180f
-const val FULLY_CLOSED_DEGREES = 0f
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt
index 53c528f..ec938b2 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt
@@ -1,3 +1,17 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
 package com.android.systemui.unfold.util
 
 import android.content.Context
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
index 81cc3a9..3ec8ce9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java
@@ -18,6 +18,7 @@
 
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
+import android.text.TextUtils;
 
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -103,6 +104,15 @@
         mView.setMessage(resId);
     }
 
+    /**
+     * Set Text if KeyguardMessageArea is empty.
+     */
+    public void setMessageIfEmpty(int resId) {
+        if (TextUtils.isEmpty(mView.getText())) {
+            setMessage(resId);
+        }
+    }
+
     public void setNextMessageColor(ColorStateList colorState) {
         mView.setNextMessageColor(colorState);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
index bfacc59..29e912f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -207,6 +207,7 @@
         if (reason != KeyguardSecurityView.SCREEN_ON || mShowImeAtScreenOn) {
             showInput();
         }
+        mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_password);
     }
 
     private void showInput() {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 39c3949..b97d9671 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -304,6 +304,12 @@
     }
 
     @Override
+    public void onResume(int reason) {
+        super.onResume(reason);
+        mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_pattern);
+    }
+
+    @Override
     public boolean needsInput() {
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
index f7423ed..59a018a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -127,6 +127,7 @@
     public void onResume(int reason) {
         super.onResume(reason);
         mPasswordEntry.requestFocus();
+        mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_pin);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index cce516d..8fb622a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -50,6 +50,7 @@
 import android.util.Log;
 import android.util.MathUtils;
 import android.util.TypedValue;
+import android.view.GestureDetector;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -93,6 +94,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.function.Consumer;
 
 public class KeyguardSecurityContainer extends FrameLayout {
     static final int USER_TYPE_PRIMARY = 1;
@@ -127,12 +129,12 @@
 
     private static final long IME_DISAPPEAR_DURATION_MS = 125;
 
-    // The duration of the animation to switch bouncer sides.
-    private static final long BOUNCER_HANDEDNESS_ANIMATION_DURATION_MS = 500;
+    // The duration of the animation to switch security sides.
+    private static final long SECURITY_SHIFT_ANIMATION_DURATION_MS = 500;
 
-    // How much of the switch sides animation should be dedicated to fading the bouncer out. The
+    // How much of the switch sides animation should be dedicated to fading the security out. The
     // remainder will fade it back in again.
-    private static final float BOUNCER_HANDEDNESS_ANIMATION_FADE_OUT_PROPORTION = 0.2f;
+    private static final float SECURITY_SHIFT_ANIMATION_FADE_OUT_PROPORTION = 0.2f;
 
     @VisibleForTesting
     KeyguardSecurityViewFlipper mSecurityViewFlipper;
@@ -146,6 +148,7 @@
     private final SpringAnimation mSpringAnimation;
     private final VelocityTracker mVelocityTracker = VelocityTracker.obtain();
     private final List<Gefingerpoken> mMotionEventListeners = new ArrayList<>();
+    private final GestureDetector mDoubleTapDetector;
 
     private float mLastTouchY = -1;
     private int mActivePointerId = -1;
@@ -305,6 +308,7 @@
         super(context, attrs, defStyle);
         mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y);
         mViewConfiguration = ViewConfiguration.get(context);
+        mDoubleTapDetector = new GestureDetector(context, new DoubleTapListener());
     }
 
     void onResume(SecurityMode securityMode, boolean faceAuthEnabled) {
@@ -372,10 +376,23 @@
         mViewMode.updatePositionByTouchX(x);
     }
 
-    /** Returns whether the inner SecurityViewFlipper is left-aligned when in one-handed mode. */
-    public boolean isOneHandedModeLeftAligned() {
-        return mCurrentMode == MODE_ONE_HANDED
-                && ((OneHandedViewMode) mViewMode).isLeftAligned();
+    public boolean isSidedSecurityMode() {
+        return mViewMode instanceof SidedSecurityMode;
+    }
+
+    /** Returns whether the inner SecurityViewFlipper is left-aligned when in sided mode. */
+    public boolean isSecurityLeftAligned() {
+        return mViewMode instanceof SidedSecurityMode
+                && ((SidedSecurityMode) mViewMode).isLeftAligned();
+    }
+
+    /**
+     * Returns whether the touch happened on the other side of security (like bouncer) when in
+     * sided mode.
+     */
+    public boolean isTouchOnTheOtherSideOfSecurity(MotionEvent ev) {
+        return mViewMode instanceof SidedSecurityMode
+                && ((SidedSecurityMode) mViewMode).isTouchOnTheOtherSideOfSecurity(ev);
     }
 
     public void onPause() {
@@ -439,6 +456,10 @@
                 .anyMatch(listener -> listener.onTouchEvent(event))
                 || super.onTouchEvent(event);
 
+        // double tap detector should be called after listeners handle touches as listeners are
+        // helping with ignoring falsing. Otherwise falsing will be activated for some double taps
+        mDoubleTapDetector.onTouchEvent(event);
+
         switch (action) {
             case MotionEvent.ACTION_MOVE:
                 mVelocityTracker.addMovement(event);
@@ -475,15 +496,26 @@
                 if (mSwipeListener != null) {
                     mSwipeListener.onSwipeUp();
                 }
-            } else {
-                if (!mIsDragging) {
-                    mViewMode.handleTap(event);
-                }
             }
         }
         return true;
     }
 
+    private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
+        @Override
+        public boolean onDoubleTap(MotionEvent e) {
+            return handleDoubleTap(e);
+        }
+    }
+
+    @VisibleForTesting boolean handleDoubleTap(MotionEvent e) {
+        if (!mIsDragging) {
+            mViewMode.handleDoubleTap(e);
+            return true;
+        }
+        return false;
+    }
+
     void addMotionEventListener(Gefingerpoken listener) {
         mMotionEventListeners.add(listener);
     }
@@ -736,8 +768,8 @@
         /** Alter the ViewFlipper position, based upon a touch outside of it */
         default void updatePositionByTouchX(float x) {};
 
-        /** A tap on the container, outside of the ViewFlipper */
-        default void handleTap(MotionEvent event) {};
+        /** A double tap on the container, outside of the ViewFlipper */
+        default void handleDoubleTap(MotionEvent event) {};
 
         /** Called when the view needs to reset or hides */
         default void reset() {};
@@ -761,6 +793,195 @@
     }
 
     /**
+     * Base class for modes which support having on left/right side of the screen, used for large
+     * screen devices
+     */
+    abstract static class SidedSecurityMode implements ViewMode {
+        @Nullable private ValueAnimator mRunningSecurityShiftAnimator;
+        private KeyguardSecurityViewFlipper mViewFlipper;
+        private ViewGroup mView;
+        private GlobalSettings mGlobalSettings;
+        private int mDefaultSideSetting;
+
+        public void init(ViewGroup v, KeyguardSecurityViewFlipper viewFlipper,
+                GlobalSettings globalSettings, boolean leftAlignedByDefault) {
+            mView = v;
+            mViewFlipper = viewFlipper;
+            mGlobalSettings = globalSettings;
+            mDefaultSideSetting =
+                    leftAlignedByDefault ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT
+                            : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT;
+        }
+
+        /**
+         * Determine if a double tap on this view is on the other side. If so, will animate
+         * positions and record the preference to always show on this side.
+         */
+        @Override
+        public void handleDoubleTap(MotionEvent event) {
+            boolean currentlyLeftAligned = isLeftAligned();
+            // Did the tap hit the "other" side of the bouncer?
+            if (isTouchOnTheOtherSideOfSecurity(event, currentlyLeftAligned)) {
+                boolean willBeLeftAligned = !currentlyLeftAligned;
+                updateSideSetting(willBeLeftAligned);
+
+                int keyguardState = willBeLeftAligned
+                        ? SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SWITCH_LEFT
+                        : SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SWITCH_RIGHT;
+                SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, keyguardState);
+
+                updateSecurityViewLocation(willBeLeftAligned, /* animate= */ true);
+            }
+        }
+
+        private boolean isTouchOnTheOtherSideOfSecurity(MotionEvent ev, boolean leftAligned) {
+            float x = ev.getX();
+            return (leftAligned && (x > mView.getWidth() / 2f))
+                    || (!leftAligned && (x < mView.getWidth() / 2f));
+        }
+
+        public boolean isTouchOnTheOtherSideOfSecurity(MotionEvent ev) {
+            return isTouchOnTheOtherSideOfSecurity(ev, isLeftAligned());
+        }
+
+        protected abstract void updateSecurityViewLocation(boolean leftAlign, boolean animate);
+
+        protected void translateSecurityViewLocation(boolean leftAlign, boolean animate) {
+            translateSecurityViewLocation(leftAlign, animate, i -> {});
+        }
+
+        /**
+         * Moves the inner security view to the correct location with animation. This is triggered
+         * when the user double taps on the side of the screen that is not currently occupied by
+         * the security view.
+         */
+        protected void translateSecurityViewLocation(boolean leftAlign, boolean animate,
+                Consumer<Float> securityAlphaListener) {
+            if (mRunningSecurityShiftAnimator != null) {
+                mRunningSecurityShiftAnimator.cancel();
+                mRunningSecurityShiftAnimator = null;
+            }
+
+            int targetTranslation = leftAlign
+                    ? 0 : mView.getMeasuredWidth() - mViewFlipper.getWidth();
+
+            if (animate) {
+                // This animation is a bit fun to implement. The bouncer needs to move, and fade
+                // in/out at the same time. The issue is, the bouncer should only move a short
+                // amount (120dp or so), but obviously needs to go from one side of the screen to
+                // the other. This needs a pretty custom animation.
+                //
+                // This works as follows. It uses a ValueAnimation to simply drive the animation
+                // progress. This animator is responsible for both the translation of the bouncer,
+                // and the current fade. It will fade the bouncer out while also moving it along the
+                // 120dp path. Once the bouncer is fully faded out though, it will "snap" the
+                // bouncer closer to its destination, then fade it back in again. The effect is that
+                // the bouncer will move from 0 -> X while fading out, then
+                // (destination - X) -> destination while fading back in again.
+                // TODO(b/208250221): Make this animation properly abortable.
+                Interpolator positionInterpolator = AnimationUtils.loadInterpolator(
+                        mView.getContext(), android.R.interpolator.fast_out_extra_slow_in);
+                Interpolator fadeOutInterpolator = Interpolators.FAST_OUT_LINEAR_IN;
+                Interpolator fadeInInterpolator = Interpolators.LINEAR_OUT_SLOW_IN;
+
+                mRunningSecurityShiftAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
+                mRunningSecurityShiftAnimator.setDuration(SECURITY_SHIFT_ANIMATION_DURATION_MS);
+                mRunningSecurityShiftAnimator.setInterpolator(Interpolators.LINEAR);
+
+                int initialTranslation = (int) mViewFlipper.getTranslationX();
+                int totalTranslation = (int) mView.getResources().getDimension(
+                        R.dimen.security_shift_animation_translation);
+
+                final boolean shouldRestoreLayerType = mViewFlipper.hasOverlappingRendering()
+                        && mViewFlipper.getLayerType() != View.LAYER_TYPE_HARDWARE;
+                if (shouldRestoreLayerType) {
+                    mViewFlipper.setLayerType(View.LAYER_TYPE_HARDWARE, /* paint= */null);
+                }
+
+                float initialAlpha = mViewFlipper.getAlpha();
+
+                mRunningSecurityShiftAnimator.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        mRunningSecurityShiftAnimator = null;
+                    }
+                });
+                mRunningSecurityShiftAnimator.addUpdateListener(animation -> {
+                    float switchPoint = SECURITY_SHIFT_ANIMATION_FADE_OUT_PROPORTION;
+                    boolean isFadingOut = animation.getAnimatedFraction() < switchPoint;
+
+                    int currentTranslation = (int) (positionInterpolator.getInterpolation(
+                            animation.getAnimatedFraction()) * totalTranslation);
+                    int translationRemaining = totalTranslation - currentTranslation;
+
+                    // Flip the sign if we're going from right to left.
+                    if (leftAlign) {
+                        currentTranslation = -currentTranslation;
+                        translationRemaining = -translationRemaining;
+                    }
+
+                    float opacity;
+                    if (isFadingOut) {
+                        // The bouncer fades out over the first X%.
+                        float fadeOutFraction = MathUtils.constrainedMap(
+                                /* rangeMin= */1.0f,
+                                /* rangeMax= */0.0f,
+                                /* valueMin= */0.0f,
+                                /* valueMax= */switchPoint,
+                                animation.getAnimatedFraction());
+                        opacity = fadeOutInterpolator.getInterpolation(fadeOutFraction);
+
+                        // When fading out, the alpha needs to start from the initial opacity of the
+                        // view flipper, otherwise we get a weird bit of jank as it ramps back to
+                        // 100%.
+                        mViewFlipper.setAlpha(opacity * initialAlpha);
+
+                        // Animate away from the source.
+                        mViewFlipper.setTranslationX(initialTranslation + currentTranslation);
+                    } else {
+                        // And in again over the remaining (100-X)%.
+                        float fadeInFraction = MathUtils.constrainedMap(
+                                /* rangeMin= */0.0f,
+                                /* rangeMax= */1.0f,
+                                /* valueMin= */switchPoint,
+                                /* valueMax= */1.0f,
+                                animation.getAnimatedFraction());
+
+                        opacity = fadeInInterpolator.getInterpolation(fadeInFraction);
+                        mViewFlipper.setAlpha(opacity);
+
+                        // Fading back in, animate towards the destination.
+                        mViewFlipper.setTranslationX(targetTranslation - translationRemaining);
+                    }
+                    securityAlphaListener.accept(opacity);
+
+                    if (animation.getAnimatedFraction() == 1.0f && shouldRestoreLayerType) {
+                        mViewFlipper.setLayerType(View.LAYER_TYPE_NONE, /* paint= */null);
+                    }
+                });
+
+                mRunningSecurityShiftAnimator.start();
+            } else {
+                mViewFlipper.setTranslationX(targetTranslation);
+            }
+        }
+
+
+        boolean isLeftAligned() {
+            return mGlobalSettings.getInt(Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
+                    mDefaultSideSetting)
+                    == Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT;
+        }
+
+        protected void updateSideSetting(boolean leftAligned) {
+            mGlobalSettings.putInt(
+                    Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
+                    leftAligned ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT
+                            : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT);
+        }
+    }
+
+    /**
      * Default bouncer is centered within the space
      */
     static class DefaultViewMode implements ViewMode {
@@ -792,7 +1013,7 @@
      * User switcher mode will display both the current user icon as well as
      * a user switcher, in both portrait and landscape modes.
      */
-    static class UserSwitcherViewMode implements ViewMode {
+    static class UserSwitcherViewMode extends SidedSecurityMode {
         private ViewGroup mView;
         private ViewGroup mUserSwitcherViewGroup;
         private KeyguardSecurityViewFlipper mViewFlipper;
@@ -804,11 +1025,15 @@
         private UserSwitcherController.UserSwitchCallback mUserSwitchCallback =
                 this::setupUserSwitcher;
 
+        private float mAnimationLastAlpha = 1f;
+        private boolean mAnimationWaitsToShift = true;
+
         @Override
         public void init(@NonNull ViewGroup v, @NonNull GlobalSettings globalSettings,
                 @NonNull KeyguardSecurityViewFlipper viewFlipper,
                 @NonNull FalsingManager falsingManager,
                 @NonNull UserSwitcherController userSwitcherController) {
+            init(v, viewFlipper, globalSettings, /* leftAlignedByDefault= */false);
             mView = v;
             mViewFlipper = viewFlipper;
             mFalsingManager = falsingManager;
@@ -822,9 +1047,7 @@
                         true);
                 mUserSwitcherViewGroup =  mView.findViewById(R.id.keyguard_bouncer_user_switcher);
             }
-
             updateSecurityViewLocation();
-
             mUserSwitcher = mView.findViewById(R.id.user_switcher_header);
             setupUserSwitcher();
             mUserSwitcherController.addUserSwitchCallback(mUserSwitchCallback);
@@ -1020,18 +1243,65 @@
 
         @Override
         public void updateSecurityViewLocation() {
-            int yTrans = mResources.getDimensionPixelSize(R.dimen.bouncer_user_switcher_y_trans);
+            updateSecurityViewLocation(isLeftAligned(), /* animate= */false);
+        }
 
+        public void updateSecurityViewLocation(boolean leftAlign, boolean animate) {
+            setYTranslation();
+            setGravity();
+            setXTranslation(leftAlign, animate);
+        }
+
+        private void setXTranslation(boolean leftAlign, boolean animate) {
             if (mResources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
-                updateViewGravity(mViewFlipper, Gravity.CENTER_HORIZONTAL);
-                updateViewGravity(mUserSwitcherViewGroup, Gravity.CENTER_HORIZONTAL);
+                mUserSwitcherViewGroup.setTranslationX(0);
+                mViewFlipper.setTranslationX(0);
+            } else {
+                int switcherTargetTranslation = leftAlign
+                        ? mView.getMeasuredWidth() - mViewFlipper.getWidth() : 0;
+                if (animate) {
+                    mAnimationWaitsToShift = true;
+                    mAnimationLastAlpha = 1f;
+                    translateSecurityViewLocation(leftAlign, animate, securityAlpha -> {
+                        // During the animation security view fades out - alpha goes from 1 to
+                        // (almost) 0 - and then fades in - alpha grows back to 1.
+                        // If new alpha is bigger than previous one it means we're at inflection
+                        // point and alpha is zero or almost zero. That's when we want to do
+                        // translation of user switcher, so that it's not visible to the user.
+                        boolean fullyFadeOut = securityAlpha == 0.0f
+                                || securityAlpha > mAnimationLastAlpha;
+                        if (fullyFadeOut && mAnimationWaitsToShift) {
+                            mUserSwitcherViewGroup.setTranslationX(switcherTargetTranslation);
+                            mAnimationWaitsToShift = false;
+                        }
+                        mUserSwitcherViewGroup.setAlpha(securityAlpha);
+                        mAnimationLastAlpha = securityAlpha;
+                    });
+                } else {
+                    translateSecurityViewLocation(leftAlign, animate);
+                    mUserSwitcherViewGroup.setTranslationX(switcherTargetTranslation);
+                }
+            }
 
+        }
+
+        private void setGravity() {
+            if (mResources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+                updateViewGravity(mUserSwitcherViewGroup, Gravity.CENTER_HORIZONTAL);
+                updateViewGravity(mViewFlipper, Gravity.CENTER_HORIZONTAL);
+            } else {
+                // horizontal gravity is the same because we translate these views anyway
+                updateViewGravity(mViewFlipper, Gravity.LEFT | Gravity.BOTTOM);
+                updateViewGravity(mUserSwitcherViewGroup, Gravity.LEFT | Gravity.CENTER_VERTICAL);
+            }
+        }
+
+        private void setYTranslation() {
+            int yTrans = mResources.getDimensionPixelSize(R.dimen.bouncer_user_switcher_y_trans);
+            if (mResources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                 mUserSwitcherViewGroup.setTranslationY(yTrans);
                 mViewFlipper.setTranslationY(-yTrans);
             } else {
-                updateViewGravity(mViewFlipper, Gravity.RIGHT | Gravity.BOTTOM);
-                updateViewGravity(mUserSwitcherViewGroup, Gravity.LEFT | Gravity.CENTER_VERTICAL);
-
                 // Attempt to reposition a bit higher to make up for this frame being a bit lower
                 // on the device
                 mUserSwitcherViewGroup.setTranslationY(-yTrans);
@@ -1050,20 +1320,18 @@
      * Logic to enabled one-handed bouncer mode. Supports animating the bouncer
      * between alternate sides of the display.
      */
-    static class OneHandedViewMode implements ViewMode {
-        @Nullable private ValueAnimator mRunningOneHandedAnimator;
+    static class OneHandedViewMode extends SidedSecurityMode {
         private ViewGroup mView;
         private KeyguardSecurityViewFlipper mViewFlipper;
-        private GlobalSettings mGlobalSettings;
 
         @Override
         public void init(@NonNull ViewGroup v, @NonNull GlobalSettings globalSettings,
                 @NonNull KeyguardSecurityViewFlipper viewFlipper,
                 @NonNull FalsingManager falsingManager,
                 @NonNull UserSwitcherController userSwitcherController) {
+            init(v, viewFlipper, globalSettings, /* leftAlignedByDefault= */true);
             mView = v;
             mViewFlipper = viewFlipper;
-            mGlobalSettings = globalSettings;
 
             updateSecurityViewGravity();
             updateSecurityViewLocation(isLeftAligned(), /* animate= */false);
@@ -1097,159 +1365,13 @@
             updateSecurityViewLocation(isTouchOnLeft, /* animate= */false);
         }
 
-        boolean isLeftAligned() {
-            return mGlobalSettings.getInt(Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
-                    Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT)
-                == Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT;
-        }
-
-        private void updateSideSetting(boolean leftAligned) {
-            mGlobalSettings.putInt(
-                    Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
-                    leftAligned ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT
-                    : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT);
-        }
-
-        /**
-         * Determine if a tap on this view is on the other side. If so, will animate positions
-         * and record the preference to always show on this side.
-         */
-        @Override
-        public void handleTap(MotionEvent event) {
-            float x = event.getX();
-            boolean currentlyLeftAligned = isLeftAligned();
-            // Did the tap hit the "other" side of the bouncer?
-            if ((currentlyLeftAligned && (x > mView.getWidth() / 2f))
-                    || (!currentlyLeftAligned && (x < mView.getWidth() / 2f))) {
-
-                boolean willBeLeftAligned = !currentlyLeftAligned;
-                updateSideSetting(willBeLeftAligned);
-
-                int keyguardState = willBeLeftAligned
-                        ? SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SWITCH_LEFT
-                        : SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SWITCH_RIGHT;
-                SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, keyguardState);
-
-                updateSecurityViewLocation(willBeLeftAligned, true /* animate */);
-            }
-        }
-
         @Override
         public void updateSecurityViewLocation() {
             updateSecurityViewLocation(isLeftAligned(), /* animate= */false);
         }
 
-        /**
-         * Moves the inner security view to the correct location (in one handed mode) with
-         * animation. This is triggered when the user taps on the side of the screen that is not
-         * currently occupied by the security view.
-         */
-        private void updateSecurityViewLocation(boolean leftAlign, boolean animate) {
-            if (mRunningOneHandedAnimator != null) {
-                mRunningOneHandedAnimator.cancel();
-                mRunningOneHandedAnimator = null;
-            }
-
-            int targetTranslation = leftAlign
-                    ? 0 : (int) (mView.getMeasuredWidth() - mViewFlipper.getWidth());
-
-            if (animate) {
-                // This animation is a bit fun to implement. The bouncer needs to move, and fade
-                // in/out at the same time. The issue is, the bouncer should only move a short
-                // amount (120dp or so), but obviously needs to go from one side of the screen to
-                // the other. This needs a pretty custom animation.
-                //
-                // This works as follows. It uses a ValueAnimation to simply drive the animation
-                // progress. This animator is responsible for both the translation of the bouncer,
-                // and the current fade. It will fade the bouncer out while also moving it along the
-                // 120dp path. Once the bouncer is fully faded out though, it will "snap" the
-                // bouncer closer to its destination, then fade it back in again. The effect is that
-                // the bouncer will move from 0 -> X while fading out, then
-                // (destination - X) -> destination while fading back in again.
-                // TODO(b/208250221): Make this animation properly abortable.
-                Interpolator positionInterpolator = AnimationUtils.loadInterpolator(
-                        mView.getContext(), android.R.interpolator.fast_out_extra_slow_in);
-                Interpolator fadeOutInterpolator = Interpolators.FAST_OUT_LINEAR_IN;
-                Interpolator fadeInInterpolator = Interpolators.LINEAR_OUT_SLOW_IN;
-
-                mRunningOneHandedAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
-                mRunningOneHandedAnimator.setDuration(BOUNCER_HANDEDNESS_ANIMATION_DURATION_MS);
-                mRunningOneHandedAnimator.setInterpolator(Interpolators.LINEAR);
-
-                int initialTranslation = (int) mViewFlipper.getTranslationX();
-                int totalTranslation = (int) mView.getResources().getDimension(
-                        R.dimen.one_handed_bouncer_move_animation_translation);
-
-                final boolean shouldRestoreLayerType = mViewFlipper.hasOverlappingRendering()
-                        && mViewFlipper.getLayerType() != View.LAYER_TYPE_HARDWARE;
-                if (shouldRestoreLayerType) {
-                    mViewFlipper.setLayerType(View.LAYER_TYPE_HARDWARE, /* paint= */null);
-                }
-
-                float initialAlpha = mViewFlipper.getAlpha();
-
-                mRunningOneHandedAnimator.addListener(new AnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationEnd(Animator animation) {
-                            mRunningOneHandedAnimator = null;
-                        }
-                    });
-                mRunningOneHandedAnimator.addUpdateListener(animation -> {
-                    float switchPoint = BOUNCER_HANDEDNESS_ANIMATION_FADE_OUT_PROPORTION;
-                    boolean isFadingOut = animation.getAnimatedFraction() < switchPoint;
-
-                    int currentTranslation = (int) (positionInterpolator.getInterpolation(
-                            animation.getAnimatedFraction()) * totalTranslation);
-                    int translationRemaining = totalTranslation - currentTranslation;
-
-                    // Flip the sign if we're going from right to left.
-                    if (leftAlign) {
-                        currentTranslation = -currentTranslation;
-                        translationRemaining = -translationRemaining;
-                    }
-
-                    if (isFadingOut) {
-                        // The bouncer fades out over the first X%.
-                        float fadeOutFraction = MathUtils.constrainedMap(
-                                /* rangeMin= */1.0f,
-                                /* rangeMax= */0.0f,
-                                /* valueMin= */0.0f,
-                                /* valueMax= */switchPoint,
-                                animation.getAnimatedFraction());
-                        float opacity = fadeOutInterpolator.getInterpolation(fadeOutFraction);
-
-                        // When fading out, the alpha needs to start from the initial opacity of the
-                        // view flipper, otherwise we get a weird bit of jank as it ramps back to
-                        // 100%.
-                        mViewFlipper.setAlpha(opacity * initialAlpha);
-
-                        // Animate away from the source.
-                        mViewFlipper.setTranslationX(initialTranslation + currentTranslation);
-                    } else {
-                        // And in again over the remaining (100-X)%.
-                        float fadeInFraction = MathUtils.constrainedMap(
-                                /* rangeMin= */0.0f,
-                                /* rangeMax= */1.0f,
-                                /* valueMin= */switchPoint,
-                                /* valueMax= */1.0f,
-                                animation.getAnimatedFraction());
-
-                        float opacity = fadeInInterpolator.getInterpolation(fadeInFraction);
-                        mViewFlipper.setAlpha(opacity);
-
-                        // Fading back in, animate towards the destination.
-                        mViewFlipper.setTranslationX(targetTranslation - translationRemaining);
-                    }
-
-                    if (animation.getAnimatedFraction() == 1.0f && shouldRestoreLayerType) {
-                        mViewFlipper.setLayerType(View.LAYER_TYPE_NONE, /* paint= */null);
-                    }
-                });
-
-                mRunningOneHandedAnimator.start();
-            } else {
-                mViewFlipper.setTranslationX(targetTranslation);
-            }
+        protected void updateSecurityViewLocation(boolean leftAlign, boolean animate) {
+            translateSecurityViewLocation(leftAlign, animate);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 19a2d9e..61e2624 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -116,12 +116,8 @@
                 // If we're in one handed mode, the user can tap on the opposite side of the screen
                 // to move the bouncer across. In that case, inhibit the falsing (otherwise the taps
                 // to move the bouncer to each screen side can end up closing it instead).
-                if (mView.getMode() == KeyguardSecurityContainer.MODE_ONE_HANDED) {
-                    boolean isLeftAligned = mView.isOneHandedModeLeftAligned();
-                    if ((isLeftAligned && ev.getX() > mView.getWidth() / 2f)
-                            || (!isLeftAligned && ev.getX() <= mView.getWidth() / 2f)) {
-                        mFalsingCollector.avoidGesture();
-                    }
+                if (mView.isTouchOnTheOtherSideOfSecurity(ev)) {
+                    mFalsingCollector.avoidGesture();
                 }
 
                 if (mTouchDown != null) {
@@ -169,8 +165,8 @@
 
         public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) {
             int bouncerSide = SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__DEFAULT;
-            if (mView.getMode() == KeyguardSecurityContainer.MODE_ONE_HANDED) {
-                bouncerSide = mView.isOneHandedModeLeftAligned()
+            if (mView.isSidedSecurityMode()) {
+                bouncerSide = mView.isSecurityLeftAligned()
                         ? SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__LEFT
                         : SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__RIGHT;
             }
@@ -367,8 +363,8 @@
     public void onResume(int reason) {
         if (mCurrentSecurityMode != SecurityMode.None) {
             int state = SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN;
-            if (mView.getMode() == KeyguardSecurityContainer.MODE_ONE_HANDED) {
-                state = mView.isOneHandedModeLeftAligned()
+            if (mView.isSidedSecurityMode()) {
+                state = mView.isSecurityLeftAligned()
                         ? SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN_LEFT
                         : SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN_RIGHT;
             }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
index 47df70b..2f6fa14 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -16,6 +16,8 @@
 
 package com.android.keyguard;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.annotation.NonNull;
 import android.app.AlertDialog;
 import android.app.AlertDialog.Builder;
@@ -241,10 +243,9 @@
             displayMessage = mView.getResources().getString(
                     R.string.kg_password_wrong_pin_code_pukked);
         } else if (attemptsRemaining > 0) {
-            msgId = isDefault ? R.plurals.kg_password_default_pin_message :
-                    R.plurals.kg_password_wrong_pin_code;
-            displayMessage = mView.getResources()
-                    .getQuantityString(msgId, attemptsRemaining, attemptsRemaining);
+            msgId = isDefault ? R.string.kg_password_default_pin_message :
+                    R.string.kg_password_wrong_pin_code;
+            displayMessage = icuMessageFormat(mView.getResources(), msgId, attemptsRemaining);
         } else {
             msgId = isDefault ? R.string.kg_sim_pin_instructions : R.string.kg_password_pin_failed;
             displayMessage = mView.getResources().getString(msgId);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index 760c2cc..c0971bf 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -16,6 +16,8 @@
 
 package com.android.keyguard;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -57,10 +59,9 @@
         if (attemptsRemaining == 0) {
             displayMessage = getContext().getString(R.string.kg_password_wrong_puk_code_dead);
         } else if (attemptsRemaining > 0) {
-            int msgId = isDefault ? R.plurals.kg_password_default_puk_message :
-                    R.plurals.kg_password_wrong_puk_code;
-            displayMessage = getContext().getResources()
-                    .getQuantityString(msgId, attemptsRemaining, attemptsRemaining);
+            int msgId = isDefault ? R.string.kg_password_default_puk_message :
+                    R.string.kg_password_wrong_puk_code;
+            displayMessage = icuMessageFormat(getResources(), msgId, attemptsRemaining);
         } else {
             int msgId = isDefault ? R.string.kg_puk_enter_puk_hint :
                     R.string.kg_password_puk_failed;
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResetOrExitSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResetOrExitSessionReceiver.java
new file mode 100644
index 0000000..fd84543
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/GuestResetOrExitSessionReceiver.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.qs.QSUserSwitcherEvent;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
+
+import javax.inject.Inject;
+
+import dagger.assisted.Assisted;
+import dagger.assisted.AssistedFactory;
+import dagger.assisted.AssistedInject;
+
+/**
+ * Manages handling of guest session persistent notification
+ * and actions to reset guest or exit guest session
+ */
+public final class GuestResetOrExitSessionReceiver extends BroadcastReceiver {
+
+    private static final String TAG = GuestResetOrExitSessionReceiver.class.getSimpleName();
+
+    /**
+     * Broadcast sent to the system when guest user needs to be reset.
+     * This is only sent to registered receivers, not manifest receivers.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_GUEST_RESET = "android.intent.action.GUEST_RESET";
+
+    /**
+     * Broadcast sent to the system when guest user needs to exit.
+     * This is only sent to registered receivers, not manifest receivers.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_GUEST_EXIT = "android.intent.action.GUEST_EXIT";
+
+    public AlertDialog mExitSessionDialog;
+    public AlertDialog mResetSessionDialog;
+    private final UserTracker mUserTracker;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+    private final ResetSessionDialog.Factory mResetSessionDialogFactory;
+    private final ExitSessionDialog.Factory mExitSessionDialogFactory;
+
+    @Inject
+    public GuestResetOrExitSessionReceiver(UserTracker userTracker,
+            BroadcastDispatcher broadcastDispatcher,
+            ResetSessionDialog.Factory resetSessionDialogFactory,
+            ExitSessionDialog.Factory exitSessionDialogFactory) {
+        mUserTracker = userTracker;
+        mBroadcastDispatcher = broadcastDispatcher;
+        mResetSessionDialogFactory = resetSessionDialogFactory;
+        mExitSessionDialogFactory = exitSessionDialogFactory;
+    }
+
+    /**
+     * Register this receiver with the {@link BroadcastDispatcher}
+     */
+    public void register() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ACTION_GUEST_RESET);
+        intentFilter.addAction(ACTION_GUEST_EXIT);
+        mBroadcastDispatcher.registerReceiver(this, intentFilter, null /* handler */,
+                                             UserHandle.SYSTEM);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+
+        cancelResetDialog();
+        cancelExitDialog();
+
+        UserInfo currentUser = mUserTracker.getUserInfo();
+        if (!currentUser.isGuest()) {
+            return;
+        }
+
+        if (ACTION_GUEST_RESET.equals(action)) {
+            mResetSessionDialog = mResetSessionDialogFactory.create(currentUser.id);
+            mResetSessionDialog.show();
+        } else if (ACTION_GUEST_EXIT.equals(action)) {
+            mExitSessionDialog = mExitSessionDialogFactory.create(currentUser.id,
+                        currentUser.isEphemeral());
+            mExitSessionDialog.show();
+        }
+    }
+
+    private void cancelResetDialog() {
+        if (mResetSessionDialog != null && mResetSessionDialog.isShowing()) {
+            mResetSessionDialog.cancel();
+            mResetSessionDialog = null;
+        }
+    }
+
+    private void cancelExitDialog() {
+        if (mExitSessionDialog != null && mExitSessionDialog.isShowing()) {
+            mExitSessionDialog.cancel();
+            mExitSessionDialog = null;
+        }
+    }
+
+    /**
+     * Dialog shown when asking for confirmation before
+     * reset and restart of guest user.
+     */
+    public static final class ResetSessionDialog extends SystemUIDialog implements
+            DialogInterface.OnClickListener {
+
+        private final UserSwitcherController mUserSwitcherController;
+        private final UiEventLogger mUiEventLogger;
+        private final int mUserId;
+
+        /** Factory class to create guest reset dialog instance */
+        @AssistedFactory
+        public interface Factory {
+            /** Create a guest reset dialog instance */
+            ResetSessionDialog create(int userId);
+        }
+
+        @AssistedInject
+        ResetSessionDialog(Context context,
+                UserSwitcherController userSwitcherController,
+                UiEventLogger uiEventLogger,
+                @Assisted int userId) {
+            super(context);
+
+            setTitle(com.android.settingslib.R.string.guest_reset_and_restart_dialog_title);
+            setMessage(context.getString(
+                        com.android.settingslib.R.string.guest_reset_and_restart_dialog_message));
+            setButton(DialogInterface.BUTTON_NEUTRAL,
+                    context.getString(android.R.string.cancel), this);
+            setButton(DialogInterface.BUTTON_POSITIVE,
+                    context.getString(
+                        com.android.settingslib.R.string.guest_reset_guest_confirm_button), this);
+            setCanceledOnTouchOutside(false);
+
+            mUserSwitcherController = userSwitcherController;
+            mUiEventLogger = uiEventLogger;
+            mUserId = userId;
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            if (which == DialogInterface.BUTTON_POSITIVE) {
+                mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE);
+                mUserSwitcherController.removeGuestUser(mUserId, UserHandle.USER_NULL);
+            } else if (which == DialogInterface.BUTTON_NEUTRAL) {
+                cancel();
+            }
+        }
+    }
+
+    /**
+     * Dialog shown when asking for confirmation before
+     * exit of guest user.
+     */
+    public static final class ExitSessionDialog extends SystemUIDialog implements
+            DialogInterface.OnClickListener {
+
+        private final UserSwitcherController mUserSwitcherController;
+        private final int mUserId;
+        private boolean mIsEphemeral;
+
+        /** Factory class to create guest exit dialog instance */
+        @AssistedFactory
+        public interface Factory {
+            /** Create a guest exit dialog instance */
+            ExitSessionDialog create(int userId, boolean isEphemeral);
+        }
+
+        @AssistedInject
+        ExitSessionDialog(Context context,
+                UserSwitcherController userSwitcherController,
+                @Assisted int userId,
+                @Assisted boolean isEphemeral) {
+            super(context);
+
+            if (isEphemeral) {
+                setTitle(context.getString(
+                            com.android.settingslib.R.string.guest_exit_dialog_title));
+                setMessage(context.getString(
+                            com.android.settingslib.R.string.guest_exit_dialog_message));
+                setButton(DialogInterface.BUTTON_NEUTRAL,
+                        context.getString(android.R.string.cancel), this);
+                setButton(DialogInterface.BUTTON_POSITIVE,
+                        context.getString(
+                            com.android.settingslib.R.string.guest_exit_dialog_button), this);
+            } else {
+                setTitle(context.getString(
+                            com.android.settingslib
+                                .R.string.guest_exit_dialog_title_non_ephemeral));
+                setMessage(context.getString(
+                            com.android.settingslib
+                                .R.string.guest_exit_dialog_message_non_ephemeral));
+                setButton(DialogInterface.BUTTON_NEUTRAL,
+                        context.getString(android.R.string.cancel), this);
+                setButton(DialogInterface.BUTTON_NEGATIVE,
+                        context.getString(
+                            com.android.settingslib.R.string.guest_exit_clear_data_button), this);
+                setButton(DialogInterface.BUTTON_POSITIVE,
+                        context.getString(
+                            com.android.settingslib.R.string.guest_exit_save_data_button), this);
+            }
+            setCanceledOnTouchOutside(false);
+
+            mUserSwitcherController = userSwitcherController;
+            mUserId = userId;
+            mIsEphemeral = isEphemeral;
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            if (mIsEphemeral) {
+                if (which == DialogInterface.BUTTON_POSITIVE) {
+                    // Ephemeral guest: exit guest, guest is removed by the system
+                    // on exit, since its marked ephemeral
+                    mUserSwitcherController.exitGuestUser(mUserId, UserHandle.USER_NULL, false);
+                } else if (which == DialogInterface.BUTTON_NEUTRAL) {
+                    // Cancel clicked, do nothing
+                    cancel();
+                }
+            } else {
+                if (which == DialogInterface.BUTTON_POSITIVE) {
+                    // Non-ephemeral guest: exit guest, guest is not removed by the system
+                    // on exit, since its marked non-ephemeral
+                    mUserSwitcherController.exitGuestUser(mUserId, UserHandle.USER_NULL, false);
+                } else if (which == DialogInterface.BUTTON_NEGATIVE) {
+                    // Non-ephemeral guest: remove guest and then exit
+                    mUserSwitcherController.exitGuestUser(mUserId, UserHandle.USER_NULL, true);
+                } else if (which == DialogInterface.BUTTON_NEUTRAL) {
+                    // Cancel clicked, do nothing
+                    cancel();
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
index 9a6020f..76a7cad 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -35,12 +35,18 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.util.settings.SecureSettings;
 
+import javax.inject.Inject;
+
+import dagger.assisted.Assisted;
+import dagger.assisted.AssistedFactory;
+import dagger.assisted.AssistedInject;
+
 /**
  * Manages notification when a guest session is resumed.
  */
 public class GuestResumeSessionReceiver extends BroadcastReceiver {
 
-    private static final String TAG = "GuestResumeSessionReceiver";
+    private static final String TAG = GuestResumeSessionReceiver.class.getSimpleName();
 
     @VisibleForTesting
     public static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in";
@@ -48,27 +54,31 @@
     @VisibleForTesting
     public AlertDialog mNewSessionDialog;
     private final UserTracker mUserTracker;
-    private final UserSwitcherController mUserSwitcherController;
-    private final UiEventLogger mUiEventLogger;
     private final SecureSettings mSecureSettings;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+    private final ResetSessionDialog.Factory mResetSessionDialogFactory;
+    private final GuestSessionNotification mGuestSessionNotification;
 
-    public GuestResumeSessionReceiver(UserSwitcherController userSwitcherController,
-            UserTracker userTracker, UiEventLogger uiEventLogger,
-            SecureSettings secureSettings) {
-        mUserSwitcherController = userSwitcherController;
+    @Inject
+    public GuestResumeSessionReceiver(
+            UserTracker userTracker,
+            SecureSettings secureSettings,
+            BroadcastDispatcher broadcastDispatcher,
+            GuestSessionNotification guestSessionNotification,
+            ResetSessionDialog.Factory resetSessionDialogFactory) {
         mUserTracker = userTracker;
-        mUiEventLogger = uiEventLogger;
         mSecureSettings = secureSettings;
+        mBroadcastDispatcher = broadcastDispatcher;
+        mGuestSessionNotification = guestSessionNotification;
+        mResetSessionDialogFactory = resetSessionDialogFactory;
     }
 
     /**
      * Register this receiver with the {@link BroadcastDispatcher}
-     *
-     * @param broadcastDispatcher to register the receiver.
      */
-    public void register(BroadcastDispatcher broadcastDispatcher) {
+    public void register() {
         IntentFilter f = new IntentFilter(Intent.ACTION_USER_SWITCHED);
-        broadcastDispatcher.registerReceiver(this, f, null /* handler */, UserHandle.SYSTEM);
+        mBroadcastDispatcher.registerReceiver(this, f, null /* handler */, UserHandle.SYSTEM);
     }
 
     @Override
@@ -89,14 +99,25 @@
                 return;
             }
 
-            int notFirstLogin = mSecureSettings.getIntForUser(
+            int guestLoginState = mSecureSettings.getIntForUser(
                     SETTING_GUEST_HAS_LOGGED_IN, 0, userId);
-            if (notFirstLogin != 0) {
-                mNewSessionDialog = new ResetSessionDialog(context, mUserSwitcherController,
-                        mUiEventLogger, userId);
+
+            if (guestLoginState == 0) {
+                // set 1 to indicate, 1st login
+                guestLoginState = 1;
+                mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, guestLoginState, userId);
+            } else if (guestLoginState == 1) {
+                // set 2 to indicate, 2nd or later login
+                guestLoginState = 2;
+                mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, guestLoginState, userId);
+            }
+
+            mGuestSessionNotification.createPersistentNotification(currentUser,
+                                                                   (guestLoginState <= 1));
+
+            if (guestLoginState > 1) {
+                mNewSessionDialog = mResetSessionDialogFactory.create(userId);
                 mNewSessionDialog.show();
-            } else {
-                mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, 1, userId);
             }
         }
     }
@@ -124,10 +145,19 @@
         private final UiEventLogger mUiEventLogger;
         private final int mUserId;
 
-        ResetSessionDialog(Context context,
+
+        /** Factory class to create guest reset dialog instance */
+        @AssistedFactory
+        public interface Factory {
+            /** Create a guest reset dialog instance */
+            ResetSessionDialog create(int userId);
+        }
+
+        @AssistedInject
+        public ResetSessionDialog(Context context,
                 UserSwitcherController userSwitcherController,
                 UiEventLogger uiEventLogger,
-                int userId) {
+                @Assisted int userId) {
             super(context, false /* dismissOnDeviceLock */);
 
             setTitle(context.getString(R.string.guest_wipe_session_title));
diff --git a/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java b/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java
new file mode 100644
index 0000000..b0eaab9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.FeatureFlagUtils;
+
+import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.util.NotificationChannels;
+
+import javax.inject.Inject;
+
+/**
+ * Posts a persistent notification on entry to guest mode
+ */
+public final class GuestSessionNotification {
+
+    private static final String TAG = GuestSessionNotification.class.getSimpleName();
+
+    private final Context mContext;
+    private final NotificationManager mNotificationManager;
+
+    @Inject
+    public GuestSessionNotification(Context context,
+            NotificationManager notificationManager) {
+        mContext = context;
+        mNotificationManager = notificationManager;
+    }
+
+    private void overrideNotificationAppName(Notification.Builder notificationBuilder) {
+        final Bundle extras = new Bundle();
+        String appName = mContext.getString(R.string.guest_notification_app_name);
+
+        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, appName);
+
+        notificationBuilder.addExtras(extras);
+    }
+
+    void createPersistentNotification(UserInfo userInfo, boolean isGuestFirstLogin) {
+        if (!FeatureFlagUtils.isEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_GUEST_MODE_UX_CHANGES)
+                || !userInfo.isGuest()) {
+            // we create a persistent notification only if enabled and only for guests
+            return;
+        }
+        String contentText;
+        if (userInfo.isEphemeral()) {
+            contentText = mContext.getString(R.string.guest_notification_ephemeral);
+        } else if (isGuestFirstLogin) {
+            contentText = mContext.getString(R.string.guest_notification_non_ephemeral);
+        } else {
+            contentText = mContext.getString(
+                            R.string.guest_notification_non_ephemeral_non_first_login);
+        }
+
+        final Intent guestExitIntent = new Intent(
+                        GuestResetOrExitSessionReceiver.ACTION_GUEST_EXIT);
+        final Intent userSettingsIntent = new Intent(Settings.ACTION_USER_SETTINGS);
+
+        PendingIntent guestExitPendingIntent =
+                PendingIntent.getBroadcastAsUser(mContext, 0, guestExitIntent,
+                    PendingIntent.FLAG_IMMUTABLE,
+                    UserHandle.SYSTEM);
+
+        PendingIntent userSettingsPendingIntent =
+                PendingIntent.getActivityAsUser(mContext, 0, userSettingsIntent,
+                    PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE,
+                    null,
+                    UserHandle.of(userInfo.id));
+
+        Notification.Builder builder = new Notification.Builder(mContext,
+                                                                NotificationChannels.ALERTS)
+                .setSmallIcon(R.drawable.ic_account_circle)
+                .setContentTitle(mContext.getString(R.string.guest_notification_session_active))
+                .setContentText(contentText)
+                .setPriority(Notification.PRIORITY_DEFAULT)
+                .setOngoing(true)
+                .setContentIntent(userSettingsPendingIntent);
+
+        // we show reset button only if this is a 2nd or later login
+        if (!isGuestFirstLogin) {
+            final Intent guestResetIntent = new Intent(
+                            GuestResetOrExitSessionReceiver.ACTION_GUEST_RESET);
+
+            PendingIntent guestResetPendingIntent =
+                    PendingIntent.getBroadcastAsUser(mContext, 0, guestResetIntent,
+                        PendingIntent.FLAG_IMMUTABLE,
+                        UserHandle.SYSTEM);
+
+            builder.addAction(R.drawable.ic_sysbar_home,
+                        mContext.getString(
+                            com.android.settingslib.R.string.guest_reset_guest_confirm_button),
+                        guestResetPendingIntent);
+        }
+        builder.addAction(R.drawable.ic_sysbar_home,
+                        mContext.getString(
+                            com.android.settingslib.R.string.guest_exit_button),
+                        guestExitPendingIntent);
+
+        overrideNotificationAppName(builder);
+
+        mNotificationManager.notifyAsUser(null,
+                                         SystemMessageProto.SystemMessage.NOTE_GUEST_SESSION,
+                                         builder.build(),
+                                         UserHandle.of(userInfo.id));
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index f5084f5..2dade21 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -29,9 +29,9 @@
 import com.android.systemui.dagger.GlobalRootComponent;
 import com.android.systemui.dagger.SysUIComponent;
 import com.android.systemui.dagger.WMComponent;
-import com.android.wm.shell.dagger.WMShellConcurrencyModule;
 import com.android.systemui.navigationbar.gestural.BackGestureTfClassifierProvider;
 import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
+import com.android.wm.shell.dagger.WMShellConcurrencyModule;
 import com.android.wm.shell.transition.ShellTransitions;
 
 import java.util.Map;
@@ -114,13 +114,11 @@
             // components that shouldn't be run in the test environment
             builder = prepareSysUIComponentBuilder(builder, mWMComponent)
                     .setPip(mWMComponent.getPip())
-                    .setLegacySplitScreen(mWMComponent.getLegacySplitScreen())
                     .setSplitScreen(mWMComponent.getSplitScreen())
                     .setOneHanded(mWMComponent.getOneHanded())
                     .setBubbles(mWMComponent.getBubbles())
                     .setHideDisplayCutout(mWMComponent.getHideDisplayCutout())
                     .setShellCommandHandler(mWMComponent.getShellCommandHandler())
-                    .setAppPairs(mWMComponent.getAppPairs())
                     .setTaskViewFactory(mWMComponent.getTaskViewFactory())
                     .setTransitions(mWMComponent.getTransitions())
                     .setStartingSurface(mWMComponent.getStartingSurface())
@@ -135,13 +133,11 @@
             // is separating this logic into newly creating SystemUITestsFactory.
             builder = prepareSysUIComponentBuilder(builder, mWMComponent)
                     .setPip(Optional.ofNullable(null))
-                    .setLegacySplitScreen(Optional.ofNullable(null))
                     .setSplitScreen(Optional.ofNullable(null))
                     .setOneHanded(Optional.ofNullable(null))
                     .setBubbles(Optional.ofNullable(null))
                     .setHideDisplayCutout(Optional.ofNullable(null))
                     .setShellCommandHandler(Optional.ofNullable(null))
-                    .setAppPairs(Optional.ofNullable(null))
                     .setTaskViewFactory(Optional.ofNullable(null))
                     .setTransitions(new ShellTransitions() {})
                     .setDisplayAreaHelper(Optional.ofNullable(null))
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index bd8e44c..448b99b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -199,8 +199,9 @@
         mNotificationShadeController = notificationShadeController;
         // Saving in instance variable since to prevent GC since
         // NotificationShadeWindowController.registerCallback() only keeps weak references.
-        mNotificationShadeCallback = (keyguardShowing, keyguardOccluded, bouncerShowing, mDozing) ->
-                registerOrUnregisterDismissNotificationShadeAction();
+        mNotificationShadeCallback =
+                (keyguardShowing, keyguardOccluded, bouncerShowing, mDozing, panelExpanded) ->
+                        registerOrUnregisterDismissNotificationShadeAction();
         mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index ec4cf2f..24b8933 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -510,6 +510,7 @@
                     mKeyguardViewManager.isBouncerInTransit() ? BouncerPanelExpansionCalculator
                             .aboutToShowBouncerProgress(fraction) : fraction;
             updateAlpha();
+            updatePauseAuth();
         }
     };
 
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
new file mode 100644
index 0000000..9b7d498
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialog.java
@@ -0,0 +1,134 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.R;
+import com.android.systemui.media.MediaDataUtils;
+import com.android.systemui.media.dialog.MediaOutputDialogFactory;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+
+/**
+ * Dialog for showing le audio broadcasting dialog.
+ */
+public class BroadcastDialog extends SystemUIDialog {
+
+    private static final String TAG = "BroadcastDialog";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private Context mContext;
+    private UiEventLogger mUiEventLogger;
+    @VisibleForTesting
+    protected View mDialogView;
+    private MediaOutputDialogFactory mMediaOutputDialogFactory;
+    private String mSwitchBroadcastApp;
+    private String mOutputPackageName;
+
+    public BroadcastDialog(Context context, MediaOutputDialogFactory mediaOutputDialogFactory,
+            String switchBroadcastApp, String outputPkgName, UiEventLogger uiEventLogger) {
+        super(context);
+        if (DEBUG) {
+            Log.d(TAG, "Init BroadcastDialog");
+        }
+
+        mContext = getContext();
+        mMediaOutputDialogFactory = mediaOutputDialogFactory;
+        mSwitchBroadcastApp = switchBroadcastApp;
+        mOutputPackageName = outputPkgName;
+        mUiEventLogger = uiEventLogger;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (DEBUG) {
+            Log.d(TAG, "onCreate");
+        }
+
+        mUiEventLogger.log(BroadcastDialogEvent.BROADCAST_DIALOG_SHOW);
+        mDialogView = LayoutInflater.from(mContext).inflate(R.layout.broadcast_dialog, null);
+        final Window window = getWindow();
+        window.setContentView(mDialogView);
+
+        TextView title = mDialogView.requireViewById(R.id.dialog_title);
+        TextView subTitle = mDialogView.requireViewById(R.id.dialog_subtitle);
+        title.setText(
+                mContext.getString(R.string.bt_le_audio_broadcast_dialog_title,
+                        MediaDataUtils.getAppLabel(mContext, mOutputPackageName,
+                                mContext.getString(
+                                        R.string.bt_le_audio_broadcast_dialog_unknown_name))));
+        subTitle.setText(
+                mContext.getString(R.string.bt_le_audio_broadcast_dialog_sub_title,
+                        mSwitchBroadcastApp));
+
+        Button switchBroadcast = mDialogView.requireViewById(R.id.switch_broadcast);
+        Button changeOutput = mDialogView.requireViewById(R.id.change_output);
+        Button cancelBtn = mDialogView.requireViewById(R.id.cancel);
+        switchBroadcast.setText(mContext.getString(
+                R.string.bt_le_audio_broadcast_dialog_switch_app, mSwitchBroadcastApp), null);
+        changeOutput.setOnClickListener((view) -> {
+            mMediaOutputDialogFactory.create(mOutputPackageName, true, null);
+            dismiss();
+        });
+        cancelBtn.setOnClickListener((view) -> {
+            if (DEBUG) {
+                Log.d(TAG, "BroadcastDialog dismiss.");
+            }
+            dismiss();
+        });
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        super.onWindowFocusChanged(hasFocus);
+        if (!hasFocus && isShowing()) {
+            dismiss();
+        }
+    }
+
+    public enum BroadcastDialogEvent implements UiEventLogger.UiEventEnum {
+        @UiEvent(doc = "The Broadcast dialog became visible on the screen.")
+        BROADCAST_DIALOG_SHOW(1062);
+
+        private final int mId;
+
+        BroadcastDialogEvent(int id) {
+            mId = id;
+        }
+
+        @Override
+        public int getId() {
+            return mId;
+        }
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java
new file mode 100644
index 0000000..8a54345
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/BroadcastDialogController.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth;
+
+import android.content.Context;
+import android.view.View;
+
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.media.dialog.MediaOutputDialogFactory;
+
+import javax.inject.Inject;
+
+/**
+ * Controller to create BroadcastDialog objects.
+ */
+@SysUISingleton
+public class BroadcastDialogController {
+
+    private Context mContext;
+    private UiEventLogger mUiEventLogger;
+    private DialogLaunchAnimator mDialogLaunchAnimator;
+    private MediaOutputDialogFactory mMediaOutputDialogFactory;
+
+    @Inject
+    public BroadcastDialogController(Context context, UiEventLogger uiEventLogger,
+            DialogLaunchAnimator dialogLaunchAnimator,
+            MediaOutputDialogFactory mediaOutputDialogFactory) {
+        mContext = context;
+        mUiEventLogger = uiEventLogger;
+        mDialogLaunchAnimator = dialogLaunchAnimator;
+        mMediaOutputDialogFactory = mediaOutputDialogFactory;
+    }
+
+    public void createBroadcastDialog(String switchAppName, String outputPkgName,
+            boolean aboveStatusBar, View view) {
+        BroadcastDialog broadcastDialog = new BroadcastDialog(mContext, mMediaOutputDialogFactory,
+                switchAppName, outputPkgName, mUiEventLogger);
+        if (view != null) {
+            mDialogLaunchAnimator.showFromView(broadcastDialog, view);
+        } else {
+            broadcastDialog.show();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
index 0bc6579..a174ed0 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
@@ -28,6 +28,7 @@
 import androidx.recyclerview.widget.RecyclerView
 import com.android.systemui.R
 import com.android.systemui.controls.ControlsServiceInfo
+import com.android.systemui.util.icuMessageFormat
 import java.text.Collator
 import java.util.concurrent.Executor
 
@@ -74,8 +75,10 @@
     }
 
     override fun onCreateViewHolder(parent: ViewGroup, i: Int): Holder {
-        return Holder(layoutInflater.inflate(R.layout.controls_app_item, parent, false),
-                favoritesRenderer)
+        return Holder(
+            layoutInflater.inflate(R.layout.controls_app_item, parent, false),
+            favoritesRenderer
+        )
     }
 
     override fun getItemCount() = listOfServices.size
@@ -116,10 +119,10 @@
 
     fun renderFavoritesForComponent(component: ComponentName): String? {
         val qty = favoriteFunction(component)
-        if (qty != 0) {
-            return resources.getQuantityString(R.plurals.controls_number_of_favorites, qty, qty)
+        return if (qty != 0) {
+            icuMessageFormat(resources, R.string.controls_number_of_favorites, qty)
         } else {
-            return null
+            null
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
index 0cf3333..8ba6f1c 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
@@ -18,6 +18,8 @@
 
 import android.content.BroadcastReceiver;
 
+import com.android.systemui.GuestResetOrExitSessionReceiver;
+import com.android.systemui.GuestResumeSessionReceiver;
 import com.android.systemui.media.dialog.MediaOutputDialogReceiver;
 import com.android.systemui.people.widget.PeopleSpaceWidgetPinnedReceiver;
 import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
@@ -89,4 +91,21 @@
     public abstract BroadcastReceiver bindPeopleSpaceWidgetProvider(
             PeopleSpaceWidgetProvider broadcastReceiver);
 
+    /**
+     *
+     */
+    @Binds
+    @IntoMap
+    @ClassKey(GuestResumeSessionReceiver.class)
+    public abstract BroadcastReceiver bindGuestResumeSessionReceiver(
+            GuestResumeSessionReceiver broadcastReceiver);
+
+    /**
+     *
+     */
+    @Binds
+    @IntoMap
+    @ClassKey(GuestResetOrExitSessionReceiver.class)
+    public abstract BroadcastReceiver bindGuestResetOrExitSessionReceiver(
+            GuestResetOrExitSessionReceiver broadcastReceiver);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index cd8ca05..afc58ef 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -45,6 +45,7 @@
 import android.content.res.Resources;
 import android.hardware.SensorManager;
 import android.hardware.SensorPrivacyManager;
+import android.hardware.camera2.CameraManager;
 import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.hardware.display.ColorDisplayManager;
@@ -553,4 +554,10 @@
     static SafetyCenterManager provideSafetyCenterManager(Context context) {
         return context.getSystemService(SafetyCenterManager.class);
     }
+
+    @Provides
+    @Singleton
+    static CameraManager provideCameraManager(Context context) {
+        return context.getSystemService(CameraManager.class);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 5d34a69..3a1b129 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -39,14 +39,12 @@
 import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider;
 import com.android.wm.shell.ShellCommandHandler;
 import com.android.wm.shell.TaskViewFactory;
-import com.android.wm.shell.apppairs.AppPairs;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.compatui.CompatUI;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
 import com.android.wm.shell.draganddrop.DragAndDrop;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.recents.RecentTasks;
@@ -86,15 +84,9 @@
         Builder setPip(Optional<Pip> p);
 
         @BindsInstance
-        Builder setLegacySplitScreen(Optional<LegacySplitScreen> s);
-
-        @BindsInstance
         Builder setSplitScreen(Optional<SplitScreen> s);
 
         @BindsInstance
-        Builder setAppPairs(Optional<AppPairs> s);
-
-        @BindsInstance
         Builder setOneHanded(Optional<OneHanded> o);
 
         @BindsInstance
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
index b02074a..1570a7e 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
@@ -26,7 +26,6 @@
 import com.android.wm.shell.ShellCommandHandler;
 import com.android.wm.shell.ShellInit;
 import com.android.wm.shell.TaskViewFactory;
-import com.android.wm.shell.apppairs.AppPairs;
 import com.android.wm.shell.back.BackAnimation;
 import com.android.wm.shell.bubbles.Bubbles;
 import com.android.wm.shell.common.annotations.ShellMainThread;
@@ -37,7 +36,6 @@
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
 import com.android.wm.shell.draganddrop.DragAndDrop;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.recents.RecentTasks;
@@ -96,15 +94,9 @@
     Optional<Pip> getPip();
 
     @WMSingleton
-    Optional<LegacySplitScreen> getLegacySplitScreen();
-
-    @WMSingleton
     Optional<SplitScreen> getSplitScreen();
 
     @WMSingleton
-    Optional<AppPairs> getAppPairs();
-
-    @WMSingleton
     Optional<Bubbles> getBubbles();
 
     @WMSingleton
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 19287c1..4161cf6 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -332,6 +332,20 @@
     }
 
     /**
+     * Logs the car mode started event.
+     */
+    public void traceCarModeStarted() {
+        mLogger.logCarModeStarted();
+    }
+
+    /**
+     * Logs the car mode ended event.
+     */
+    public void traceCarModeEnded() {
+        mLogger.logCarModeEnded();
+    }
+
+    /**
      * Appends power save changes that may cause a new doze state
      * @param powerSaveActive true if power saving is active
      * @param nextState the state that we'll transition to
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
index 4c81563..4b279ec 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
@@ -105,7 +105,7 @@
             bool4 = screenOnFromTouch
         }, {
             "Fling expand=$bool1 aboveThreshold=$bool2 thresholdNeeded=$bool3 " +
-                    "screenOnFromTouch=$bool4"
+                "screenOnFromTouch=$bool4"
         })
     }
 
@@ -151,7 +151,7 @@
             long2 = triggerAt
         }, {
             "Time tick scheduledAt=${DATE_FORMAT.format(Date(long1))} " +
-                    "triggerAt=${DATE_FORMAT.format(Date(long2))}"
+                "triggerAt=${DATE_FORMAT.format(Date(long2))}"
         })
     }
 
@@ -220,7 +220,7 @@
             str1 = partUpdated
         }, {
             "Posture changed, posture=${DevicePostureController.devicePostureToString(int1)}" +
-                    " partUpdated=$str1"
+                " partUpdated=$str1"
         })
     }
 
@@ -299,6 +299,18 @@
             "Doze aod dimming scrim opacity set, opacity=$long1"
         })
     }
+
+    fun logCarModeEnded() {
+        buffer.log(TAG, INFO, {}, {
+            "Doze car mode ended"
+        })
+    }
+
+    fun logCarModeStarted() {
+        buffer.log(TAG, INFO, {}, {
+            "Doze car mode started"
+        })
+    }
 }
 
 private const val TAG = "DozeLog"
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 5779bb3..32bc9de 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -20,6 +20,8 @@
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
 
 import android.annotation.MainThread;
+import android.app.UiModeManager;
+import android.content.res.Configuration;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.os.Trace;
 import android.os.UserHandle;
@@ -33,7 +35,6 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle.Wakefulness;
 import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.util.Assert;
 import com.android.systemui.util.wakelock.WakeLock;
 
@@ -66,6 +67,8 @@
         INITIALIZED,
         /** Regular doze. Device is asleep and listening for pulse triggers. */
         DOZE,
+        /** Deep doze. Device is asleep and is not listening for pulse triggers. */
+        DOZE_SUSPEND_TRIGGERS,
         /** Always-on doze. Device is asleep, showing UI and listening for pulse triggers. */
         DOZE_AOD,
         /** Pulse has been requested. Device is awake and preparing UI */
@@ -125,6 +128,7 @@
                             : Display.STATE_ON;
                 case DOZE_AOD_PAUSED:
                 case DOZE:
+                case DOZE_SUSPEND_TRIGGERS:
                     return Display.STATE_OFF;
                 case DOZE_PULSING:
                 case DOZE_PULSING_BRIGHT:
@@ -143,26 +147,27 @@
     private final WakeLock mWakeLock;
     private final AmbientDisplayConfiguration mConfig;
     private final WakefulnessLifecycle mWakefulnessLifecycle;
-    private final BatteryController mBatteryController;
     private final DozeHost mDozeHost;
-    private Part[] mParts;
+    private final UiModeManager mUiModeManager;
+    private final DockManager mDockManager;
+    private final Part[] mParts;
 
     private final ArrayList<State> mQueuedRequests = new ArrayList<>();
     private State mState = State.UNINITIALIZED;
     private int mPulseReason;
     private boolean mWakeLockHeldForCurrentState = false;
-    private DockManager mDockManager;
 
     @Inject
     public DozeMachine(@WrappedService Service service, AmbientDisplayConfiguration config,
             WakeLock wakeLock, WakefulnessLifecycle wakefulnessLifecycle,
-            BatteryController batteryController, DozeLog dozeLog, DockManager dockManager,
+            UiModeManager uiModeManager,
+            DozeLog dozeLog, DockManager dockManager,
             DozeHost dozeHost, Part[] parts) {
         mDozeService = service;
         mConfig = config;
         mWakefulnessLifecycle = wakefulnessLifecycle;
         mWakeLock = wakeLock;
-        mBatteryController = batteryController;
+        mUiModeManager = uiModeManager;
         mDozeLog = dozeLog;
         mDockManager = dockManager;
         mDozeHost = dozeHost;
@@ -244,7 +249,7 @@
         Assert.isMainThread();
         if (isExecutingTransition()) {
             throw new IllegalStateException("Cannot get state because there were pending "
-                    + "transitions: " + mQueuedRequests.toString());
+                    + "transitions: " + mQueuedRequests);
         }
         return mState;
     }
@@ -313,11 +318,8 @@
         }
         mDozeLog.traceDozeStateSendComplete(newState);
 
-        switch (newState) {
-            case FINISH:
-                mDozeService.finish();
-                break;
-            default:
+        if (newState == State.FINISH) {
+            mDozeService.finish();
         }
     }
 
@@ -357,6 +359,12 @@
         if (mState == State.FINISH) {
             return State.FINISH;
         }
+        if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
+                && (requestedState.canPulse() || requestedState.staysAwake())) {
+            Log.i(TAG, "Doze is suppressed with all triggers disabled as car mode is active");
+            mDozeLog.traceCarModeStarted();
+            return State.DOZE_SUSPEND_TRIGGERS;
+        }
         if (mDozeHost.isAlwaysOnSuppressed() && requestedState.isAlwaysOn()) {
             Log.i(TAG, "Doze is suppressed by an app. Suppressing state: " + requestedState);
             mDozeLog.traceAlwaysOnSuppressed(requestedState, "app");
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index 83220ca..60227ee9 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -147,6 +147,7 @@
                 setLightSensorEnabled(true);
                 break;
             case DOZE:
+            case DOZE_SUSPEND_TRIGGERS:
                 setLightSensorEnabled(false);
                 resetBrightnessToDefault();
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index c8720e4..da6c163 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -183,7 +183,8 @@
                         mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
                         null /* setting */,
                         dozeParameters.getPulseOnSigMotion(),
-                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
+                        DozeLog.PULSE_REASON_SENSOR_SIGMOTION,
+                        false /* touchCoords */,
                         false /* touchscreen */),
                 new TriggerSensor(
                         mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
@@ -193,7 +194,8 @@
                         DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */,
                         false /* touchscreen */,
                         false /* ignoresSetting */,
-                        false /* requires prox */),
+                        false /* requires prox */,
+                        true /* immediatelyReRegister */),
                 new TriggerSensor(
                         findSensor(config.doubleTapSensorType()),
                         Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
@@ -211,6 +213,7 @@
                         true /* touchscreen */,
                         false /* ignoresSetting */,
                         dozeParameters.singleTapUsesProx(mDevicePosture) /* requiresProx */,
+                        true /* immediatelyReRegister */,
                         mDevicePosture),
                 new TriggerSensor(
                         findSensor(config.longPressSensorType()),
@@ -221,7 +224,8 @@
                         true /* reports touch coordinates */,
                         true /* touchscreen */,
                         false /* ignoresSetting */,
-                        dozeParameters.longPressUsesProx() /* requiresProx */),
+                        dozeParameters.longPressUsesProx() /* requiresProx */,
+                        true /* immediatelyReRegister */),
                 new TriggerSensor(
                         findSensor(config.udfpsLongPressSensorType()),
                         "doze_pulse_on_auth",
@@ -231,7 +235,8 @@
                         true /* reports touch coordinates */,
                         true /* touchscreen */,
                         false /* ignoresSetting */,
-                        dozeParameters.longPressUsesProx()),
+                        dozeParameters.longPressUsesProx(),
+                        false /* immediatelyReRegister */),
                 new PluginSensor(
                         new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
                         Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
@@ -257,7 +262,8 @@
                         false /* requiresTouchCoordinates */,
                         false /* requiresTouchscreen */,
                         false /* ignoresSetting */,
-                        false /* requiresProx */),
+                        false /* requiresProx */,
+                        true /* immediatelyReRegister */),
         };
         setProxListening(false);  // Don't immediately start listening when we register.
         mProximitySensor.register(
@@ -493,6 +499,10 @@
         private final boolean mRequiresTouchscreen;
         private final boolean mRequiresProx;
 
+        // Whether to immediately re-register this sensor after the sensor is triggered.
+        // If false, the sensor registration will be updated on the next AOD state transition.
+        private final boolean mImmediatelyReRegister;
+
         protected boolean mRequested;
         protected boolean mRegistered;
         protected boolean mDisabled;
@@ -516,7 +526,8 @@
                     reportsTouchCoordinates,
                     requiresTouchscreen,
                     false /* ignoresSetting */,
-                    false /* requiresProx */
+                    false /* requiresProx */,
+                    true /* immediatelyReRegister */
             );
         }
 
@@ -529,7 +540,8 @@
                 boolean reportsTouchCoordinates,
                 boolean requiresTouchscreen,
                 boolean ignoresSetting,
-                boolean requiresProx
+                boolean requiresProx,
+                boolean immediatelyReRegister
         ) {
             this(
                     new Sensor[]{ sensor },
@@ -541,6 +553,7 @@
                     requiresTouchscreen,
                     ignoresSetting,
                     requiresProx,
+                    immediatelyReRegister,
                     DevicePostureController.DEVICE_POSTURE_UNKNOWN
             );
         }
@@ -555,6 +568,7 @@
                 boolean requiresTouchscreen,
                 boolean ignoresSetting,
                 boolean requiresProx,
+                boolean immediatelyReRegister,
                 @DevicePostureController.DevicePostureInt int posture
         ) {
             mSensors = sensors;
@@ -567,6 +581,7 @@
             mIgnoresSetting = ignoresSetting;
             mRequiresProx = requiresProx;
             mPosture = posture;
+            mImmediatelyReRegister = immediatelyReRegister;
         }
 
         /**
@@ -702,8 +717,8 @@
                     screenY = event.values[1];
                 }
                 mSensorCallback.onSensorPulse(mPulseReason, screenX, screenY, event.values);
-                if (!mRegistered) {
-                    updateListening();  // reregister, this sensor only fires once
+                if (!mRegistered && mImmediatelyReRegister) {
+                    updateListening();
                 }
             }));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java
index 89f50ad..7ed4b35 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java
@@ -17,6 +17,7 @@
 package com.android.systemui.doze;
 
 import static android.app.UiModeManager.ACTION_ENTER_CAR_MODE;
+import static android.app.UiModeManager.ACTION_EXIT_CAR_MODE;
 
 import android.app.UiModeManager;
 import android.content.BroadcastReceiver;
@@ -96,6 +97,7 @@
                 registerBroadcastReceiver();
                 mDozeHost.addCallback(mHostCallback);
                 checkShouldImmediatelyEndDoze();
+                checkShouldImmediatelySuspendDoze();
                 break;
             case FINISH:
                 destroy();
@@ -110,11 +112,16 @@
         mDozeHost.removeCallback(mHostCallback);
     }
 
+    private void checkShouldImmediatelySuspendDoze() {
+        if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
+            mDozeLog.traceCarModeStarted();
+            mMachine.requestState(DozeMachine.State.DOZE_SUSPEND_TRIGGERS);
+        }
+    }
+
     private void checkShouldImmediatelyEndDoze() {
         String reason = null;
-        if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
-            reason = "car_mode";
-        } else if (!mDozeHost.isProvisioned()) {
+        if (!mDozeHost.isProvisioned()) {
             reason = "device_unprovisioned";
         } else if (mBiometricUnlockControllerLazy.get().hasPendingAuthentication()) {
             reason = "has_pending_auth";
@@ -141,6 +148,7 @@
             return;
         }
         IntentFilter filter = new IntentFilter(ACTION_ENTER_CAR_MODE);
+        filter.addAction(ACTION_EXIT_CAR_MODE);
         mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
         mBroadcastReceiverRegistered = true;
     }
@@ -156,9 +164,14 @@
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
-                mDozeLog.traceImmediatelyEndDoze("car_mode");
-                mMachine.requestState(DozeMachine.State.FINISH);
+            String action = intent.getAction();
+            if (ACTION_ENTER_CAR_MODE.equals(action)) {
+                mDozeLog.traceCarModeStarted();
+                mMachine.requestState(DozeMachine.State.DOZE_SUSPEND_TRIGGERS);
+            } else if (ACTION_EXIT_CAR_MODE.equals(action)) {
+                mDozeLog.traceCarModeEnded();
+                mMachine.requestState(mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)
+                        ? DozeMachine.State.DOZE_AOD : DozeMachine.State.DOZE);
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 1cc5df5..0014d6b 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -16,6 +16,10 @@
 
 package com.android.systemui.doze;
 
+import static com.android.systemui.doze.DozeMachine.State.DOZE_SUSPEND_TRIGGERS;
+import static com.android.systemui.doze.DozeMachine.State.FINISH;
+import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
+
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -437,14 +441,18 @@
 
     @Override
     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        if (oldState == DOZE_SUSPEND_TRIGGERS && (newState != FINISH
+                && newState != UNINITIALIZED)) {
+            // Register callbacks that were unregistered when we switched to
+            // DOZE_SUSPEND_TRIGGERS state.
+            registerCallbacks();
+        }
         switch (newState) {
             case INITIALIZED:
                 mAodInterruptRunnable = null;
                 sWakeDisplaySensorState = true;
-                mBroadcastReceiver.register(mBroadcastDispatcher);
-                mDockManager.addListener(mDockEventListener);
+                registerCallbacks();
                 mDozeSensors.requestTemporaryDisable();
-                mDozeHost.addCallback(mHostCallback);
                 break;
             case DOZE:
             case DOZE_AOD:
@@ -472,21 +480,36 @@
             case DOZE_PULSE_DONE:
                 mDozeSensors.requestTemporaryDisable();
                 break;
+            case DOZE_SUSPEND_TRIGGERS:
             case FINISH:
-                mBroadcastReceiver.unregister(mBroadcastDispatcher);
-                mDozeHost.removeCallback(mHostCallback);
-                mDockManager.removeListener(mDockEventListener);
-                mDozeSensors.setListening(false, false);
-                mDozeSensors.setProxListening(false);
-                mWantSensors = false;
-                mWantProxSensor = false;
-                mWantTouchScreenSensors = false;
+                stopListeningToAllTriggers();
                 break;
             default:
         }
         mDozeSensors.setListening(mWantSensors, mWantTouchScreenSensors);
     }
 
+    private void registerCallbacks() {
+        mBroadcastReceiver.register(mBroadcastDispatcher);
+        mDockManager.addListener(mDockEventListener);
+        mDozeHost.addCallback(mHostCallback);
+    }
+
+    private void unregisterCallbacks() {
+        mBroadcastReceiver.unregister(mBroadcastDispatcher);
+        mDozeHost.removeCallback(mHostCallback);
+        mDockManager.removeListener(mDockEventListener);
+    }
+
+    private void stopListeningToAllTriggers() {
+        unregisterCallbacks();
+        mDozeSensors.setListening(false, false);
+        mDozeSensors.setProxListening(false);
+        mWantSensors = false;
+        mWantProxSensor = false;
+        mWantTouchScreenSensors = false;
+    }
+
     @Override
     public void onScreenState(int state) {
         mDozeSensors.onScreenState(state);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index e568b82..70e4fa3 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -139,6 +139,7 @@
                 break;
             case DOZE:
             case DOZE_AOD_PAUSED:
+            case DOZE_SUSPEND_TRIGGERS:
                 unscheduleTimeTick();
                 break;
             case DOZE_REQUEST_PULSE:
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 74949d0..d7b7777 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -183,22 +183,22 @@
     }
 
     private void updateBurnInOffsets() {
-        int burnInOffset = mMaxBurnInOffset;
-
         // Make sure the offset starts at zero, to avoid a big jump in the overlay when it first
         // appears.
-        long millisSinceStart = System.currentTimeMillis() - mJitterStartTimeMillis;
+        final long millisSinceStart = System.currentTimeMillis() - mJitterStartTimeMillis;
+        final int burnInOffset;
         if (millisSinceStart < mMillisUntilFullJitter) {
             float lerpAmount = (float) millisSinceStart / (float) mMillisUntilFullJitter;
-            burnInOffset = Math.round(MathUtils.lerp(0f, burnInOffset, lerpAmount));
+            burnInOffset = Math.round(MathUtils.lerp(0f, mMaxBurnInOffset, lerpAmount));
+        } else {
+            burnInOffset = mMaxBurnInOffset;
         }
 
         // These translation values change slowly, and the set translation methods are idempotent,
         // so no translation occurs when the values don't change.
-        int burnInOffsetX = getBurnInOffset(burnInOffset * 2, true)
-                - burnInOffset;
-        int burnInOffsetY = getBurnInOffset(burnInOffset * 2, false)
-                - burnInOffset;
+        final int halfBurnInOffset = burnInOffset / 2;
+        final int burnInOffsetX = getBurnInOffset(burnInOffset, true) - halfBurnInOffset;
+        final int burnInOffsetY = getBurnInOffset(burnInOffset, false) - halfBurnInOffset;
         mView.setTranslationX(burnInOffsetX);
         mView.setTranslationY(burnInOffsetY);
 
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayNotificationCountProvider.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayNotificationCountProvider.java
index 6589f26..f9fc1f3 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayNotificationCountProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayNotificationCountProvider.java
@@ -20,7 +20,6 @@
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 
-import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
@@ -33,13 +32,10 @@
 import java.util.Set;
 import java.util.concurrent.Executor;
 
-import javax.inject.Inject;
-
 /***
  * {@link DreamOverlayNotificationCountProvider} provides the current notification count to
- * registered callbacks.
+ * registered callbacks. Ongoing notifications are not included in the count.
  */
-@SysUISingleton
 public class DreamOverlayNotificationCountProvider
         implements CallbackController<DreamOverlayNotificationCountProvider.Callback> {
     private final Set<String> mNotificationKeys = new HashSet<>();
@@ -49,6 +45,10 @@
         @Override
         public void onNotificationPosted(
                 StatusBarNotification sbn, NotificationListenerService.RankingMap rankingMap) {
+            if (sbn.isOngoing()) {
+                // Don't count ongoing notifications.
+                return;
+            }
             mNotificationKeys.add(sbn.getKey());
             reportNotificationCountChanged();
         }
@@ -78,7 +78,6 @@
         }
     };
 
-    @Inject
     public DreamOverlayNotificationCountProvider(
             NotificationListener notificationListener,
             @Background Executor bgExecutor) {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
index 994c630..99ca3c7 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.os.PatternMatcher;
 import android.os.RemoteException;
@@ -31,7 +32,6 @@
 import android.util.Log;
 
 import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.Main;
 
 import javax.inject.Inject;
@@ -66,23 +66,15 @@
         final int enabledState =
                 packageManager.getComponentEnabledSetting(mOverlayServiceComponent);
 
-
-        // TODO(b/204626521): We should not have to set the component enabled setting if the
-        // enabled config flag is properly applied based on the RRO.
-        if (enabledState != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
-            final int overlayState = mResources.getBoolean(R.bool.config_dreamOverlayServiceEnabled)
-                    ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
-                    : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
-
-            if (overlayState != enabledState) {
-                packageManager
-                        .setComponentEnabledSetting(mOverlayServiceComponent, overlayState, 0);
-            }
-        }
-
         // The overlay service is only registered when its component setting is enabled.
-        boolean register = packageManager.getComponentEnabledSetting(mOverlayServiceComponent)
-                == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+        boolean register = false;
+
+        try {
+            register = packageManager.getServiceInfo(mOverlayServiceComponent,
+                PackageManager.GET_META_DATA).enabled;
+        } catch (NameNotFoundException e) {
+            Log.e(TAG, "could not find dream overlay service");
+        }
 
         if (mCurrentRegisteredState == register) {
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
index fc71e2f..69e41ba 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
@@ -101,6 +101,9 @@
     public void addComplication(Complication complication) {
         mExecutor.execute(() -> {
             if (mComplications.add(complication)) {
+                if (DEBUG) {
+                    Log.d(TAG, "addComplication: added " + complication);
+                }
                 mCallbacks.stream().forEach(callback -> callback.onComplicationsChanged());
             }
         });
@@ -112,6 +115,9 @@
     public void removeComplication(Complication complication) {
         mExecutor.execute(() -> {
             if (mComplications.remove(complication)) {
+                if (DEBUG) {
+                    Log.d(TAG, "removeComplication: removed " + complication);
+                }
                 mCallbacks.stream().forEach(callback -> callback.onComplicationsChanged());
             }
         });
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
index e878b22..250313d 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
@@ -49,6 +49,7 @@
 
 import java.util.Locale;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
@@ -65,7 +66,8 @@
     private final Resources mResources;
     private final DateFormatUtil mDateFormatUtil;
     private final IndividualSensorPrivacyController mSensorPrivacyController;
-    private final DreamOverlayNotificationCountProvider mDreamOverlayNotificationCountProvider;
+    private final Optional<DreamOverlayNotificationCountProvider>
+            mDreamOverlayNotificationCountProvider;
     private final ZenModeController mZenModeController;
     private final Executor mMainExecutor;
 
@@ -125,7 +127,7 @@
             NextAlarmController nextAlarmController,
             DateFormatUtil dateFormatUtil,
             IndividualSensorPrivacyController sensorPrivacyController,
-            DreamOverlayNotificationCountProvider dreamOverlayNotificationCountProvider,
+            Optional<DreamOverlayNotificationCountProvider> dreamOverlayNotificationCountProvider,
             ZenModeController zenModeController,
             StatusBarWindowStateController statusBarWindowStateController) {
         super(view);
@@ -161,7 +163,9 @@
         mZenModeController.addCallback(mZenModeCallback);
         updatePriorityModeStatusIcon();
 
-        mDreamOverlayNotificationCountProvider.addCallback(mNotificationCountCallback);
+        mDreamOverlayNotificationCountProvider.ifPresent(
+                provider -> provider.addCallback(mNotificationCountCallback));
+
         mTouchInsetSession.addViewToTracking(mView);
     }
 
@@ -171,7 +175,8 @@
         mSensorPrivacyController.removeCallback(mSensorCallback);
         mNextAlarmController.removeCallback(mNextAlarmCallback);
         mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
-        mDreamOverlayNotificationCountProvider.removeCallback(mNotificationCountCallback);
+        mDreamOverlayNotificationCountProvider.ifPresent(
+                provider -> provider.removeCallback(mNotificationCountCallback));
         mTouchInsetSession.clear();
 
         mIsAttached = false;
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
index a83e006df..be94e50 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
@@ -26,7 +26,7 @@
 import com.android.systemui.dreams.complication.Complication;
 import com.android.systemui.dreams.complication.ComplicationLayoutParams;
 import com.android.systemui.dreams.complication.ComplicationViewModel;
-import com.android.systemui.dreams.smartspace.DreamsSmartspaceController;
+import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 
 import java.util.List;
@@ -43,7 +43,7 @@
      * SystemUI.
      */
     public static class Registrant extends CoreStartable {
-        private final DreamsSmartspaceController mSmartSpaceController;
+        private final DreamSmartspaceController mSmartSpaceController;
         private final DreamOverlayStateController mDreamOverlayStateController;
         private final SmartSpaceComplication mComplication;
 
@@ -66,7 +66,7 @@
         public Registrant(Context context,
                 DreamOverlayStateController dreamOverlayStateController,
                 SmartSpaceComplication smartSpaceComplication,
-                DreamsSmartspaceController smartSpaceController) {
+                DreamSmartspaceController smartSpaceController) {
             super(context);
             mDreamOverlayStateController = dreamOverlayStateController;
             mComplication = smartSpaceComplication;
@@ -82,6 +82,7 @@
                         mSmartSpaceController.addListener(mSmartspaceListener);
                     } else {
                         mSmartSpaceController.removeListener(mSmartspaceListener);
+                        mDreamOverlayStateController.removeComplication(mComplication);
                     }
                 }
             });
@@ -89,25 +90,30 @@
     }
 
     private static class SmartSpaceComplicationViewHolder implements ViewHolder {
+        private View mView = null;
         private static final int SMARTSPACE_COMPLICATION_WEIGHT = 10;
-        private final DreamsSmartspaceController mSmartSpaceController;
+        private final DreamSmartspaceController mSmartSpaceController;
         private final Context mContext;
 
         protected SmartSpaceComplicationViewHolder(
                 Context context,
-                DreamsSmartspaceController smartSpaceController) {
+                DreamSmartspaceController smartSpaceController) {
             mSmartSpaceController = smartSpaceController;
             mContext = context;
         }
 
         @Override
         public View getView() {
+            if (mView != null) {
+                return mView;
+            }
             final FrameLayout smartSpaceContainer = new FrameLayout(mContext);
             smartSpaceContainer.addView(
                     mSmartSpaceController.buildAndConnectView(smartSpaceContainer),
                     new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                             ViewGroup.LayoutParams.WRAP_CONTENT));
 
+            mView = smartSpaceContainer;
             return smartSpaceContainer;
         }
 
@@ -120,12 +126,12 @@
         }
     }
 
-    private final DreamsSmartspaceController mSmartSpaceController;
+    private final DreamSmartspaceController mSmartSpaceController;
     private final Context mContext;
 
     @Inject
     public SmartSpaceComplication(Context context,
-            DreamsSmartspaceController smartSpaceController) {
+            DreamSmartspaceController smartSpaceController) {
         mContext = context;
         mSmartSpaceController = smartSpaceController;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/AirQualityColorPicker.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/AirQualityColorPicker.java
new file mode 100644
index 0000000..328753f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/AirQualityColorPicker.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams.complication;
+
+import static com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.DREAM_AQI_COLOR_DEFAULT;
+import static com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.DREAM_AQI_COLOR_THRESHOLDS;
+import static com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.DREAM_AQI_COLOR_VALUES;
+
+import android.util.Log;
+
+import androidx.annotation.ColorInt;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+final class AirQualityColorPicker {
+    private static final String TAG = "AirQualityColorPicker";
+    private final int[] mThresholds;
+    private final int[] mColorValues;
+    private final int mDefaultColor;
+
+    @Inject
+    AirQualityColorPicker(@Named(DREAM_AQI_COLOR_THRESHOLDS) int[] thresholds,
+            @Named(DREAM_AQI_COLOR_VALUES) int[] colorValues,
+            @Named(DREAM_AQI_COLOR_DEFAULT) @ColorInt int defaultColor) {
+        mThresholds = thresholds;
+        mColorValues = colorValues;
+        mDefaultColor = defaultColor;
+    }
+
+    @ColorInt
+    int getColorForValue(String aqiString) {
+        int size = mThresholds.length;
+        if (mThresholds.length != mColorValues.length) {
+            size = Math.min(mThresholds.length, mColorValues.length);
+            Log.e(TAG,
+                    "Threshold size ("
+                            + mThresholds.length + ") does not match color value size ("
+                            + mColorValues.length
+                            + "). Taking the minimum, some values may be ignored.");
+
+        }
+        try {
+            final int value = Integer.parseInt(aqiString.replaceAll("[^0-9]", ""));
+            for (int i = size - 1; i >= 0; i--) {
+                if (value > mThresholds[i]) {
+                    return mColorValues[i];
+                }
+            }
+            Log.e(TAG, "No matching AQI color for value: " + value);
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "Could not read AQI value from:" + aqiString);
+        }
+        return mDefaultColor;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
index 4c0154f..fd6cfc0 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
@@ -21,6 +21,7 @@
 
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.os.Debug;
 import android.util.Log;
 import android.view.View;
 
@@ -44,7 +45,8 @@
  * a {@link ComplicationLayoutEngine}.
  */
 public class ComplicationHostViewController extends ViewController<ConstraintLayout> {
-    public static final String TAG = "ComplicationHostViewController";
+    private static final String TAG = "ComplicationHostVwCtrl";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final ComplicationLayoutEngine mLayoutEngine;
     private final LifecycleOwner mLifecycleOwner;
@@ -90,6 +92,11 @@
     }
 
     private void updateComplications(Collection<ComplicationViewModel> complications) {
+        if (DEBUG) {
+            Log.d(TAG, "updateComplications called. Callers = " + Debug.getCallers(25));
+            Log.d(TAG, "    mComplications = " + mComplications.toString());
+            Log.d(TAG, "    complications = " + complications.toString());
+        }
         final Collection<ComplicationId> ids = complications.stream()
                 .map(complicationViewModel -> complicationViewModel.getId())
                 .collect(Collectors.toSet());
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
index ded61a8..9cd149b 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
@@ -54,7 +54,7 @@
  */
 @DreamOverlayComponent.DreamOverlayScope
 public class ComplicationLayoutEngine implements Complication.VisibilityController {
-    public static final String TAG = "ComplicationLayoutEngine";
+    public static final String TAG = "ComplicationLayoutEng";
 
     /**
      * {@link ViewEntry} is an internal container, capturing information necessary for working with
@@ -529,7 +529,7 @@
      */
     public void addComplication(ComplicationId id, View view,
             ComplicationLayoutParams lp, @Complication.Category int category) {
-        Log.d(TAG, "engine: " + this + " addComplication");
+        Log.d(TAG, "@" + Integer.toHexString(this.hashCode()) + " addComplication: " + id);
 
         // If the complication is present, remove.
         if (mEntries.containsKey(id)) {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationViewModel.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationViewModel.java
index f023937..00cf58c 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationViewModel.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationViewModel.java
@@ -64,4 +64,9 @@
     public void exitDream() {
         mHost.requestExitDream();
     }
+
+    @Override
+    public String toString() {
+        return mId + "=" + mComplication.toString();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamAirQualityComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamAirQualityComplication.java
new file mode 100644
index 0000000..ba63303
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamAirQualityComplication.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams.complication;
+
+import static com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.DREAM_AQI_COMPLICATION_LAYOUT_PARAMS;
+import static com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.DREAM_AQI_COMPLICATION_VIEW;
+import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT;
+
+import android.app.smartspace.SmartspaceAction;
+import android.app.smartspace.SmartspaceTarget;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.systemui.CoreStartable;
+import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.dreams.complication.dagger.DreamAirQualityComplicationComponent;
+import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener;
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * Air quality complication which produces view holder responsible for showing AQI over dreams.
+ */
+public class DreamAirQualityComplication implements Complication {
+    // TODO(b/236024839): Move to SmartspaceTarget
+    public static final int FEATURE_AIR_QUALITY = 46;
+
+    private final DreamAirQualityComplicationComponent.Factory mComponentFactory;
+
+    @Inject
+    public DreamAirQualityComplication(
+            DreamAirQualityComplicationComponent.Factory componentFactory) {
+        mComponentFactory = componentFactory;
+    }
+
+    @Override
+    public int getRequiredTypeAvailability() {
+        return COMPLICATION_TYPE_AIR_QUALITY;
+    }
+
+    @Override
+    public ViewHolder createView(ComplicationViewModel model) {
+        return mComponentFactory.create().getViewHolder();
+    }
+
+    /**
+     * {@link CoreStartable} for registering {@link DreamAirQualityComplication} with SystemUI.
+     */
+    public static class Registrant extends CoreStartable {
+        private final DreamOverlayStateController mDreamOverlayStateController;
+        private final DreamAirQualityComplication mComplication;
+
+        /**
+         * Default constructor to register {@link DreamAirQualityComplication}.
+         */
+        @Inject
+        public Registrant(Context context,
+                DreamOverlayStateController dreamOverlayStateController,
+                DreamAirQualityComplication complication) {
+            super(context);
+            mDreamOverlayStateController = dreamOverlayStateController;
+            mComplication = complication;
+        }
+
+        @Override
+        public void start() {
+            // TODO(b/221500478): Only add complication once we have data to show.
+            mDreamOverlayStateController.addComplication(mComplication);
+        }
+    }
+
+    /**
+     * ViewHolder to contain value/logic associated with the AQI complication view.
+     */
+    public static class DreamAirQualityViewHolder implements ViewHolder {
+        private final TextView mView;
+        private final DreamAirQualityViewController mController;
+        private final ComplicationLayoutParams mLayoutParams;
+
+        @Inject
+        DreamAirQualityViewHolder(@Named(DREAM_AQI_COMPLICATION_VIEW) TextView view,
+                DreamAirQualityViewController controller,
+                @Named(DREAM_AQI_COMPLICATION_LAYOUT_PARAMS)
+                        ComplicationLayoutParams layoutParams) {
+            mView = view;
+            mLayoutParams = layoutParams;
+            mController = controller;
+            mController.init();
+        }
+
+        @Override
+        public View getView() {
+            return mView;
+        }
+
+        @Override
+        public ComplicationLayoutParams getLayoutParams() {
+            return mLayoutParams;
+        }
+    }
+
+    static class DreamAirQualityViewController extends ViewController<TextView> {
+        private final DreamSmartspaceController mSmartspaceController;
+        private final String mSmartspaceTrampolineComponent;
+        private final ActivityStarter mActivityStarter;
+        private final AirQualityColorPicker mAirQualityColorPicker;
+
+        private final SmartspaceTargetListener mSmartspaceTargetListener = targets -> {
+            final SmartspaceTarget target = targets.stream()
+                    .filter(t -> t instanceof SmartspaceTarget)
+                    .map(t -> (SmartspaceTarget) t)
+                    .filter(t -> t.getFeatureType() == FEATURE_AIR_QUALITY)
+                    .findFirst()
+                    .orElse(null);
+            updateView(target);
+        };
+
+        @Inject
+        DreamAirQualityViewController(@Named(DREAM_AQI_COMPLICATION_VIEW) TextView view,
+                DreamSmartspaceController smartspaceController,
+                @Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT)
+                        String smartspaceTrampolineComponent,
+                ActivityStarter activityStarter,
+                AirQualityColorPicker airQualityColorPicker) {
+            super(view);
+            mSmartspaceController = smartspaceController;
+            mSmartspaceTrampolineComponent = smartspaceTrampolineComponent;
+            mActivityStarter = activityStarter;
+            mAirQualityColorPicker = airQualityColorPicker;
+        }
+
+        @Override
+        protected void onViewAttached() {
+            mSmartspaceController.addUnfilteredListener(mSmartspaceTargetListener);
+        }
+
+        @Override
+        protected void onViewDetached() {
+            mSmartspaceController.removeUnfilteredListener(mSmartspaceTargetListener);
+        }
+
+        private void updateView(@Nullable SmartspaceTarget target) {
+            final SmartspaceAction headerAction = target == null ? null : target.getHeaderAction();
+            if (headerAction == null || TextUtils.isEmpty(headerAction.getTitle())) {
+                mView.setVisibility(View.GONE);
+                return;
+            }
+            mView.setVisibility(View.VISIBLE);
+
+            final String airQuality = headerAction.getTitle().toString();
+            mView.setText(airQuality);
+
+            final Drawable background = mView.getBackground().mutate();
+            final int color = mAirQualityColorPicker.getColorForValue(airQuality);
+
+            if (background instanceof ShapeDrawable) {
+                ((ShapeDrawable) background).getPaint().setColor(color);
+            } else if (background instanceof GradientDrawable) {
+                ((GradientDrawable) background).setColor(color);
+            }
+            mView.setBackground(background);
+
+            final Intent intent = headerAction.getIntent();
+            if (intent != null && intent.getComponent() != null
+                    && intent.getComponent().getClassName().equals(
+                    mSmartspaceTrampolineComponent)) {
+                mView.setOnClickListener(v -> {
+                    mActivityStarter.postStartActivityDismissingKeyguard(intent, /* delay= */ 0);
+                });
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java
index f5c5a43..4eae3b9 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java
@@ -18,10 +18,12 @@
 
 import static com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent.DreamWeatherComplicationModule.DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS;
 import static com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent.DreamWeatherComplicationModule.DREAM_WEATHER_COMPLICATION_VIEW;
+import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT;
 
 import android.app.smartspace.SmartspaceAction;
 import android.app.smartspace.SmartspaceTarget;
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.text.TextUtils;
@@ -31,8 +33,9 @@
 import com.android.systemui.R;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent;
+import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener;
-import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
 import com.android.systemui.util.ViewController;
 
 import javax.inject.Inject;
@@ -70,7 +73,6 @@
      * {@link CoreStartable} for registering {@link DreamWeatherComplication} with SystemUI.
      */
     public static class Registrant extends CoreStartable {
-        private final LockscreenSmartspaceController mSmartSpaceController;
         private final DreamOverlayStateController mDreamOverlayStateController;
         private final DreamWeatherComplication mComplication;
 
@@ -79,20 +81,16 @@
          */
         @Inject
         public Registrant(Context context,
-                LockscreenSmartspaceController smartspaceController,
                 DreamOverlayStateController dreamOverlayStateController,
                 DreamWeatherComplication dreamWeatherComplication) {
             super(context);
-            mSmartSpaceController = smartspaceController;
             mDreamOverlayStateController = dreamOverlayStateController;
             mComplication = dreamWeatherComplication;
         }
 
         @Override
         public void start() {
-            if (mSmartSpaceController.isEnabled()) {
-                mDreamOverlayStateController.addComplication(mComplication);
-            }
+            mDreamOverlayStateController.addComplication(mComplication);
         }
     }
 
@@ -131,16 +129,22 @@
      * ViewController to contain value/logic associated with a Weather Complication View.
      */
     static class DreamWeatherViewController extends ViewController<TextView> {
-        private final LockscreenSmartspaceController mSmartSpaceController;
+        private final DreamSmartspaceController mSmartSpaceController;
+        private final ActivityStarter mActivityStarter;
+        private final String mSmartspaceTrampolineActivityComponent;
         private SmartspaceTargetListener mSmartspaceTargetListener;
 
         @Inject
         DreamWeatherViewController(
                 @Named(DREAM_WEATHER_COMPLICATION_VIEW) TextView view,
-                LockscreenSmartspaceController smartspaceController
+                @Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT) String smartspaceTrampoline,
+                ActivityStarter activityStarter,
+                DreamSmartspaceController smartspaceController
         ) {
             super(view);
+            mActivityStarter = activityStarter;
             mSmartSpaceController = smartspaceController;
+            mSmartspaceTrampolineActivityComponent = smartspaceTrampoline;
         }
 
         @Override
@@ -172,14 +176,25 @@
                                                 R.dimen.smart_action_button_icon_padding));
 
                             }
+                            mView.setOnClickListener(v -> {
+                                final Intent intent = headerAction.getIntent();
+                                if (intent != null && intent.getComponent() != null
+                                        && intent.getComponent().getClassName()
+                                        .equals(mSmartspaceTrampolineActivityComponent)) {
+                                    mActivityStarter.postStartActivityDismissingKeyguard(
+                                            intent, 0 /*delay*/);
+                                }
+                            });
                         }
                     });
-            mSmartSpaceController.addListener(mSmartspaceTargetListener);
+            // We need to use an unfiltered listener here since weather is filtered from showing
+            // in the dream smartspace.
+            mSmartSpaceController.addUnfilteredListener(mSmartspaceTargetListener);
         }
 
         @Override
         protected void onViewDetached() {
-            mSmartSpaceController.removeListener(mSmartspaceTargetListener);
+            mSmartSpaceController.removeUnfilteredListener(mSmartspaceTargetListener);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamAirQualityComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamAirQualityComplicationComponent.java
new file mode 100644
index 0000000..112a1ce
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamAirQualityComplicationComponent.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams.complication.dagger;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.ColorInt;
+
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dreams.complication.ComplicationLayoutParams;
+import com.android.systemui.dreams.complication.DreamAirQualityComplication;
+import com.android.systemui.dreams.complication.DreamAirQualityComplication.DreamAirQualityViewHolder;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+import javax.inject.Named;
+import javax.inject.Scope;
+
+import dagger.Module;
+import dagger.Provides;
+import dagger.Subcomponent;
+
+/**
+ * Component responsible for generating dependencies for the {@link DreamAirQualityComplication},
+ * such as the layout details.
+ */
+@Subcomponent(modules = {
+        DreamAirQualityComplicationComponent.DreamAirQualityComplicationModule.class,
+})
+@DreamAirQualityComplicationComponent.DreamAirQualityComplicationScope
+public interface DreamAirQualityComplicationComponent {
+
+    @Documented
+    @Retention(RetentionPolicy.RUNTIME)
+    @Scope
+    @interface DreamAirQualityComplicationScope {
+    }
+
+    /**
+     * Generates {@link DreamAirQualityComplicationComponent}.
+     */
+    @Subcomponent.Factory
+    interface Factory {
+        DreamAirQualityComplicationComponent create();
+    }
+
+    /**
+     * Creates {@link DreamAirQualityViewHolder}.
+     */
+    DreamAirQualityViewHolder getViewHolder();
+
+    /**
+     * Scoped values for {@link DreamAirQualityComplicationComponent}.
+     */
+    @Module
+    interface DreamAirQualityComplicationModule {
+        String DREAM_AQI_COMPLICATION_VIEW = "aqi_complication_view";
+        String DREAM_AQI_COMPLICATION_LAYOUT_PARAMS = "aqi_complication_layout_params";
+        String DREAM_AQI_COLOR_THRESHOLDS = "aqi_color_thresholds";
+        String DREAM_AQI_COLOR_VALUES = "aqi_color_values";
+        String DREAM_AQI_COLOR_DEFAULT = "aqi_color_default";
+        // Order weight of insert into parent container
+        int INSERT_ORDER_WEIGHT = 1;
+
+        /**
+         * Provides the complication view.
+         */
+        @Provides
+        @DreamAirQualityComplicationScope
+        @Named(DREAM_AQI_COMPLICATION_VIEW)
+        static TextView provideComplicationView(LayoutInflater layoutInflater) {
+            return Objects.requireNonNull((TextView)
+                            layoutInflater.inflate(R.layout.dream_overlay_complication_aqi,
+                                    null, false),
+                    "R.layout.dream_overlay_complication_aqi did not properly inflated");
+        }
+
+        /**
+         * Provides the layout parameters for the complication view.
+         */
+        @Provides
+        @DreamAirQualityComplicationScope
+        @Named(DREAM_AQI_COMPLICATION_LAYOUT_PARAMS)
+        static ComplicationLayoutParams provideLayoutParams() {
+            return new ComplicationLayoutParams(0,
+                    ViewGroup.LayoutParams.WRAP_CONTENT,
+                    ComplicationLayoutParams.POSITION_BOTTOM
+                            | ComplicationLayoutParams.POSITION_START,
+                    ComplicationLayoutParams.DIRECTION_END,
+                    INSERT_ORDER_WEIGHT, /* snapToGuide= */ true);
+        }
+
+        @Provides
+        @DreamAirQualityComplicationScope
+        @Named(DREAM_AQI_COLOR_THRESHOLDS)
+        static int[] provideAqiColorThresholds(@Main Resources resources) {
+            return resources.getIntArray(R.array.config_dreamAqiThresholds);
+        }
+
+        @Provides
+        @DreamAirQualityComplicationScope
+        @Named(DREAM_AQI_COLOR_VALUES)
+        static int[] provideAqiColorValues(@Main Resources resources) {
+            return resources.getIntArray(R.array.config_dreamAqiColorValues);
+        }
+
+        @Provides
+        @DreamAirQualityComplicationScope
+        @Named(DREAM_AQI_COLOR_DEFAULT)
+        @ColorInt
+        static int provideDefaultAqiColor(Context context) {
+            return context.getColor(R.color.dream_overlay_aqi_unknown);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamClockDateComplicationModule.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamClockDateComplicationModule.java
index eb2fc5d..3ab26ce 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamClockDateComplicationModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamClockDateComplicationModule.java
@@ -41,7 +41,7 @@
             "clock_date_complication_layout_params";
     // Order weight of insert into parent container
     //TODO(b/217199227): move to a single location.
-    int INSERT_ORDER_WEIGHT = 2;
+    int INSERT_ORDER_WEIGHT = 3;
 
     /**
      * Provides the complication view.
@@ -66,6 +66,6 @@
                 ComplicationLayoutParams.POSITION_BOTTOM
                         | ComplicationLayoutParams.POSITION_START,
                 ComplicationLayoutParams.DIRECTION_END,
-                INSERT_ORDER_WEIGHT);
+                INSERT_ORDER_WEIGHT, /* snapToGuide= */ true);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java
index 536f3dc..7ab3ad1 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java
@@ -77,7 +77,7 @@
         String DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS =
                 "weather_complication_layout_params";
         // Order weight of insert into parent container
-        int INSERT_ORDER_WEIGHT = 1;
+        int INSERT_ORDER_WEIGHT = 2;
 
         /**
          * Provides the complication view.
@@ -104,7 +104,7 @@
                     ComplicationLayoutParams.POSITION_BOTTOM
                             | ComplicationLayoutParams.POSITION_START,
                     ComplicationLayoutParams.DIRECTION_END,
-                    INSERT_ORDER_WEIGHT);
+                    INSERT_ORDER_WEIGHT, /* snapToGuide= */ true);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java
index 62a4140..98344aa 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java
@@ -16,9 +16,15 @@
 
 package com.android.systemui.dreams.complication.dagger;
 
+import android.content.Context;
+
+import com.android.systemui.R;
 import com.android.systemui.dagger.SystemUIBinder;
 
+import javax.inject.Named;
+
 import dagger.Module;
+import dagger.Provides;
 
 /**
  * Module for all components with corresponding dream layer complications registered in
@@ -30,6 +36,17 @@
         },
         subcomponents = {
                 DreamWeatherComplicationComponent.class,
+                DreamAirQualityComplicationComponent.class,
         })
 public interface RegisteredComplicationsModule {
+    String SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT = "smartspace_trampoline_activity";
+
+    /**
+     * Provides the smartspace trampoline activity component.
+     */
+    @Provides
+    @Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT)
+    static String provideSmartspaceTrampolineActivityComponent(Context context) {
+        return context.getString(R.string.config_smartspaceTrampolineActivityComponent);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index c1dff24..2dd2098 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -17,10 +17,18 @@
 package com.android.systemui.dreams.dagger;
 
 import android.content.Context;
+import android.content.res.Resources;
 
 import com.android.settingslib.dream.DreamBackend;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dreams.DreamOverlayNotificationCountProvider;
 import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule;
 
+import java.util.Optional;
+
+import javax.inject.Named;
+
 import dagger.Module;
 import dagger.Provides;
 
@@ -34,6 +42,10 @@
             DreamOverlayComponent.class,
         })
 public interface DreamModule {
+    String DREAM_ONLY_ENABLED_FOR_SYSTEM_USER = "dream_only_enabled_for_system_user";
+
+    String DREAM_SUPPORTED = "dream_supported";
+
     /**
      * Provides an instance of the dream backend.
      */
@@ -41,4 +53,31 @@
     static DreamBackend providesDreamBackend(Context context) {
         return DreamBackend.getInstance(context);
     }
+
+    /**
+     * Provides an instance of a {@link DreamOverlayNotificationCountProvider}.
+     */
+    @SysUISingleton
+    @Provides
+    static Optional<DreamOverlayNotificationCountProvider>
+            providesDreamOverlayNotificationCountProvider() {
+        // If we decide to bring this back, we should gate it on a config that can be changed in
+        // an overlay.
+        return Optional.empty();
+    }
+
+    /** */
+    @Provides
+    @Named(DREAM_ONLY_ENABLED_FOR_SYSTEM_USER)
+    static boolean providesDreamOnlyEnabledForSystemUser(@Main Resources resources) {
+        return resources.getBoolean(
+                com.android.internal.R.bool.config_dreamsOnlyEnabledForSystemUser);
+    }
+
+    /** */
+    @Provides
+    @Named(DREAM_SUPPORTED)
+    static boolean providesDreamSupported(@Main Resources resources) {
+        return resources.getBoolean(com.android.internal.R.bool.config_dreamsSupported);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
similarity index 85%
rename from packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt
rename to packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
index a309547..63f63a5 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
@@ -19,6 +19,7 @@
 import android.app.smartspace.SmartspaceConfig
 import android.app.smartspace.SmartspaceManager
 import android.app.smartspace.SmartspaceSession
+import android.app.smartspace.SmartspaceTarget
 import android.content.Context
 import android.graphics.Color
 import android.util.Log
@@ -46,7 +47,7 @@
  * Controller for managing the smartspace view on the dream
  */
 @SysUISingleton
-class DreamsSmartspaceController @Inject constructor(
+class DreamSmartspaceController @Inject constructor(
     private val context: Context,
     private val smartspaceManager: SmartspaceManager,
     private val execution: Execution,
@@ -58,7 +59,7 @@
     @Named(DREAM_SMARTSPACE_DATA_PLUGIN) optionalPlugin: Optional<BcSmartspaceDataPlugin>
 ) {
     companion object {
-        private const val TAG = "DreamsSmartspaceCtrlr"
+        private const val TAG = "DreamSmartspaceCtrlr"
     }
 
     private var session: SmartspaceSession? = null
@@ -66,7 +67,9 @@
     private var targetFilter: SmartspaceTargetFilter? = optionalTargetFilter.orElse(null)
 
     // A shadow copy of listeners is maintained to track whether the session should remain open.
-    private var listeners = mutableSetOf<BcSmartspaceDataPlugin.SmartspaceTargetListener>()
+    private var listeners = mutableSetOf<SmartspaceTargetListener>()
+
+    private var unfilteredListeners = mutableSetOf<SmartspaceTargetListener>()
 
     // Smartspace can be used on multiple displays, such as when the user casts their screen
     private var smartspaceViews = mutableSetOf<SmartspaceView>()
@@ -113,6 +116,7 @@
     private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets ->
         execution.assertIsMainThread()
 
+        onTargetsAvailableUnfiltered(targets)
         val filteredTargets = targets.filter { targetFilter?.filterSmartspaceTarget(it) ?: true }
         plugin?.onTargetsAvailable(filteredTargets)
     }
@@ -137,13 +141,10 @@
     private fun buildView(parent: ViewGroup): View? {
         return if (plugin != null) {
             var view = smartspaceViewComponentFactory.create(parent, plugin, stateChangeListener)
-                    .getView()
+                .getView()
             if (view !is View) {
                 return null
             }
-
-            view.setIsDreaming(true)
-
             return view
         } else {
             null
@@ -151,7 +152,8 @@
     }
 
     private fun hasActiveSessionListeners(): Boolean {
-        return smartspaceViews.isNotEmpty() || listeners.isNotEmpty()
+        return smartspaceViews.isNotEmpty() || listeners.isNotEmpty() ||
+            unfilteredListeners.isNotEmpty()
     }
 
     private fun connectSession() {
@@ -164,13 +166,15 @@
         }
 
         val newSession = smartspaceManager.createSmartspaceSession(
-                SmartspaceConfig.Builder(context, "dream").build())
+            SmartspaceConfig.Builder(context, "dream").build()
+        )
         Log.d(TAG, "Starting smartspace session for dream")
         newSession.addOnTargetsAvailableListener(uiExecutor, sessionListener)
         this.session = newSession
 
         plugin.registerSmartspaceEventNotifier {
-                e -> session?.notifySmartspaceEvent(e)
+                e ->
+            session?.notifySmartspaceEvent(e)
         }
 
         reloadSmartspace()
@@ -218,4 +222,22 @@
     private fun reloadSmartspace() {
         session?.requestSmartspaceUpdate()
     }
+
+    private fun onTargetsAvailableUnfiltered(targets: List<SmartspaceTarget>) {
+        unfilteredListeners.forEach { it.onSmartspaceTargetsUpdated(targets) }
+    }
+
+    /**
+     * Adds a listener for the raw, unfiltered list of smartspace targets. This should be used
+     * carefully, as it doesn't filter out targets which the user may not want shown.
+     */
+    fun addUnfilteredListener(listener: SmartspaceTargetListener) {
+        unfilteredListeners.add(listener)
+        connectSession()
+    }
+
+    fun removeUnfilteredListener(listener: SmartspaceTargetListener) {
+        unfilteredListeners.remove(listener)
+        disconnect()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
index fbca7b1..f769a23 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
@@ -44,6 +44,7 @@
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
 import java.util.Optional;
+
 import javax.inject.Inject;
 import javax.inject.Named;
 
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java
index 4965c9d..3087cdf 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java
@@ -25,6 +25,7 @@
 
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.complication.Complication;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.touch.TouchInsetManager;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -50,6 +51,7 @@
 
     private final Complication.VisibilityController mVisibilityController;
     private final int mRestoreTimeout;
+    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private final Handler mHandler;
     private final Executor mExecutor;
     private final TouchInsetManager mTouchInsetManager;
@@ -65,10 +67,12 @@
     HideComplicationTouchHandler(Complication.VisibilityController visibilityController,
             @Named(COMPLICATIONS_RESTORE_TIMEOUT) int restoreTimeout,
             TouchInsetManager touchInsetManager,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             @Main Executor executor,
             @Main Handler handler) {
         mVisibilityController = visibilityController;
         mRestoreTimeout = restoreTimeout;
+        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mHandler = handler;
         mTouchInsetManager = touchInsetManager;
         mExecutor = executor;
@@ -80,10 +84,13 @@
             Log.d(TAG, "onSessionStart");
         }
 
+        final boolean bouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing();
+
         // If other sessions are interested in this touch, do not fade out elements.
-        if (session.getActiveSessionCount() > 1) {
+        if (session.getActiveSessionCount() > 1 || bouncerShowing) {
             if (DEBUG) {
-                Log.d(TAG, "multiple active touch sessions, not fading");
+                Log.d(TAG, "not fading. Active session count: " + session.getActiveSessionCount()
+                        + ". Bouncer showing: " + bouncerShowing);
             }
             session.pop();
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt
index 9d6e3c2..2cee2520 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt
@@ -29,6 +29,9 @@
     fun isEnabled(flag: ResourceBooleanFlag): Boolean
 
     /** Returns a boolean value for the given flag.  */
+    fun isEnabled(flag: DeviceConfigBooleanFlag): Boolean
+
+    /** Returns a boolean value for the given flag.  */
     fun isEnabled(flag: SysPropBooleanFlag): Boolean
 
     /** Returns a string value for the given flag.  */
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
index c4531b5..49b3908 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
@@ -32,6 +32,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.provider.DeviceConfig;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -44,6 +45,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.statusbar.commandline.Command;
 import com.android.systemui.statusbar.commandline.CommandRegistry;
+import com.android.systemui.util.DeviceConfigProxy;
 import com.android.systemui.util.settings.SecureSettings;
 
 import java.io.PrintWriter;
@@ -81,6 +83,7 @@
     private final SecureSettings mSecureSettings;
     private final Resources mResources;
     private final SystemPropertiesHelper mSystemProperties;
+    private final DeviceConfigProxy mDeviceConfigProxy;
     private final Map<Integer, Flag<?>> mAllFlags;
     private final Map<Integer, Boolean> mBooleanFlagCache = new TreeMap<>();
     private final Map<Integer, String> mStringFlagCache = new TreeMap<>();
@@ -94,6 +97,7 @@
             SystemPropertiesHelper systemProperties,
             @Main Resources resources,
             DumpManager dumpManager,
+            DeviceConfigProxy deviceConfigProxy,
             @Named(ALL_FLAGS) Map<Integer, Flag<?>> allFlags,
             CommandRegistry commandRegistry,
             IStatusBarService barService) {
@@ -101,6 +105,7 @@
         mSecureSettings = secureSettings;
         mResources = resources;
         mSystemProperties = systemProperties;
+        mDeviceConfigProxy = deviceConfigProxy;
         mAllFlags = allFlags;
         mBarService = barService;
 
@@ -138,6 +143,18 @@
     }
 
     @Override
+    public boolean isEnabled(@NonNull DeviceConfigBooleanFlag flag) {
+        int id = flag.getId();
+        if (!mBooleanFlagCache.containsKey(id)) {
+            boolean deviceConfigValue = mDeviceConfigProxy.getBoolean(flag.getNamespace(),
+                    flag.getName(), flag.getDefault());
+            mBooleanFlagCache.put(id, readFlagValue(id, deviceConfigValue));
+        }
+
+        return mBooleanFlagCache.get(id);
+    }
+
+    @Override
     public boolean isEnabled(@NonNull SysPropBooleanFlag flag) {
         int id = flag.getId();
         if (!mBooleanFlagCache.containsKey(id)) {
@@ -293,6 +310,8 @@
             setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
         } else if (flag instanceof ResourceBooleanFlag) {
             setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
+        } else if (flag instanceof DeviceConfigBooleanFlag) {
+            setFlagValue(flag.getId(), value, BooleanFlagSerializer.INSTANCE);
         } else if (flag instanceof SysPropBooleanFlag) {
             // Store SysProp flags in SystemProperties where they can read by outside parties.
             mSystemProperties.setBoolean(((SysPropBooleanFlag) flag).getName(), value);
@@ -394,6 +413,10 @@
                 return new BooleanFlag(
                         f.getId(), isEnabled((ResourceBooleanFlag) f), f.getTeamfood());
             }
+            if (f instanceof DeviceConfigBooleanFlag) {
+                return new BooleanFlag(
+                        f.getId(), isEnabled((DeviceConfigBooleanFlag) f), f.getTeamfood());
+            }
             if (f instanceof SysPropBooleanFlag) {
                 // TODO(b/223379190): Teamfood not supported for sysprop flags yet.
                 return new BooleanFlag(
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
index cacef16..1492a2b 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
@@ -19,6 +19,7 @@
 import static java.util.Objects.requireNonNull;
 
 import android.content.res.Resources;
+import android.provider.DeviceConfig;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 
@@ -28,6 +29,7 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.util.DeviceConfigProxy;
 
 import java.io.PrintWriter;
 import java.util.Map;
@@ -44,6 +46,7 @@
 public class FeatureFlagsRelease implements FeatureFlags, Dumpable {
     private final Resources mResources;
     private final SystemPropertiesHelper mSystemProperties;
+    private final DeviceConfigProxy mDeviceConfigProxy;
     SparseBooleanArray mBooleanCache = new SparseBooleanArray();
     SparseArray<String> mStringCache = new SparseArray<>();
 
@@ -51,9 +54,11 @@
     public FeatureFlagsRelease(
             @Main Resources resources,
             SystemPropertiesHelper systemProperties,
+            DeviceConfigProxy deviceConfigProxy,
             DumpManager dumpManager) {
         mResources = resources;
         mSystemProperties = systemProperties;
+        mDeviceConfigProxy = deviceConfigProxy;
         dumpManager.registerDumpable("SysUIFlags", this);
     }
 
@@ -79,6 +84,18 @@
     }
 
     @Override
+    public boolean isEnabled(@NonNull DeviceConfigBooleanFlag flag) {
+        int cacheIndex = mBooleanCache.indexOfKey(flag.getId());
+        if (cacheIndex < 0) {
+            boolean deviceConfigValue = mDeviceConfigProxy.getBoolean(flag.getNamespace(),
+                    flag.getName(), flag.getDefault());
+            return isEnabled(flag.getId(), deviceConfigValue);
+        }
+
+        return mBooleanCache.valueAt(cacheIndex);
+    }
+
+    @Override
     public boolean isEnabled(SysPropBooleanFlag flag) {
         int cacheIndex = mBooleanCache.indexOfKey(flag.getId());
         if (cacheIndex < 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 2c79830..47a68bbb 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.flags;
 
+import static android.provider.DeviceConfig.NAMESPACE_WINDOW_MANAGER;
+
 import com.android.internal.annotations.Keep;
 import com.android.systemui.R;
 
@@ -43,9 +45,6 @@
 
     /***************************************/
     // 100 - notification
-    public static final BooleanFlag NEW_NOTIFICATION_PIPELINE_RENDERING =
-            new BooleanFlag(101, true);
-
     public static final BooleanFlag NOTIFICATION_PIPELINE_DEVELOPER_LOGGING =
             new BooleanFlag(103, false);
 
@@ -61,6 +60,9 @@
     public static final ResourceBooleanFlag NOTIFICATION_DRAG_TO_CONTENTS =
             new ResourceBooleanFlag(108, R.bool.config_notificationToContents);
 
+    public static final BooleanFlag REMOVE_UNRANKED_NOTIFICATIONS =
+            new BooleanFlag(109, false);
+
     /***************************************/
     // 200 - keyguard/lockscreen
 
@@ -153,7 +155,7 @@
 
     /***************************************/
     // 900 - media
-    public static final BooleanFlag MEDIA_TAP_TO_TRANSFER = new BooleanFlag(900, false);
+    public static final BooleanFlag MEDIA_TAP_TO_TRANSFER = new BooleanFlag(900, true);
     public static final BooleanFlag MEDIA_SESSION_ACTIONS = new BooleanFlag(901, false);
     public static final BooleanFlag MEDIA_NEARBY_DEVICES = new BooleanFlag(903, true);
     public static final BooleanFlag MEDIA_MUTE_AWAIT = new BooleanFlag(904, true);
@@ -161,12 +163,26 @@
     // 1000 - dock
     public static final BooleanFlag SIMULATE_DOCK_THROUGH_CHARGING =
             new BooleanFlag(1000, true);
+    public static final BooleanFlag DOCK_SETUP_ENABLED = new BooleanFlag(1001, false);
+
 
     // 1100 - windowing
     @Keep
     public static final SysPropBooleanFlag WM_ENABLE_SHELL_TRANSITIONS =
             new SysPropBooleanFlag(1100, "persist.wm.debug.shell_transit", false);
 
+    /**
+     * b/170163464: animate bubbles expanded view collapse with home gesture
+     */
+    @Keep
+    public static final SysPropBooleanFlag BUBBLES_HOME_GESTURE =
+            new SysPropBooleanFlag(1101, "persist.wm.debug.bubbles_home_gesture", true);
+
+    @Keep
+    public static final DeviceConfigBooleanFlag WM_ENABLE_PARTIAL_SCREEN_SHARING =
+            new DeviceConfigBooleanFlag(1102, "record_task_content",
+                    NAMESPACE_WINDOW_MANAGER, false, true);
+
     // 1200 - predictive back
     @Keep
     public static final SysPropBooleanFlag WM_ENABLE_PREDICTIVE_BACK = new SysPropBooleanFlag(
@@ -178,6 +194,8 @@
     public static final SysPropBooleanFlag WM_ALWAYS_ENFORCE_PREDICTIVE_BACK =
             new SysPropBooleanFlag(1202, "persist.wm.debug.predictive_back_always_enforce", false);
 
+    public static final BooleanFlag NEW_BACK_AFFORDANCE = new BooleanFlag(1203, true);
+
     // Pay no attention to the reflection behind the curtain.
     // ========================== Curtain ==========================
     // |                                                           |
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index acb080a..ab30db2 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -54,6 +54,7 @@
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -99,6 +100,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEvent;
 import com.android.internal.logging.UiEventLogger;
@@ -110,6 +112,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.MultiListLayout;
 import com.android.systemui.MultiListLayout.MultiListAdapter;
+import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -154,6 +157,8 @@
 
     private static final String TAG = "GlobalActionsDialogLite";
 
+    private static final String INTERACTION_JANK_TAG = "global_actions";
+
     private static final boolean SHOW_SILENT_TOGGLE = true;
 
     /* Valid settings for global actions keys.
@@ -499,7 +504,9 @@
         mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM);
 
         if (view != null) {
-            mDialogLaunchAnimator.showFromView(mDialog, view);
+            mDialogLaunchAnimator.showFromView(mDialog, view,
+                    new DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                            INTERACTION_JANK_TAG));
         } else {
             mDialog.show();
         }
@@ -1038,7 +1045,8 @@
 
         @Override
         public boolean showBeforeProvisioning() {
-            return false;
+            return Build.isDebuggable() && mGlobalSettings.getInt(
+                    Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index fb61948..95b3b3f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -55,6 +55,7 @@
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.Trace;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
 import android.view.IRemoteAnimationFinishedCallback;
@@ -157,7 +158,7 @@
             Rect localBounds = new Rect(change.getEndAbsBounds());
             localBounds.offsetTo(change.getEndRelOffset().x, change.getEndRelOffset().y);
 
-            out.add(new RemoteAnimationTarget(
+            final RemoteAnimationTarget target = new RemoteAnimationTarget(
                     taskId,
                     newModeToLegacyMode(change.getMode()),
                     change.getLeash(),
@@ -168,7 +169,15 @@
                     info.getChanges().size() - i,
                     new Point(), localBounds, new Rect(change.getEndAbsBounds()),
                     windowConfiguration, isNotInRecents, null /* startLeash */,
-                    change.getStartAbsBounds(), taskInfo, false /* allowEnterPip */));
+                    change.getStartAbsBounds(), taskInfo, false /* allowEnterPip */);
+            // Use hasAnimatingParent to mark the anything below root task
+            if (taskId != -1 && change.getParent() != null) {
+                final TransitionInfo.Change parentChange = info.getChange(change.getParent());
+                if (parentChange != null && parentChange.getTaskInfo() != null) {
+                    target.hasAnimatingParent = true;
+                }
+            }
+            out.add(target);
         }
         return out.toArray(new RemoteAnimationTarget[out.size()]);
     }
@@ -189,8 +198,12 @@
         }
     }
 
+    // Wrap Keyguard going away animation
     private static IRemoteTransition wrap(IRemoteAnimationRunner runner) {
         return new IRemoteTransition.Stub() {
+            final ArrayMap<IBinder, IRemoteTransitionFinishedCallback> mFinishCallbacks =
+                    new ArrayMap<>();
+
             @Override
             public void startAnimation(IBinder transition, TransitionInfo info,
                     SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback)
@@ -200,16 +213,37 @@
                 final RemoteAnimationTarget[] wallpapers = wrap(info, true /* wallpapers */);
                 final RemoteAnimationTarget[] nonApps = new RemoteAnimationTarget[0];
 
-                // TODO: Remove this, and update alpha value in the IAnimationRunner.
-                for (TransitionInfo.Change change : info.getChanges()) {
-                    t.setAlpha(change.getLeash(), 1.0f);
+                // Sets the alpha to 0 for the opening root task for fade in animation. And since
+                // the fade in animation can only apply on the first opening app, so set alpha to 1
+                // for anything else.
+                boolean foundOpening = false;
+                for (RemoteAnimationTarget target : apps) {
+                    if (target.taskId != -1
+                            && target.mode == RemoteAnimationTarget.MODE_OPENING
+                            && !target.hasAnimatingParent) {
+                        if (foundOpening) {
+                            Log.w(TAG, "More than one opening target");
+                            t.setAlpha(target.leash, 1.0f);
+                            continue;
+                        }
+                        t.setAlpha(target.leash, 0.0f);
+                        foundOpening = true;
+                    } else {
+                        t.setAlpha(target.leash, 1.0f);
+                    }
                 }
                 t.apply();
+                synchronized (mFinishCallbacks) {
+                    mFinishCallbacks.put(transition, finishCallback);
+                }
                 runner.onAnimationStart(getTransitionOldType(info.getType(), info.getFlags(), apps),
                         apps, wallpapers, nonApps,
                         new IRemoteAnimationFinishedCallback.Stub() {
                             @Override
                             public void onAnimationFinished() throws RemoteException {
+                                synchronized (mFinishCallbacks) {
+                                    if (mFinishCallbacks.remove(transition) == null) return;
+                                }
                                 Slog.d(TAG, "Finish IRemoteAnimationRunner.");
                                 finishCallback.onTransitionFinished(null /* wct */, null /* t */);
                             }
@@ -220,6 +254,20 @@
             public void mergeAnimation(IBinder transition, TransitionInfo info,
                     SurfaceControl.Transaction t, IBinder mergeTarget,
                     IRemoteTransitionFinishedCallback finishCallback) {
+                try {
+                    final IRemoteTransitionFinishedCallback origFinishCB;
+                    synchronized (mFinishCallbacks) {
+                        origFinishCB = mFinishCallbacks.remove(transition);
+                    }
+                    if (origFinishCB == null) {
+                        // already finished (or not started yet), so do nothing.
+                        return;
+                    }
+                    runner.onAnimationCancelled(false /* isKeyguardOccluded */);
+                    origFinishCB.onTransitionFinished(null /* wct */, null /* t */);
+                } catch (RemoteException e) {
+                    // nothing, we'll just let it finish on its own I guess.
+                }
             }
         };
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 99b5720..382323f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -26,6 +26,7 @@
 import android.os.RemoteException
 import android.util.Log
 import android.view.RemoteAnimationTarget
+import android.view.SurfaceControl
 import android.view.SyncRtSurfaceTransactionApplier
 import android.view.View
 import androidx.annotation.VisibleForTesting
@@ -293,6 +294,8 @@
 
     private val handler = Handler()
 
+    private val tmpFloat = FloatArray(9)
+
     init {
         with(surfaceBehindAlphaAnimator) {
             duration = SURFACE_BEHIND_SWIPE_FADE_DURATION_MS
@@ -723,13 +726,27 @@
             if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount
             else surfaceBehindAlpha
 
-        applyParamsToSurface(
-            SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
-                surfaceBehindRemoteAnimationTarget!!.leash)
-                .withMatrix(surfaceBehindMatrix)
-                .withCornerRadius(roundedCornerRadius)
-                .withAlpha(animationAlpha)
-                .build())
+        // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is unable
+        // to draw
+        val sc: SurfaceControl? = surfaceBehindRemoteAnimationTarget?.leash
+        if (keyguardViewController.viewRootImpl.view?.visibility != View.VISIBLE &&
+            sc?.isValid == true) {
+            with(SurfaceControl.Transaction()) {
+                setMatrix(sc, surfaceBehindMatrix, tmpFloat)
+                setCornerRadius(sc, roundedCornerRadius)
+                setAlpha(sc, animationAlpha)
+                apply()
+            }
+        } else {
+            applyParamsToSurface(
+                SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
+                    surfaceBehindRemoteAnimationTarget!!.leash)
+                    .withMatrix(surfaceBehindMatrix)
+                    .withCornerRadius(roundedCornerRadius)
+                    .withAlpha(animationAlpha)
+                    .build()
+            )
+        }
     }
 
     /**
@@ -744,8 +761,11 @@
         handler.removeCallbacksAndMessages(null)
 
         // Make sure we made the surface behind fully visible, just in case. It should already be
-        // fully visible. If the launcher is doing its own animation, let it continue without
-        // forcing it to 1f.
+        // fully visible. The exit animation is finished, and we should not hold the leash anymore,
+        // so forcing it to 1f.
+        surfaceBehindAlphaAnimator.cancel()
+        surfaceBehindEntryAnimator.cancel()
+        surfaceBehindAlpha = 1f
         setSurfaceBehindAppearAmount(1f)
         launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
 
@@ -910,4 +930,4 @@
             return context.resources.getIntArray(R.array.config_foldedDeviceStates).isNotEmpty()
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d2e5506..340cde1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -40,6 +40,7 @@
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
+import android.app.WindowConfiguration;
 import android.app.trust.TrustManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -934,6 +935,8 @@
                     }
 
                     final RemoteAnimationTarget primary = apps[0];
+                    final boolean isDream = (apps[0].taskInfo.topActivityType
+                            == WindowConfiguration.ACTIVITY_TYPE_DREAM);
 
                     final SyncRtSurfaceTransactionApplier applier =
                             new SyncRtSurfaceTransactionApplier(
@@ -955,20 +958,24 @@
 
                                     final float surfaceHeight = primary.screenSpaceBounds.height();
 
-                                    mUnoccludeMatrix.setTranslate(
-                                            0f,
-                                            (1f - animatedValue)
-                                                    * surfaceHeight
-                                                    * UNOCCLUDE_TRANSLATE_DISTANCE_PERCENT);
-
-                                    SyncRtSurfaceTransactionApplier.SurfaceParams params =
+                                    // Fade for all types of activities.
+                                    SyncRtSurfaceTransactionApplier.SurfaceParams.Builder
+                                            paramsBuilder =
                                             new SyncRtSurfaceTransactionApplier.SurfaceParams
                                                     .Builder(primary.leash)
-                                                    .withMatrix(mUnoccludeMatrix)
-                                                    .withCornerRadius(mWindowCornerRadius)
-                                                    .withAlpha(animatedValue)
-                                                    .build();
-                                    applier.scheduleApply(params);
+                                                    .withAlpha(animatedValue);
+                                    // Set translate if the occluding activity isn't Dream.
+                                    if (!isDream) {
+                                        mUnoccludeMatrix.setTranslate(
+                                                0f,
+                                                (1f - animatedValue)
+                                                        * surfaceHeight
+                                                        * UNOCCLUDE_TRANSLATE_DISTANCE_PERCENT);
+
+                                        paramsBuilder.withMatrix(mUnoccludeMatrix).withCornerRadius(
+                                                mWindowCornerRadius);
+                                    }
+                                    applier.scheduleApply(paramsBuilder.build());
                                 });
                         mUnoccludeAnimator.addListener(new AnimatorListenerAdapter() {
                             @Override
@@ -2495,10 +2502,18 @@
                 mInteractionJankMonitor.begin(
                         createInteractionJankMonitorConf("DismissPanel"));
 
+                // Apply the opening animation on root task if exists
+                RemoteAnimationTarget aniTarget = apps[0];
+                for (RemoteAnimationTarget tmpTarget : apps) {
+                    if (tmpTarget.taskId != -1 && !tmpTarget.hasAnimatingParent) {
+                        aniTarget = tmpTarget;
+                        break;
+                    }
+                }
                 // Pass the surface and metadata to the unlock animation controller.
                 mKeyguardUnlockAnimationControllerLazy.get()
                         .notifyStartSurfaceBehindRemoteAnimation(
-                                apps[0], startTime, mSurfaceBehindRemoteAnimationRequested);
+                                aniTarget, startTime, mSurfaceBehindRemoteAnimationRequested);
             } else {
                 mInteractionJankMonitor.begin(
                         createInteractionJankMonitorConf("RemoteAnimationDisabled"));
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index eff025f..90cca15 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -52,7 +52,7 @@
         return factory.create("NotifLog", 1000 /* maxSize */, false /* systrace */);
     }
 
-    /** Provides a logging buffer for all logs related to the data layer of notifications. */
+    /** Provides a logging buffer for logs related to heads up presentation of notifications. */
     @Provides
     @SysUISingleton
     @NotificationHeadsUpLog
@@ -60,6 +60,14 @@
         return factory.create("NotifHeadsUpLog", 1000);
     }
 
+    /** Provides a logging buffer for notification interruption calculations. */
+    @Provides
+    @SysUISingleton
+    @NotificationInterruptLog
+    public static LogBuffer provideNotificationInterruptLogBuffer(LogBufferFactory factory) {
+        return factory.create("NotifInterruptLog", 100);
+    }
+
     /** Provides a logging buffer for all logs for lockscreen to shade transition events. */
     @Provides
     @SysUISingleton
@@ -251,4 +259,14 @@
             return new LogcatEchoTrackerProd();
         }
     }
+
+    /**
+     * Provides a {@link LogBuffer} for use by the status bar network controller.
+     */
+    @Provides
+    @SysUISingleton
+    @StatusBarNetworkControllerLog
+    public static LogBuffer provideStatusBarNetworkControllerBuffer(LogBufferFactory factory) {
+        return factory.create("StatusBarNetworkControllerLog", 20);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationInterruptLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationInterruptLog.java
new file mode 100644
index 0000000..760fbf3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationInterruptLog.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/** A {@link LogBuffer} for notification interruption logging. */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface NotificationInterruptLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarNetworkControllerLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarNetworkControllerLog.java
new file mode 100644
index 0000000..f26b316
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarNetworkControllerLog.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/**
+ * A {@link LogBuffer} for {@link com.android.systemui.statusbar.connectivity.NetworkController}
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface StatusBarNetworkControllerLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 33453a4..68aba62 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -70,6 +70,7 @@
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.GhostedViewLaunchAnimatorController;
 import com.android.systemui.animation.Interpolators;
+import com.android.systemui.bluetooth.BroadcastDialogController;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -188,6 +189,11 @@
     private final SeekBarViewModel.EnabledChangeListener mEnabledChangeListener =
             this::setIsSeekBarEnabled;
 
+    private final BroadcastDialogController mBroadcastDialogController;
+    private boolean mIsCurrentBroadcastedApp = false;
+    private boolean mShowBroadcastDialogButton = false;
+    private String mSwitchBroadcastApp;
+
     /**
      * Initialize a new control panel
      *
@@ -213,7 +219,8 @@
             MediaUiEventLogger logger,
             KeyguardStateController keyguardStateController,
             ActivityIntentHelper activityIntentHelper,
-            NotificationLockscreenUserManager lockscreenUserManager) {
+            NotificationLockscreenUserManager lockscreenUserManager,
+            BroadcastDialogController broadcastDialogController) {
         mContext = context;
         mBackgroundExecutor = backgroundExecutor;
         mMainExecutor = mainExecutor;
@@ -230,6 +237,7 @@
         mKeyguardStateController = keyguardStateController;
         mActivityIntentHelper = activityIntentHelper;
         mLockscreenUserManager = lockscreenUserManager;
+        mBroadcastDialogController = broadcastDialogController;
 
         mSeekBarViewModel.setLogSeek(() -> {
             if (mPackageName != null && mInstanceId != null) {
@@ -449,7 +457,10 @@
         final MediaController controller = getController();
         mBackgroundExecutor.execute(() -> mSeekBarViewModel.updateController(controller));
 
-        bindOutputSwitcherChip(data);
+        // Show the broadcast dialog button only when the le audio is enabled.
+        mShowBroadcastDialogButton =
+                data.getDevice() != null && data.getDevice().getShowBroadcastButton();
+        bindOutputSwitcherAndBroadcastButton(mShowBroadcastDialogButton, data);
         bindGutsMenuForPlayer(data);
         bindPlayerContentDescription(data);
         bindScrubbingTime(data);
@@ -467,21 +478,40 @@
         Trace.endSection();
     }
 
-    private void bindOutputSwitcherChip(MediaData data) {
-        // Output switcher chip
+    private void bindOutputSwitcherAndBroadcastButton(boolean showBroadcastButton, MediaData data) {
         ViewGroup seamlessView = mMediaViewHolder.getSeamless();
         seamlessView.setVisibility(View.VISIBLE);
         ImageView iconView = mMediaViewHolder.getSeamlessIcon();
         TextView deviceName = mMediaViewHolder.getSeamlessText();
         final MediaDeviceData device = data.getDevice();
 
-        // Disable clicking on output switcher for invalid devices and resumption controls
-        final boolean seamlessDisabled = (device != null && !device.getEnabled())
-                || data.getResumption();
-        final float seamlessAlpha = seamlessDisabled ? DISABLED_ALPHA : 1.0f;
-        mMediaViewHolder.getSeamlessButton().setAlpha(seamlessAlpha);
-        seamlessView.setEnabled(!seamlessDisabled);
-        CharSequence deviceString = mContext.getString(R.string.media_seamless_other_device);
+        final boolean enabled;
+        final boolean seamlessDisabled;
+        final int iconResource;
+        CharSequence deviceString;
+        if (showBroadcastButton) {
+            // TODO(b/233698402): Use the package name instead of app label to avoid the
+            // unexpected result.
+            mIsCurrentBroadcastedApp = device != null
+                    && TextUtils.equals(device.getName(),
+                    MediaDataUtils.getAppLabel(mContext, mPackageName, mContext.getString(
+                            R.string.bt_le_audio_broadcast_dialog_unknown_name)));
+            seamlessDisabled = !mIsCurrentBroadcastedApp;
+            // Always be enabled if the broadcast button is shown
+            enabled = true;
+            deviceString = mContext.getString(R.string.bt_le_audio_broadcast_dialog_unknown_name);
+            iconResource = R.drawable.settings_input_antenna;
+        } else {
+            // Disable clicking on output switcher for invalid devices and resumption controls
+            seamlessDisabled = (device != null && !device.getEnabled()) || data.getResumption();
+            enabled = !seamlessDisabled;
+            deviceString = mContext.getString(R.string.media_seamless_other_device);
+            iconResource = R.drawable.ic_media_home_devices;
+        }
+
+        mMediaViewHolder.getSeamlessButton().setAlpha(seamlessDisabled ? DISABLED_ALPHA : 1.0f);
+        seamlessView.setEnabled(enabled);
+
         if (device != null) {
             Drawable icon = device.getIcon();
             if (icon instanceof AdaptiveIcon) {
@@ -494,7 +524,7 @@
             deviceString = device.getName();
         } else {
             // Set to default icon
-            iconView.setImageResource(R.drawable.ic_media_home_devices);
+            iconView.setImageResource(iconResource);
         }
         deviceName.setText(deviceString);
         seamlessView.setContentDescription(deviceString);
@@ -503,21 +533,39 @@
                     if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
                         return;
                     }
-                    mLogger.logOpenOutputSwitcher(mUid, mPackageName, mInstanceId);
-                    if (device.getIntent() != null) {
-                        if (device.getIntent().isActivity()) {
-                            mActivityStarter.startActivity(
-                                    device.getIntent().getIntent(), true);
+
+                    if (showBroadcastButton) {
+                        // If the current media app is not broadcasted and users press the outputer
+                        // button, we should pop up the broadcast dialog to check do they want to
+                        // switch broadcast to the other media app, otherwise we still pop up the
+                        // media output dialog.
+                        if (!mIsCurrentBroadcastedApp) {
+                            mLogger.logOpenBroadcastDialog(mUid, mPackageName, mInstanceId);
+                            mSwitchBroadcastApp = device.getName().toString();
+                            mBroadcastDialogController.createBroadcastDialog(mSwitchBroadcastApp,
+                                    mPackageName, true, mMediaViewHolder.getSeamlessButton());
                         } else {
-                            try {
-                                device.getIntent().send();
-                            } catch (PendingIntent.CanceledException e) {
-                                Log.e(TAG, "Device pending intent was canceled");
-                            }
+                            mLogger.logOpenOutputSwitcher(mUid, mPackageName, mInstanceId);
+                            mMediaOutputDialogFactory.create(mPackageName, true,
+                                    mMediaViewHolder.getSeamlessButton());
                         }
                     } else {
-                        mMediaOutputDialogFactory.create(mPackageName, true,
-                                mMediaViewHolder.getSeamlessButton());
+                        mLogger.logOpenOutputSwitcher(mUid, mPackageName, mInstanceId);
+                        if (device.getIntent() != null) {
+                            if (device.getIntent().isActivity()) {
+                                mActivityStarter.startActivity(
+                                        device.getIntent().getIntent(), true);
+                            } else {
+                                try {
+                                    device.getIntent().send();
+                                } catch (PendingIntent.CanceledException e) {
+                                    Log.e(TAG, "Device pending intent was canceled");
+                                }
+                            }
+                        } else {
+                            mMediaOutputDialogFactory.create(mPackageName, true,
+                                    mMediaViewHolder.getSeamlessButton());
+                        }
                     }
                 });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index aeeef6b..5b2cda0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -215,7 +215,10 @@
     val intent: PendingIntent? = null,
 
     /** Unique id for this device */
-    val id: String? = null
+    val id: String? = null,
+
+    /** Whether or not to show the broadcast button */
+    val showBroadcastButton: Boolean
 ) {
     /**
      * Check whether [MediaDeviceData] objects are equal in all fields except the icon. The icon
@@ -230,6 +233,7 @@
         return enabled == other.enabled &&
             name == other.name &&
             intent == other.intent &&
-            id == other.id
+            id == other.id &&
+            showBroadcastButton == other.showBroadcastButton
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 6a69d42..30ba476 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -686,7 +686,8 @@
                 val enabled = deviceIntent != null && deviceIntent.isActivity
                 val deviceDrawable = Icon.createWithResource(sbn.packageName, deviceIcon)
                         .loadDrawable(sbn.getPackageContext(context))
-                device = MediaDeviceData(enabled, deviceDrawable, deviceName, deviceIntent)
+                device = MediaDeviceData(enabled, deviceDrawable, deviceName, deviceIntent,
+                        showBroadcastButton = false)
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataUtils.java b/packages/SystemUI/src/com/android/systemui/media/MediaDataUtils.java
new file mode 100644
index 0000000..b8185b9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataUtils.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.text.TextUtils;
+
+public class MediaDataUtils {
+
+    public static String getAppLabel(Context context, String packageName, String unknownName) {
+        if (TextUtils.isEmpty(packageName)) {
+            return null;
+        }
+        final PackageManager packageManager = context.getPackageManager();
+        ApplicationInfo applicationInfo;
+        try {
+            applicationInfo = packageManager.getApplicationInfo(packageName, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            applicationInfo = null;
+        }
+        final String applicationName =
+                (String) (applicationInfo != null
+                        ? packageManager.getApplicationLabel(applicationInfo)
+                        : unknownName);
+        return applicationName;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
index baed1c4..8305050 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -16,15 +16,23 @@
 
 package com.android.systemui.media
 
+import android.bluetooth.BluetoothLeBroadcast
+import android.bluetooth.BluetoothLeBroadcastMetadata
+import android.content.Context
 import android.graphics.drawable.Drawable
 import android.media.MediaRouter2Manager
 import android.media.session.MediaController
+import android.text.TextUtils
+import android.util.Log
 import androidx.annotation.AnyThread
 import androidx.annotation.MainThread
 import androidx.annotation.WorkerThread
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast
+import com.android.settingslib.bluetooth.LocalBluetoothManager
 import com.android.settingslib.media.LocalMediaManager
 import com.android.settingslib.media.MediaDevice
 import com.android.systemui.Dumpable
+import com.android.systemui.R
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
@@ -36,16 +44,20 @@
 import javax.inject.Inject
 
 private const val PLAYBACK_TYPE_UNKNOWN = 0
+private const val TAG = "MediaDeviceManager"
+private const val DEBUG = true
 
 /**
  * Provides information about the route (ie. device) where playback is occurring.
  */
 class MediaDeviceManager @Inject constructor(
+    private val context: Context,
     private val controllerFactory: MediaControllerFactory,
     private val localMediaManagerFactory: LocalMediaManagerFactory,
     private val mr2manager: MediaRouter2Manager,
     private val muteAwaitConnectionManagerFactory: MediaMuteAwaitConnectionManagerFactory,
     private val configurationController: ConfigurationController,
+    private val localBluetoothManager: LocalBluetoothManager?,
     @Main private val fgExecutor: Executor,
     @Background private val bgExecutor: Executor,
     dumpManager: DumpManager
@@ -147,7 +159,8 @@
         val controller: MediaController?,
         val localMediaManager: LocalMediaManager,
         val muteAwaitConnectionManager: MediaMuteAwaitConnectionManager?
-    ) : LocalMediaManager.DeviceCallback, MediaController.Callback() {
+    ) : LocalMediaManager.DeviceCallback, MediaController.Callback(),
+            BluetoothLeBroadcast.Callback {
 
         val token
             get() = controller?.sessionToken
@@ -166,7 +179,7 @@
         // A device that is not yet connected but is expected to connect imminently. Because it's
         // expected to connect imminently, it should be displayed as the current device.
         private var aboutToConnectDeviceOverride: AboutToConnectDevice? = null
-
+        private var broadcastDescription: String? = null
         private val configListener = object : ConfigurationController.ConfigurationListener {
             override fun onLocaleListChanged() {
                 updateCurrent()
@@ -238,7 +251,11 @@
         ) {
             aboutToConnectDeviceOverride = AboutToConnectDevice(
                 fullMediaDevice = localMediaManager.getMediaDeviceById(deviceAddress),
-                backupMediaDeviceData = MediaDeviceData(enabled = true, deviceIcon, deviceName)
+                backupMediaDeviceData = MediaDeviceData(
+                        /* enabled */ enabled = true,
+                        /* icon */ deviceIcon,
+                        /* name */ deviceName,
+                        /* showBroadcastButton */ showBroadcastButton = false)
             )
             updateCurrent()
         }
@@ -248,23 +265,127 @@
             updateCurrent()
         }
 
+
+        override fun onBroadcastStarted(reason: Int, broadcastId: Int) {
+            if (DEBUG) {
+                Log.d(TAG, "onBroadcastStarted(), reason = $reason , broadcastId = $broadcastId")
+            }
+            updateCurrent()
+        }
+
+        override fun onBroadcastStartFailed(reason: Int) {
+            if (DEBUG) {
+                Log.d(TAG, "onBroadcastStartFailed(), reason = $reason")
+            }
+        }
+
+        override fun onBroadcastMetadataChanged(broadcastId: Int,
+                                                metadata: BluetoothLeBroadcastMetadata) {
+            if (DEBUG) {
+                Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = $broadcastId , " +
+                        "metadata = $metadata")
+            }
+            updateCurrent()
+        }
+
+        override fun onBroadcastStopped(reason: Int, broadcastId: Int) {
+            if (DEBUG) {
+                Log.d(TAG, "onBroadcastStopped(), reason = $reason , broadcastId = $broadcastId")
+
+            }
+            updateCurrent()
+        }
+
+        override fun onBroadcastStopFailed(reason: Int) {
+            if (DEBUG) {
+                Log.d(TAG, "onBroadcastStopFailed(), reason = $reason")
+            }
+        }
+
+        override fun onBroadcastUpdated(reason: Int, broadcastId: Int) {
+            if (DEBUG) {
+                Log.d(TAG, "onBroadcastUpdated(), reason = $reason , broadcastId = $broadcastId")
+            }
+            updateCurrent()
+        }
+
+        override fun onBroadcastUpdateFailed(reason: Int, broadcastId: Int) {
+            if (DEBUG) {
+                Log.d(TAG, "onBroadcastUpdateFailed(), reason = $reason , " +
+                        "broadcastId = $broadcastId")
+            }
+        }
+
+        override fun onPlaybackStarted(reason: Int, broadcastId: Int) {}
+
+        override fun onPlaybackStopped(reason: Int, broadcastId: Int) {}
+
         @WorkerThread
         private fun updateCurrent() {
-            val aboutToConnect = aboutToConnectDeviceOverride
-            if (aboutToConnect != null &&
-                aboutToConnect.fullMediaDevice == null &&
-                aboutToConnect.backupMediaDeviceData != null) {
+            if (isLeAudioBroadcastEnabled()) {
+                current = MediaDeviceData(
+                        /* enabled */ true,
+                        /* icon */ context.getDrawable(R.drawable.settings_input_antenna),
+                        /* name */ broadcastDescription,
+                        /* intent */ null,
+                        /* showBroadcastButton */ showBroadcastButton = true)
+            } else {
+                val aboutToConnect = aboutToConnectDeviceOverride
+                if (aboutToConnect != null &&
+                        aboutToConnect.fullMediaDevice == null &&
+                        aboutToConnect.backupMediaDeviceData != null) {
                     // Only use [backupMediaDeviceData] when we don't have [fullMediaDevice].
                     current = aboutToConnect.backupMediaDeviceData
                     return
-            }
-            val device = aboutToConnect?.fullMediaDevice ?: localMediaManager.currentConnectedDevice
-            val route = controller?.let { mr2manager.getRoutingSessionForMediaController(it) }
+                }
+                val device = aboutToConnect?.fullMediaDevice
+                        ?: localMediaManager.currentConnectedDevice
+                val route = controller?.let { mr2manager.getRoutingSessionForMediaController(it) }
 
-            // If we have a controller but get a null route, then don't trust the device
-            val enabled = device != null && (controller == null || route != null)
-            val name = route?.name?.toString() ?: device?.name
-            current = MediaDeviceData(enabled, device?.iconWithoutBackground, name, id = device?.id)
+                // If we have a controller but get a null route, then don't trust the device
+                val enabled = device != null && (controller == null || route != null)
+                val name = route?.name?.toString() ?: device?.name
+                current = MediaDeviceData(enabled, device?.iconWithoutBackground, name,
+                        id = device?.id, showBroadcastButton = false)
+            }
+        }
+
+        private fun isLeAudioBroadcastEnabled(): Boolean {
+            if (localBluetoothManager != null) {
+                val profileManager = localBluetoothManager.profileManager
+                if (profileManager != null) {
+                    val bluetoothLeBroadcast = profileManager.leAudioBroadcastProfile
+                    if (bluetoothLeBroadcast != null && bluetoothLeBroadcast.isEnabled(null)) {
+                        getBroadcastingInfo(bluetoothLeBroadcast)
+                        return true
+                    } else if (DEBUG) {
+                        Log.d(TAG, "Can not get LocalBluetoothLeBroadcast")
+                    }
+                } else if (DEBUG) {
+                    Log.d(TAG, "Can not get LocalBluetoothProfileManager")
+                }
+            } else if (DEBUG) {
+                Log.d(TAG, "Can not get LocalBluetoothManager")
+            }
+            return false
+        }
+
+        private fun getBroadcastingInfo(bluetoothLeBroadcast: LocalBluetoothLeBroadcast) {
+            var currentBroadcastedApp = bluetoothLeBroadcast.appSourceName
+            // TODO(b/233698402): Use the package name instead of app label to avoid the
+            // unexpected result.
+            // Check the current media app's name is the same with current broadcast app's name
+            // or not.
+            var mediaApp = MediaDataUtils.getAppLabel(
+                    context, localMediaManager.packageName,
+                    context.getString(R.string.bt_le_audio_broadcast_dialog_unknown_name))
+            var isCurrentBroadcastedApp = TextUtils.equals(mediaApp, currentBroadcastedApp)
+            if (isCurrentBroadcastedApp) {
+                broadcastDescription = context.getString(
+                        R.string.broadcasting_description_is_broadcasting)
+            } else {
+                broadcastDescription = currentBroadcastedApp
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index ed5c193..2f732de 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -23,6 +23,7 @@
 import android.content.Context
 import android.content.res.Configuration
 import android.graphics.Rect
+import android.util.Log
 import android.util.MathUtils
 import android.view.View
 import android.view.ViewGroup
@@ -48,6 +49,8 @@
 import com.android.systemui.util.traceSection
 import javax.inject.Inject
 
+private val TAG: String = MediaHierarchyManager::class.java.simpleName
+
 /**
  * Similarly to isShown but also excludes views that have 0 alpha
  */
@@ -964,6 +967,14 @@
                         top,
                         left + currentBounds.width(),
                         top + currentBounds.height())
+
+                if (mediaFrame.childCount > 0) {
+                    val child = mediaFrame.getChildAt(0)
+                    if (mediaFrame.height < child.height) {
+                        Log.wtf(TAG, "mediaFrame height is too small for child: " +
+                            "${mediaFrame.height} vs ${child.height}")
+                    }
+                }
             }
             if (isCrossFadeAnimatorRunning) {
                 // When cross-fading with an animation, we only notify the media carousel of the
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt
index 52f5cc5..0baf01e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt
@@ -176,6 +176,11 @@
         logger.logWithInstanceId(MediaUiEvent.MEDIA_RECOMMENDATION_CARD_TAP, 0, packageName,
             instanceId)
     }
+
+    fun logOpenBroadcastDialog(uid: Int, packageName: String, instanceId: InstanceId) {
+        logger.logWithInstanceId(MediaUiEvent.MEDIA_OPEN_BROADCAST_DIALOG, uid, packageName,
+            instanceId)
+    }
 }
 
 enum class MediaUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum {
@@ -273,7 +278,10 @@
     MEDIA_RECOMMENDATION_ITEM_TAP(1044),
 
     @UiEvent(doc = "User tapped on a media recommendation card")
-    MEDIA_RECOMMENDATION_CARD_TAP(1045);
+    MEDIA_RECOMMENDATION_CARD_TAP(1045),
+
+    @UiEvent(doc = "User opened the broadcast dialog from a media control")
+    MEDIA_OPEN_BROADCAST_DIALOG(1079);
 
     override fun getId() = metricId
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 9b964a5..e591306 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -482,7 +482,7 @@
     abstract int getStopButtonVisibility();
 
     public CharSequence getStopButtonText() {
-        return mContext.getText(R.string.media_output_dialog_button_stop_casting);
+        return mContext.getText(R.string.keyboard_key_media_stop);
     }
 
     public void onStopButtonClick() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index f8b5edc..247ffa7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -858,6 +858,10 @@
                 || features.contains(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK));
     }
 
+    boolean isBluetoothLeDevice(@NonNull MediaDevice device) {
+        return device.isBLEDevice();
+    }
+
     boolean isBroadcastSupported() {
         LocalBluetoothLeBroadcast broadcast =
                 mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
index 026a305..a6cf408 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -99,12 +99,17 @@
 
     @Override
     public boolean isBroadcastSupported() {
-        return mMediaOutputController.isBroadcastSupported();
+        boolean isBluetoothLeDevice = false;
+        if (mMediaOutputController.getCurrentConnectedMediaDevice() != null) {
+            isBluetoothLeDevice = mMediaOutputController.isBluetoothLeDevice(
+                    mMediaOutputController.getCurrentConnectedMediaDevice());
+        }
+        return mMediaOutputController.isBroadcastSupported() && isBluetoothLeDevice;
     }
 
     @Override
     public CharSequence getStopButtonText() {
-        int resId = R.string.media_output_dialog_button_stop_casting;
+        int resId = R.string.keyboard_key_media_stop;
         if (isBroadcastSupported() && mMediaOutputController.isPlaying()
                 && !mMediaOutputController.isBluetoothLeBroadcastEnabled()) {
             resId = R.string.media_output_broadcast;
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
index 5581fb8..8249a7c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
@@ -21,8 +21,10 @@
 import android.media.session.MediaSessionManager
 import android.os.PowerExemptionManager
 import android.view.View
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.UiEventLogger
 import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.media.nearby.NearbyMediaDevicesManager
@@ -48,6 +50,7 @@
     private val powerExemptionManager: PowerExemptionManager
 ) {
     companion object {
+        private const val INTERACTION_JANK_TAG = "media_output"
         var mediaOutputDialog: MediaOutputDialog? = null
     }
 
@@ -67,7 +70,13 @@
 
         // Show the dialog.
         if (view != null) {
-            dialogLaunchAnimator.showFromView(dialog, view)
+            dialogLaunchAnimator.showFromView(
+                dialog, view,
+                cuj = DialogCuj(
+                    InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                    INTERACTION_JANK_TAG
+                )
+            )
         } else {
             dialog.show()
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamComplication.java b/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamComplication.java
index 7c04810..2c35db3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamComplication.java
@@ -37,11 +37,6 @@
     }
 
     @Override
-    public int getRequiredTypeAvailability() {
-        return COMPLICATION_TYPE_CAST_INFO;
-    }
-
-    @Override
     public ViewHolder createView(ComplicationViewModel model) {
         return mComponentFactory.create().getViewHolder();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
index 3cc99a8..e95976f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
@@ -27,4 +27,4 @@
     fun getTimeoutMs(): Long
 }
 
-const val DEFAULT_TIMEOUT_MILLIS = 3000L
+const val DEFAULT_TIMEOUT_MILLIS = 4000L
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
index 7cc52e4..fe1ac80 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
@@ -31,6 +31,10 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManager
+import android.view.accessibility.AccessibilityManager
+import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTROLS
+import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS
+import android.view.accessibility.AccessibilityManager.FLAG_CONTENT_TEXT
 import android.widget.LinearLayout
 import com.android.internal.widget.CachingIconView
 import com.android.settingslib.Utils
@@ -56,6 +60,7 @@
     private val windowManager: WindowManager,
     private val viewUtil: ViewUtil,
     @Main private val mainExecutor: DelayableExecutor,
+    private val accessibilityManager: AccessibilityManager,
     private val tapGestureDetector: TapGestureDetector,
     private val powerManager: PowerManager,
     @LayoutRes private val chipLayoutRes: Int
@@ -110,10 +115,16 @@
         }
 
         // Cancel and re-set the chip timeout each time we get a new state.
+        val timeout = accessibilityManager.getRecommendedTimeoutMillis(
+            chipInfo.getTimeoutMs().toInt(),
+            // Not all chips have controls so FLAG_CONTENT_CONTROLS might be superfluous, but
+            // include it just to be safe.
+            FLAG_CONTENT_ICONS or FLAG_CONTENT_TEXT or FLAG_CONTENT_CONTROLS
+       )
         cancelChipViewTimeout?.run()
         cancelChipViewTimeout = mainExecutor.executeDelayed(
             { removeChip(MediaTttRemovalReason.REASON_TIMEOUT) },
-            chipInfo.getTimeoutMs()
+            timeout.toLong()
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index 072263f..a5d763c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -26,6 +26,7 @@
 import android.util.Log
 import android.view.ViewGroup
 import android.view.WindowManager
+import android.view.accessibility.AccessibilityManager
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
@@ -52,6 +53,7 @@
     windowManager: WindowManager,
     viewUtil: ViewUtil,
     mainExecutor: DelayableExecutor,
+    accessibilityManager: AccessibilityManager,
     tapGestureDetector: TapGestureDetector,
     powerManager: PowerManager,
     @Main private val mainHandler: Handler,
@@ -62,6 +64,7 @@
     windowManager,
     viewUtil,
     mainExecutor,
+    accessibilityManager,
     tapGestureDetector,
     powerManager,
     R.layout.media_ttt_chip_receiver
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
index 54b4380..943604c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
@@ -24,6 +24,7 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManager
+import android.view.accessibility.AccessibilityManager
 import android.widget.TextView
 import com.android.internal.statusbar.IUndoMediaTransferCallback
 import com.android.systemui.R
@@ -53,6 +54,7 @@
     windowManager: WindowManager,
     viewUtil: ViewUtil,
     @Main mainExecutor: DelayableExecutor,
+    accessibilityManager: AccessibilityManager,
     tapGestureDetector: TapGestureDetector,
     powerManager: PowerManager,
     private val uiEventLogger: MediaTttSenderUiEventLogger
@@ -62,6 +64,7 @@
     windowManager,
     viewUtil,
     mainExecutor,
+    accessibilityManager,
     tapGestureDetector,
     powerManager,
     R.layout.media_ttt_chip
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
index 779292c..6bc50a6 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
@@ -17,11 +17,19 @@
 package com.android.systemui.navigationbar;
 
 import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU;
+import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
 
 import static com.android.systemui.accessibility.SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON;
 import static com.android.systemui.accessibility.SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 
 import android.content.ContentResolver;
 import android.content.Context;
@@ -50,6 +58,7 @@
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import java.io.PrintWriter;
@@ -325,6 +334,23 @@
         void updateAssistantAvailable(boolean available);
     }
 
+    static @TransitionMode int transitionMode(boolean isTransient, int appearance) {
+        final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_NAVIGATION_BARS;
+        if (isTransient) {
+            return MODE_SEMI_TRANSPARENT;
+        } else if ((appearance & lightsOutOpaque) == lightsOutOpaque) {
+            return MODE_LIGHTS_OUT;
+        } else if ((appearance & APPEARANCE_LOW_PROFILE_BARS) != 0) {
+            return MODE_LIGHTS_OUT_TRANSPARENT;
+        } else if ((appearance & APPEARANCE_OPAQUE_NAVIGATION_BARS) != 0) {
+            return MODE_OPAQUE;
+        } else if ((appearance & APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS) != 0) {
+            return MODE_SEMI_TRANSPARENT;
+        } else {
+            return MODE_TRANSPARENT;
+        }
+    }
+
     @Override
     public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
         pw.println("NavbarTaskbarFriendster");
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index aa38b78..730f88a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -27,9 +27,6 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.containsType;
-import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
@@ -39,6 +36,7 @@
 import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NAV_BAR_HANDLE_FORCE_OPAQUE;
+import static com.android.systemui.navigationbar.NavBarHelper.transitionMode;
 import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
 import static com.android.systemui.shared.recents.utilities.Utilities.isTablet;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
@@ -48,11 +46,7 @@
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
 import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG_WINDOW_STATE;
 import static com.android.systemui.statusbar.phone.CentralSurfaces.dumpBarTransitions;
@@ -86,7 +80,7 @@
 import android.view.Display;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
-import android.view.InsetsState;
+import android.view.InsetsFrameProvider;
 import android.view.InsetsState.InternalInsetsType;
 import android.view.InsetsVisibilities;
 import android.view.KeyEvent;
@@ -215,8 +209,8 @@
     private final UiEventLogger mUiEventLogger;
     private final NavBarHelper mNavBarHelper;
     private final NotificationShadeDepthController mNotificationShadeDepthController;
-    private final UserContextProvider mUserContextProvider;
     private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener;
+    private final UserContextProvider mUserContextProvider;
     private final RegionSamplingHelper mRegionSamplingHelper;
     private final int mNavColorSampleMargin;
     private NavigationBarFrame mFrame;
@@ -1152,23 +1146,6 @@
         return false;
     }
 
-    private static @TransitionMode int transitionMode(boolean isTransient, int appearance) {
-        final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_NAVIGATION_BARS;
-        if (isTransient) {
-            return MODE_SEMI_TRANSPARENT;
-        } else if ((appearance & lightsOutOpaque) == lightsOutOpaque) {
-            return MODE_LIGHTS_OUT;
-        } else if ((appearance & APPEARANCE_LOW_PROFILE_BARS) != 0) {
-            return MODE_LIGHTS_OUT_TRANSPARENT;
-        } else if ((appearance & APPEARANCE_OPAQUE_NAVIGATION_BARS) != 0) {
-            return MODE_OPAQUE;
-        } else if ((appearance & APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS) != 0) {
-            return MODE_SEMI_TRANSPARENT;
-        } else {
-            return MODE_TRANSPARENT;
-        }
-    }
-
     @Override
     public void disable(int displayId, int state1, int state2, boolean animate) {
         if (displayId != mDisplayId) {
@@ -1654,12 +1631,14 @@
                         | WindowManager.LayoutParams.FLAG_SLIPPERY,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = gravity;
-        lp.providedInternalInsets = new Insets[InsetsState.SIZE];
         if (insetsHeight != -1) {
-            lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] =
-                    Insets.of(0, height - insetsHeight, 0, 0);
+            lp.providedInsets = new InsetsFrameProvider[] {
+                new InsetsFrameProvider(ITYPE_NAVIGATION_BAR, Insets.of(0, 0, 0, insetsHeight))
+            };
         } else {
-            lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] = null;
+            lp.providedInsets = new InsetsFrameProvider[] {
+                    new InsetsFrameProvider(ITYPE_NAVIGATION_BAR)
+            };
         }
         lp.token = new Binder();
         lp.accessibilityTitle = userContext.getString(R.string.nav_bar);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index d756af7..2a7c871 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -69,7 +69,6 @@
 
 import javax.inject.Inject;
 
-
 /** A controller to handle navigation bars. */
 @SysUISingleton
 public class NavigationBarController implements
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 3fc9afe..ad3cfa3 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -812,6 +812,7 @@
         mImeDrawsImeNavBar = imeDrawsImeNavBar;
         mBarTransitions.onNavigationModeChanged(mNavBarMode);
         mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode);
+        mRotationButtonController.onNavigationModeChanged(mNavBarMode);
         updateRotationButton();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index 8ee16a9..1abf990 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -24,6 +24,7 @@
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
+import static com.android.systemui.navigationbar.NavBarHelper.transitionMode;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
@@ -35,6 +36,7 @@
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 
 import android.app.StatusBarManager;
 import android.app.StatusBarManager.WindowVisibleState;
@@ -50,6 +52,7 @@
 import android.view.Display;
 import android.view.InsetsVisibilities;
 import android.view.View;
+import android.view.WindowInsetsController.Appearance;
 import android.view.WindowInsetsController.Behavior;
 
 import androidx.annotation.NonNull;
@@ -114,6 +117,9 @@
             };
     private int mDisabledFlags;
     private @WindowVisibleState int mTaskBarWindowState = WINDOW_STATE_SHOWING;
+
+    private @TransitionMode int mTransitionMode;
+    private @Appearance int mAppearance;
     private @Behavior int mBehavior;
     private final Context mContext;
     private final DisplayManager mDisplayManager;
@@ -146,19 +152,12 @@
         }
     };
 
-    private final Consumer<Boolean> mNavbarOverlayVisibilityChangeCallback = (visible) -> {
-        if (visible) {
-            mAutoHideController.touchAutoHide();
-        }
-    };
     private BackAnimation mBackAnimation;
 
     @Inject
-    public TaskbarDelegate(
-            Context context,
+    public TaskbarDelegate(Context context,
             EdgeBackGestureHandler.Factory edgeBackGestureHandlerFactory,
-            LightBarTransitionsController.Factory lightBarTransitionsControllerFactory
-    ) {
+            LightBarTransitionsController.Factory lightBarTransitionsControllerFactory) {
         mLightBarTransitionsControllerFactory = lightBarTransitionsControllerFactory;
         mEdgeBackGestureHandler = edgeBackGestureHandlerFactory.create(context);
 
@@ -360,9 +359,15 @@
             AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme, int behavior,
             InsetsVisibilities requestedVisibilities, String packageName) {
         mOverviewProxyService.onSystemBarAttributesChanged(displayId, behavior);
-        if (mLightBarController != null && displayId == mDisplayId) {
-            mLightBarController.onNavigationBarAppearanceChanged(appearance, false/*nbModeChanged*/,
-                    BarTransitions.MODE_TRANSPARENT /*navigationBarMode*/, navbarColorManagedByIme);
+        boolean nbModeChanged = false;
+        if (mAppearance != appearance) {
+            mAppearance = appearance;
+            nbModeChanged = updateTransitionMode(
+                    transitionMode(mTaskbarTransientShowing, appearance));
+        }
+        if (displayId == mDisplayId) {
+            mLightBarController.onNavigationBarAppearanceChanged(appearance, nbModeChanged,
+                    BarTransitions.MODE_TRANSPARENT, navbarColorManagedByIme);
         }
         if (mBehavior != behavior) {
             mBehavior = behavior;
@@ -413,6 +418,22 @@
 
     private void onTransientStateChanged() {
         mEdgeBackGestureHandler.onNavBarTransientStateChanged(mTaskbarTransientShowing);
+
+        final int transitionMode = transitionMode(mTaskbarTransientShowing, mAppearance);
+        if (updateTransitionMode(transitionMode)) {
+            mLightBarController.onNavigationBarModeChanged(transitionMode);
+        }
+    }
+
+    private boolean updateTransitionMode(int barMode) {
+        if (mTransitionMode != barMode) {
+            mTransitionMode = barMode;
+            if (mAutoHideController != null) {
+                mAutoHideController.touchAutoHide();
+            }
+            return true;
+        }
+        return false;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
new file mode 100644
index 0000000..2822435
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
@@ -0,0 +1,397 @@
+package com.android.systemui.navigationbar.gestural
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.RectF
+import android.view.View
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+import androidx.dynamicanimation.animation.SpringAnimation
+import androidx.dynamicanimation.animation.SpringForce
+import com.android.internal.util.LatencyTracker
+import com.android.settingslib.Utils
+import com.android.systemui.navigationbar.gestural.BackPanelController.DelayedOnAnimationEndListener
+
+private const val TAG = "BackPanel"
+private const val DEBUG = false
+
+class BackPanel(context: Context, private val latencyTracker: LatencyTracker) : View(context) {
+
+    var arrowsPointLeft = false
+        set(value) {
+            if (field != value) {
+                invalidate()
+                field = value
+            }
+        }
+
+    // Arrow color and shape
+    private val arrowPath = Path()
+    private val arrowPaint = Paint()
+
+    // Arrow background color and shape
+    private var arrowBackgroundRect = RectF()
+    private var arrowBackgroundPaint = Paint()
+
+    // True if the panel is currently on the left of the screen
+    var isLeftPanel = false
+
+    /**
+     * Used to track back arrow latency from [android.view.MotionEvent.ACTION_DOWN] to [onDraw]
+     */
+    private var trackingBackArrowLatency = false
+
+    /**
+     * The length of the arrow measured horizontally. Used for animating [arrowPath]
+     */
+    private var arrowLength = AnimatedFloat("arrowLength", SpringForce())
+
+    /**
+     * The height of the arrow measured vertically from its center to its top (i.e. half the total
+     * height). Used for animating [arrowPath]
+     */
+    private var arrowHeight = AnimatedFloat("arrowHeight", SpringForce())
+
+    private val backgroundWidth = AnimatedFloat(
+        name = "backgroundWidth",
+        SpringForce().apply {
+            stiffness = 600f
+            dampingRatio = 0.65f
+        }
+    )
+
+    private val backgroundHeight = AnimatedFloat(
+        name = "backgroundHeight",
+        SpringForce().apply {
+            stiffness = 600f
+            dampingRatio = 0.65f
+        }
+    )
+
+    /**
+     * Corners of the background closer to the edge of the screen (where the arrow appeared from).
+     * Used for animating [arrowBackgroundRect]
+     */
+    private val backgroundEdgeCornerRadius = AnimatedFloat(
+        name = "backgroundEdgeCornerRadius",
+        SpringForce().apply {
+            stiffness = 400f
+            dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY
+        }
+    )
+
+    /**
+     * Corners of the background further from the edge of the screens (toward the direction the
+     * arrow is being dragged). Used for animating [arrowBackgroundRect]
+     */
+    private val backgroundFarCornerRadius = AnimatedFloat(
+        name = "backgroundDragCornerRadius",
+        SpringForce().apply {
+            stiffness = 2200f
+            dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
+        }
+    )
+
+    /**
+     * Left/right position of the background relative to the canvas. Also corresponds with the
+     * background's margin relative to the screen edge. The arrow will be centered within the
+     * background.
+     */
+    private var horizontalTranslation = AnimatedFloat("horizontalTranslation", SpringForce())
+
+    private val currentAlpha: FloatPropertyCompat<BackPanel> =
+        object : FloatPropertyCompat<BackPanel>("currentAlpha") {
+            override fun setValue(panel: BackPanel, value: Float) {
+                panel.alpha = value
+            }
+
+            override fun getValue(panel: BackPanel): Float = panel.alpha
+        }
+
+    private val alphaAnimation = SpringAnimation(this, currentAlpha)
+        .setSpring(
+            SpringForce()
+                .setStiffness(60f)
+                .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)
+        )
+
+    /**
+     * Canvas vertical translation. How far up/down the arrow and background appear relative to the
+     * canvas.
+     */
+    private var verticalTranslation: AnimatedFloat = AnimatedFloat(
+        name = "verticalTranslation",
+        SpringForce().apply {
+            stiffness = SpringForce.STIFFNESS_MEDIUM
+        }
+    )
+
+    /**
+     * Use for drawing debug info. Can only be set if [DEBUG]=true
+     */
+    var drawDebugInfo: ((canvas: Canvas) -> Unit)? = null
+        set(value) {
+            if (DEBUG) field = value
+        }
+
+    internal fun updateArrowPaint(arrowThickness: Float) {
+        // Arrow constants
+        arrowPaint.strokeWidth = arrowThickness
+
+        arrowPaint.color =
+            Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
+        arrowBackgroundPaint.color = Utils.getColorAccentDefaultColor(context)
+    }
+
+    private inner class AnimatedFloat(name: String, springForce: SpringForce) {
+        // The resting position when not stretched by a touch drag
+        private var restingPosition = 0f
+
+        // The current position as updated by the SpringAnimation
+        var pos = 0f
+            set(v) {
+                if (field != v) {
+                    field = v
+                    invalidate()
+                }
+            }
+
+        val animation: SpringAnimation
+
+        init {
+            val floatProp = object : FloatPropertyCompat<AnimatedFloat>(name) {
+                override fun setValue(animatedFloat: AnimatedFloat, value: Float) {
+                    animatedFloat.pos = value
+                }
+
+                override fun getValue(animatedFloat: AnimatedFloat): Float = animatedFloat.pos
+            }
+            animation = SpringAnimation(this, floatProp)
+            animation.spring = springForce
+        }
+
+        fun snapTo(newPosition: Float) {
+            animation.cancel()
+            restingPosition = newPosition
+            animation.spring.finalPosition = newPosition
+            pos = newPosition
+        }
+
+        fun stretchTo(stretchAmount: Float) {
+            animation.animateToFinalPosition(restingPosition + stretchAmount)
+        }
+
+        /**
+         * Animates to a new position ([finalPosition]) that is the given fraction ([amount])
+         * between the existing [restingPosition] and the new [finalPosition].
+         *
+         * The [restingPosition] will remain unchanged. Only the animation is updated.
+         */
+        fun stretchBy(finalPosition: Float, amount: Float) {
+            val stretchedAmount = amount * (finalPosition - restingPosition)
+            animation.animateToFinalPosition(restingPosition + stretchedAmount)
+        }
+
+        fun updateRestingPosition(pos: Float, animated: Boolean) {
+            restingPosition = pos
+            if (animated)
+                animation.animateToFinalPosition(restingPosition)
+            else
+                snapTo(restingPosition)
+        }
+    }
+
+    init {
+        visibility = GONE
+        arrowPaint.apply {
+            style = Paint.Style.STROKE
+            strokeCap = Paint.Cap.SQUARE
+        }
+        arrowBackgroundPaint.apply {
+            style = Paint.Style.FILL
+            strokeJoin = Paint.Join.ROUND
+            strokeCap = Paint.Cap.ROUND
+        }
+    }
+
+    private fun calculateArrowPath(dx: Float, dy: Float): Path {
+        arrowPath.reset()
+        arrowPath.moveTo(dx, -dy)
+        arrowPath.lineTo(0f, 0f)
+        arrowPath.lineTo(dx, dy)
+        arrowPath.moveTo(dx, -dy)
+        return arrowPath
+    }
+
+    fun addEndListener(endListener: DelayedOnAnimationEndListener): Boolean {
+        return if (alphaAnimation.isRunning) {
+            alphaAnimation.addEndListener(endListener)
+            true
+        } else if (horizontalTranslation.animation.isRunning) {
+            horizontalTranslation.animation.addEndListener(endListener)
+            true
+        } else {
+            endListener.runNow()
+            false
+        }
+    }
+
+    fun setStretch(
+        horizontalTranslationStretchAmount: Float,
+        arrowStretchAmount: Float,
+        backgroundWidthStretchAmount: Float,
+        fullyStretchedDimens: EdgePanelParams.BackIndicatorDimens
+    ) {
+        horizontalTranslation.stretchBy(
+            finalPosition = fullyStretchedDimens.horizontalTranslation,
+            amount = horizontalTranslationStretchAmount
+        )
+        arrowLength.stretchBy(
+            finalPosition = fullyStretchedDimens.arrowDimens.length,
+            amount = arrowStretchAmount
+        )
+        arrowHeight.stretchBy(
+            finalPosition = fullyStretchedDimens.arrowDimens.height,
+            amount = arrowStretchAmount
+        )
+        backgroundWidth.stretchBy(
+            finalPosition = fullyStretchedDimens.backgroundDimens.width,
+            amount = backgroundWidthStretchAmount
+        )
+    }
+
+    fun resetStretch() {
+        horizontalTranslation.stretchTo(0f)
+        arrowLength.stretchTo(0f)
+        arrowHeight.stretchTo(0f)
+        backgroundWidth.stretchTo(0f)
+        backgroundHeight.stretchTo(0f)
+        backgroundEdgeCornerRadius.stretchTo(0f)
+        backgroundFarCornerRadius.stretchTo(0f)
+    }
+
+    /**
+     * Updates resting arrow and background size not accounting for stretch
+     */
+    internal fun setRestingDimens(
+        restingParams: EdgePanelParams.BackIndicatorDimens,
+        animate: Boolean
+    ) {
+        horizontalTranslation.updateRestingPosition(restingParams.horizontalTranslation, animate)
+        arrowLength.updateRestingPosition(restingParams.arrowDimens.length, animate)
+        arrowHeight.updateRestingPosition(restingParams.arrowDimens.height, animate)
+        backgroundWidth.updateRestingPosition(restingParams.backgroundDimens.width, animate)
+        backgroundHeight.updateRestingPosition(restingParams.backgroundDimens.height, animate)
+        backgroundEdgeCornerRadius.updateRestingPosition(
+            restingParams.backgroundDimens.edgeCornerRadius,
+            animate
+        )
+        backgroundFarCornerRadius.updateRestingPosition(
+            restingParams.backgroundDimens.farCornerRadius,
+            animate
+        )
+    }
+
+    fun animateVertically(yPos: Float) = verticalTranslation.stretchTo(yPos)
+
+    fun setArrowStiffness(arrowStiffness: Float, arrowDampingRatio: Float) {
+        arrowLength.animation.spring.apply {
+            stiffness = arrowStiffness
+            dampingRatio = arrowDampingRatio
+        }
+        arrowHeight.animation.spring.apply {
+            stiffness = arrowStiffness
+            dampingRatio = arrowDampingRatio
+        }
+    }
+
+    override fun hasOverlappingRendering() = false
+
+    override fun onDraw(canvas: Canvas) {
+        var edgeCorner = backgroundEdgeCornerRadius.pos
+        val farCorner = backgroundFarCornerRadius.pos
+        val halfHeight = backgroundHeight.pos / 2
+
+        canvas.save()
+
+        if (!isLeftPanel) canvas.scale(-1f, 1f, width / 2.0f, 0f)
+
+        canvas.translate(
+            horizontalTranslation.pos,
+            height * 0.5f + verticalTranslation.pos
+        )
+
+        val arrowBackground = arrowBackgroundRect.apply {
+            left = 0f
+            top = -halfHeight
+            right = backgroundWidth.pos
+            bottom = halfHeight
+        }.toPathWithRoundCorners(
+            topLeft = edgeCorner,
+            bottomLeft = edgeCorner,
+            topRight = farCorner,
+            bottomRight = farCorner
+        )
+        canvas.drawPath(arrowBackground, arrowBackgroundPaint)
+
+        val dx = arrowLength.pos
+        val dy = arrowHeight.pos
+
+        // How far the arrow bounding box should be from the edge of the screen. Measured from
+        // either the tip or the back of the arrow, whichever is closer
+        var arrowOffset = (backgroundWidth.pos - dx) / 2
+        canvas.translate(
+            /* dx= */ arrowOffset,
+            /* dy= */ 0f /* pass 0 for the y position since the canvas was already translated */
+        )
+
+        val arrowPointsAwayFromEdge = !arrowsPointLeft.xor(isLeftPanel)
+        if (arrowPointsAwayFromEdge) {
+            canvas.apply {
+                scale(-1f, 1f, 0f, 0f)
+                translate(-dx, 0f)
+            }
+        }
+
+        val arrowPath = calculateArrowPath(dx = dx, dy = dy)
+        canvas.drawPath(arrowPath, arrowPaint)
+        canvas.restore()
+
+        if (trackingBackArrowLatency) {
+            latencyTracker.onActionEnd(LatencyTracker.ACTION_SHOW_BACK_ARROW)
+            trackingBackArrowLatency = false
+        }
+
+        if (DEBUG) drawDebugInfo?.invoke(canvas)
+    }
+
+    fun startTrackingShowBackArrowLatency() {
+        latencyTracker.onActionStart(LatencyTracker.ACTION_SHOW_BACK_ARROW)
+        trackingBackArrowLatency = true
+    }
+
+    private fun RectF.toPathWithRoundCorners(
+        topLeft: Float = 0f,
+        topRight: Float = 0f,
+        bottomRight: Float = 0f,
+        bottomLeft: Float = 0f
+    ): Path = Path().apply {
+        val corners = floatArrayOf(
+            topLeft, topLeft,
+            topRight, topRight,
+            bottomRight, bottomRight,
+            bottomLeft, bottomLeft
+        )
+        addRoundRect(this@toPathWithRoundCorners, corners, Path.Direction.CW)
+    }
+
+    fun cancelAlphaAnimations() {
+        alphaAnimation.cancel()
+        alpha = 1f
+    }
+
+    fun fadeOut() {
+        alphaAnimation.animateToFinalPosition(0f)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
new file mode 100644
index 0000000..8179d17
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -0,0 +1,727 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.navigationbar.gestural
+
+import android.content.Context
+import android.content.res.Configuration
+import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.Point
+import android.os.Handler
+import android.os.SystemClock
+import android.os.VibrationEffect
+import android.util.Log
+import android.util.MathUtils.constrain
+import android.util.MathUtils.saturate
+import android.view.Gravity
+import android.view.MotionEvent
+import android.view.VelocityTracker
+import android.view.View
+import android.view.WindowManager
+import android.view.animation.DecelerateInterpolator
+import android.view.animation.PathInterpolator
+import android.window.BackEvent
+import androidx.dynamicanimation.animation.DynamicAnimation
+import androidx.dynamicanimation.animation.SpringForce
+import com.android.internal.util.LatencyTracker
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.NavigationEdgeBackPlugin
+import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.ViewController
+import com.android.wm.shell.back.BackAnimation
+import java.io.PrintWriter
+import javax.inject.Inject
+import kotlin.math.abs
+import kotlin.math.max
+import kotlin.math.min
+import kotlin.math.sign
+
+private const val TAG = "BackPanelController"
+private const val DEBUG = false
+
+private const val ENABLE_FAILSAFE = true
+
+private const val FAILSAFE_DELAY_MS: Long = 350
+
+/**
+ * The time required between the arrow-appears vibration effect and the back-committed vibration
+ * effect. If the arrow is flung quickly, the phone only vibrates once. However, if the arrow is
+ * held on the screen for a long time, it will vibrate a second time when the back gesture is
+ * committed.
+ */
+private const val GESTURE_DURATION_FOR_CLICK_MS = 400
+
+/**
+ * The min duration arrow remains on screen during a fling event.
+ */
+private const val FLING_MIN_APPEARANCE_DURATION = 235L
+
+/**
+ * The min duration arrow remains on screen during a fling event.
+ */
+private const val MIN_FLING_VELOCITY = 3000
+
+/**
+ * The amount of rubber banding we do for the vertical translation
+ */
+private const val RUBBER_BAND_AMOUNT = 15
+
+private const val ARROW_APPEAR_STIFFNESS = 600f
+private const val ARROW_APPEAR_DAMPING_RATIO = 0.4f
+private const val ARROW_DISAPPEAR_STIFFNESS = 1200f
+private const val ARROW_DISAPPEAR_DAMPING_RATIO = SpringForce.DAMPING_RATIO_NO_BOUNCY
+
+/**
+ * The interpolator used to rubber band
+ */
+private val RUBBER_BAND_INTERPOLATOR = PathInterpolator(1.0f / 5.0f, 1.0f, 1.0f, 1.0f)
+
+private val DECELERATE_INTERPOLATOR = DecelerateInterpolator()
+
+private val DECELERATE_INTERPOLATOR_SLOW = DecelerateInterpolator(0.7f)
+
+class BackPanelController private constructor(
+    context: Context,
+    private var backAnimation: BackAnimation?,
+    private val windowManager: WindowManager,
+    @Main private val mainHandler: Handler,
+    private val vibratorHelper: VibratorHelper,
+    private val configurationController: ConfigurationController,
+    latencyTracker: LatencyTracker
+) : ViewController<BackPanel>(BackPanel(context, latencyTracker)), NavigationEdgeBackPlugin {
+
+    /**
+     * Injectable instance to create a new BackPanelController.
+     *
+     * Necessary because EdgeBackGestureHandler sometimes needs to create new instances of
+     * BackPanelController, and we need to match EdgeBackGestureHandler's context.
+     */
+    class Factory @Inject constructor(
+        private val windowManager: WindowManager,
+        @Main private val mainHandler: Handler,
+        private val vibratorHelper: VibratorHelper,
+        private val configurationController: ConfigurationController,
+        private val latencyTracker: LatencyTracker
+    ) {
+        /** Construct a [BackPanelController].  */
+        fun create(context: Context, backAnimation: BackAnimation?): BackPanelController {
+            val backPanelController = BackPanelController(
+                context,
+                backAnimation,
+                windowManager,
+                mainHandler,
+                vibratorHelper,
+                configurationController,
+                latencyTracker
+            )
+            backPanelController.init()
+            return backPanelController
+        }
+    }
+
+    private var params: EdgePanelParams = EdgePanelParams(resources)
+    private var currentState: GestureState = GestureState.GONE
+    private var previousState: GestureState = GestureState.GONE
+
+    // Phone should only vibrate the first time the arrow is activated
+    private var hasHapticPlayed = false
+
+    // Screen attributes
+    private lateinit var layoutParams: WindowManager.LayoutParams
+    private val displaySize = Point()
+
+    private lateinit var backCallback: NavigationEdgeBackPlugin.BackCallback
+
+    private var previousXTranslation = 0f
+    private var totalTouchDelta = 0f
+    private var velocityTracker: VelocityTracker? = null
+        set(value) {
+            if (field != value) field?.recycle()
+            field = value
+        }
+        get() {
+            if (field == null) field = VelocityTracker.obtain()
+            return field
+        }
+
+    // The x,y position of the first touch event
+    private var startX = 0f
+    private var startY = 0f
+
+    private var gestureStartTime = 0L
+
+    private val failsafeRunnable = Runnable { onFailsafe() }
+
+    private enum class GestureState {
+        /* Arrow is off the screen and invisible */
+        GONE,
+
+        /* Arrow is animating in */
+        ENTRY,
+
+        /* could be entry, neutral, or stretched, releasing will commit back */
+        ACTIVE,
+
+        /* releasing will cancel back */
+        INACTIVE,
+
+        /* like committed, but animation takes longer */
+        FLUNG,
+
+        /* back action currently occurring, arrow soon to be GONE */
+        COMMITTED,
+
+        /* back action currently cancelling, arrow soon to be GONE */
+        CANCELLED;
+
+        /**
+         * @return true if the current state responds to touch move events in some way (e.g. by
+         * stretching the back indicator)
+         */
+        fun isInteractive(): Boolean {
+            return when (this) {
+                ENTRY, ACTIVE, INACTIVE -> true
+                GONE, FLUNG, COMMITTED, CANCELLED -> false
+            }
+        }
+    }
+
+    /**
+     * Wrapper around OnAnimationEndListener which runs the given runnable after a delay. The
+     * runnable is not called if the animation is cancelled
+     */
+    inner class DelayedOnAnimationEndListener internal constructor(
+        private val handler: Handler,
+        private val runnable: Runnable,
+        private val minDuration: Long
+    ) : DynamicAnimation.OnAnimationEndListener {
+        override fun onAnimationEnd(
+            animation: DynamicAnimation<*>,
+            canceled: Boolean,
+            value: Float,
+            velocity: Float
+        ) {
+            animation.removeEndListener(this)
+            if (!canceled) {
+                // Total elapsed time of the gesture and the animation
+                val totalElapsedTime = SystemClock.uptimeMillis() - gestureStartTime
+                // The delay between finishing this animation and starting the runnable
+                val delay = max(0, minDuration - totalElapsedTime)
+                handler.postDelayed(runnable, delay)
+            }
+        }
+
+        internal fun runNow() {
+            runnable.run()
+        }
+    }
+
+    private val setCommittedEndListener =
+        DelayedOnAnimationEndListener(
+            mainHandler,
+            { updateArrowState(GestureState.COMMITTED) },
+            minDuration = FLING_MIN_APPEARANCE_DURATION
+        )
+
+    private val setGoneEndListener =
+        DelayedOnAnimationEndListener(
+            mainHandler,
+            {
+                cancelFailsafe()
+                updateArrowState(GestureState.GONE)
+            },
+            minDuration = 0
+        )
+
+    // Vibration
+    private var vibrationTime: Long = 0
+
+    // Minimum of the screen's width or the predefined threshold
+    private var fullyStretchedThreshold = 0f
+
+    /**
+     * Used for initialization and configuration changes
+     */
+    private fun updateConfiguration() {
+        params.update(resources)
+        updateBackAnimationSwipeThresholds()
+        mView.updateArrowPaint(params.arrowThickness)
+    }
+
+    private val configurationListener = object : ConfigurationController.ConfigurationListener {
+        override fun onConfigChanged(newConfig: Configuration?) {
+            updateConfiguration()
+        }
+
+        override fun onLayoutDirectionChanged(isLayoutRtl: Boolean) {
+            updateArrowDirection(isLayoutRtl)
+        }
+    }
+
+    override fun onViewAttached() {
+        updateConfiguration()
+        updateArrowDirection(configurationController.isLayoutRtl)
+        updateArrowState(GestureState.GONE, force = true)
+        updateRestingArrowDimens(animated = false, currentState)
+        configurationController.addCallback(configurationListener)
+    }
+
+    /** Update the arrow direction. The arrow should point the same way for both panels. */
+    private fun updateArrowDirection(isLayoutRtl: Boolean) {
+        mView.arrowsPointLeft = isLayoutRtl
+    }
+
+    override fun onViewDetached() {
+        configurationController.removeCallback(configurationListener)
+    }
+
+    override fun onMotionEvent(event: MotionEvent) {
+        backAnimation?.onBackMotion(
+            event.x,
+            event.y,
+            event.actionMasked,
+            if (mView.isLeftPanel) BackEvent.EDGE_LEFT else BackEvent.EDGE_RIGHT
+        )
+
+        velocityTracker!!.addMovement(event)
+        when (event.actionMasked) {
+            MotionEvent.ACTION_DOWN -> {
+                resetOnDown()
+                startX = event.x
+                startY = event.y
+                gestureStartTime = SystemClock.uptimeMillis()
+
+                // Reset the arrow to the side
+                updateArrowState(GestureState.ENTRY)
+
+                windowManager.updateViewLayout(mView, layoutParams)
+                mView.startTrackingShowBackArrowLatency()
+            }
+            MotionEvent.ACTION_MOVE -> handleMoveEvent(event)
+            MotionEvent.ACTION_UP -> {
+                if (currentState == GestureState.ACTIVE) {
+                    updateArrowState(if (isFlung()) GestureState.FLUNG else GestureState.COMMITTED)
+                } else {
+                    updateArrowState(GestureState.CANCELLED)
+                }
+                velocityTracker = null
+            }
+            MotionEvent.ACTION_CANCEL -> {
+                updateArrowState(GestureState.CANCELLED)
+                velocityTracker = null
+            }
+        }
+    }
+
+    private fun updateArrowStateOnMove(yTranslation: Float, xTranslation: Float) {
+        if (!currentState.isInteractive())
+            return
+
+        when (currentState) {
+            // Check if we should transition from ENTRY to ACTIVE
+            GestureState.ENTRY ->
+                if (xTranslation > params.swipeTriggerThreshold) {
+                    updateArrowState(GestureState.ACTIVE)
+                }
+
+            // Abort if we had continuous motion toward the edge for a while, OR the direction
+            // in Y is bigger than X * 2
+            GestureState.ACTIVE ->
+                if ((totalTouchDelta < 0 && -totalTouchDelta > params.minDeltaForSwitch) ||
+                    (yTranslation > xTranslation * 2)
+                ) {
+                    updateArrowState(GestureState.INACTIVE)
+                }
+
+            //  Re-activate if we had continuous motion away from the edge for a while
+            GestureState.INACTIVE ->
+                if (totalTouchDelta > 0 && totalTouchDelta > params.minDeltaForSwitch) {
+                    updateArrowState(GestureState.ACTIVE)
+                }
+
+            // By default assume the current direction is kept
+            else -> {}
+        }
+    }
+
+    private fun handleMoveEvent(event: MotionEvent) {
+        if (!currentState.isInteractive())
+            return
+
+        val x = event.x
+        val y = event.y
+
+        val yOffset = y - startY
+
+        // How far in the y direction we are from the original touch
+        val yTranslation = abs(yOffset)
+
+        // How far in the x direction we are from the original touch ignoring motion that
+        // occurs between the screen edge and the touch start.
+        val xTranslation = max(0f, if (mView.isLeftPanel) x - startX else startX - x)
+
+        // Compared to last time, how far we moved in the x direction. If <0, we are moving closer
+        // to the edge. If >0, we are moving further from the edge
+        val xDelta = xTranslation - previousXTranslation
+        previousXTranslation = xTranslation
+
+        if (abs(xDelta) > 0) {
+            if (sign(xDelta) == sign(totalTouchDelta)) {
+                // Direction has NOT changed, so keep counting the delta
+                totalTouchDelta += xDelta
+            } else {
+                // Direction has changed, so reset the delta
+                totalTouchDelta = xDelta
+            }
+        }
+
+        updateArrowStateOnMove(yTranslation, xTranslation)
+        when (currentState) {
+            GestureState.ACTIVE ->
+                stretchActiveBackIndicator(fullScreenStretchProgress(xTranslation))
+            GestureState.ENTRY ->
+                stretchEntryBackIndicator(preThresholdStretchProgress(xTranslation))
+            GestureState.INACTIVE ->
+                mView.resetStretch()
+        }
+
+        // set y translation
+        setVerticalTranslation(yOffset)
+    }
+
+    private fun setVerticalTranslation(yOffset: Float) {
+        val yTranslation = abs(yOffset)
+        val maxYOffset = (mView.height - params.entryIndicator.backgroundDimens.height) / 2f
+        val yProgress = saturate(yTranslation / (maxYOffset * RUBBER_BAND_AMOUNT))
+        mView.animateVertically(
+            RUBBER_BAND_INTERPOLATOR.getInterpolation(yProgress) * maxYOffset *
+                sign(yOffset)
+        )
+    }
+
+    /**
+     * @return the relative position of the drag from the time after the arrow is activated until
+     * the arrow is fully stretched (between 0.0 - 1.0f)
+     */
+    private fun fullScreenStretchProgress(xTranslation: Float): Float {
+        return saturate(
+            (xTranslation - params.swipeTriggerThreshold) /
+                (fullyStretchedThreshold - params.swipeTriggerThreshold)
+        )
+    }
+
+    /**
+     * Tracks the relative position of the drag from the entry until the threshold where the arrow
+     * activates (between 0.0 - 1.0f)
+     */
+    private fun preThresholdStretchProgress(xTranslation: Float): Float {
+        return saturate(xTranslation / params.swipeTriggerThreshold)
+    }
+
+    private fun stretchActiveBackIndicator(progress: Float) {
+        val rubberBandIterpolation = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress)
+        mView.setStretch(
+            horizontalTranslationStretchAmount = rubberBandIterpolation,
+            arrowStretchAmount = rubberBandIterpolation,
+            backgroundWidthStretchAmount = DECELERATE_INTERPOLATOR_SLOW.getInterpolation(progress),
+            params.fullyStretchedIndicator
+        )
+    }
+
+    private fun stretchEntryBackIndicator(progress: Float) {
+        mView.setStretch(
+            horizontalTranslationStretchAmount = 0f,
+            arrowStretchAmount = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress),
+            backgroundWidthStretchAmount = DECELERATE_INTERPOLATOR.getInterpolation(progress),
+            params.preThresholdIndicator
+        )
+    }
+
+    fun setBackAnimation(backAnimation: BackAnimation?) {
+        this.backAnimation = backAnimation
+        updateBackAnimationSwipeThresholds()
+    }
+
+    private fun updateBackAnimationSwipeThresholds() {
+        backAnimation?.setSwipeThresholds(
+            params.swipeTriggerThreshold,
+            fullyStretchedThreshold
+        )
+    }
+
+    override fun onDestroy() {
+        cancelFailsafe()
+        windowManager.removeView(mView)
+    }
+
+    override fun setIsLeftPanel(isLeftPanel: Boolean) {
+        mView.isLeftPanel = isLeftPanel
+        layoutParams.gravity = if (isLeftPanel) {
+            Gravity.LEFT or Gravity.TOP
+        } else {
+            Gravity.RIGHT or Gravity.TOP
+        }
+    }
+
+    override fun setInsets(insetLeft: Int, insetRight: Int) {
+    }
+
+    override fun setBackCallback(callback: NavigationEdgeBackPlugin.BackCallback) {
+        backCallback = callback
+    }
+
+    override fun setLayoutParams(layoutParams: WindowManager.LayoutParams) {
+        this.layoutParams = layoutParams
+        windowManager.addView(mView, layoutParams)
+    }
+
+    private fun isFlung() = velocityTracker!!.run {
+        computeCurrentVelocity(1000)
+        abs(xVelocity) > MIN_FLING_VELOCITY
+    }
+
+    private fun playFlingBackAnimation() {
+        playAnimation(setCommittedEndListener)
+    }
+
+    private fun playCommitBackAnimation() {
+        // Check if we should vibrate again
+        if (previousState != GestureState.FLUNG) {
+            backCallback.triggerBack()
+            velocityTracker!!.computeCurrentVelocity(1000)
+            val isSlow = abs(velocityTracker!!.xVelocity) < 500
+            val hasNotVibratedRecently =
+                SystemClock.uptimeMillis() - vibrationTime >= GESTURE_DURATION_FOR_CLICK_MS
+            if (isSlow || hasNotVibratedRecently) {
+                vibratorHelper.vibrate(VibrationEffect.EFFECT_CLICK)
+            }
+        }
+        playAnimation(setGoneEndListener)
+    }
+
+    private fun playCancelBackAnimation() {
+        backCallback.cancelBack()
+        playAnimation(setGoneEndListener)
+    }
+
+    /**
+     * @return true if the animation is running, false otherwise. Some transitions don't animate
+     */
+    private fun playAnimation(endListener: DelayedOnAnimationEndListener) {
+        updateRestingArrowDimens(animated = true, currentState)
+
+        if (!mView.addEndListener(endListener)) {
+            scheduleFailsafe()
+        }
+    }
+
+    private fun resetOnDown() {
+        hasHapticPlayed = false
+        totalTouchDelta = 0f
+        vibrationTime = 0
+        cancelFailsafe()
+        backAnimation?.setTriggerBack(false)
+    }
+
+    private fun updateYPosition(touchY: Float) {
+        var yPosition = touchY - params.fingerOffset
+        yPosition = max(yPosition, params.minArrowYPosition.toFloat())
+        yPosition -= layoutParams.height / 2.0f
+        layoutParams.y = constrain(yPosition.toInt(), 0, displaySize.y)
+    }
+
+    override fun setDisplaySize(displaySize: Point) {
+        this.displaySize.set(displaySize.x, displaySize.y)
+        fullyStretchedThreshold = min(displaySize.x.toFloat(), params.swipeProgressThreshold)
+        updateBackAnimationSwipeThresholds()
+    }
+
+    /**
+     * Updates resting arrow and background size not accounting for stretch
+     */
+    private fun updateRestingArrowDimens(animated: Boolean, currentState: GestureState) {
+        if (animated) {
+            when (currentState) {
+                GestureState.ENTRY, GestureState.ACTIVE, GestureState.FLUNG ->
+                    mView.setArrowStiffness(ARROW_APPEAR_STIFFNESS, ARROW_APPEAR_DAMPING_RATIO)
+                GestureState.CANCELLED -> mView.fadeOut()
+                else ->
+                    mView.setArrowStiffness(
+                        ARROW_DISAPPEAR_STIFFNESS,
+                        ARROW_DISAPPEAR_DAMPING_RATIO
+                    )
+            }
+        }
+        mView.setRestingDimens(
+            restingParams = EdgePanelParams.BackIndicatorDimens(
+                horizontalTranslation = when (currentState) {
+                    GestureState.GONE -> -params.activeIndicator.backgroundDimens.width
+                    // Position the committed arrow slightly further off the screen so we  do not
+                    // see part of it bouncing
+                    GestureState.COMMITTED ->
+                        -params.activeIndicator.backgroundDimens.width * 1.5f
+                    GestureState.FLUNG -> params.fullyStretchedIndicator.horizontalTranslation
+                    GestureState.ACTIVE -> params.activeIndicator.horizontalTranslation
+                    GestureState.ENTRY, GestureState.INACTIVE, GestureState.CANCELLED ->
+                        params.entryIndicator.horizontalTranslation
+                },
+                arrowDimens = when (currentState) {
+                    GestureState.ACTIVE, GestureState.INACTIVE,
+                    GestureState.COMMITTED, GestureState.FLUNG -> params.activeIndicator.arrowDimens
+                    GestureState.CANCELLED -> params.cancelledArrowDimens
+                    GestureState.GONE, GestureState.ENTRY -> params.entryIndicator.arrowDimens
+                },
+                backgroundDimens = when (currentState) {
+                    GestureState.GONE, GestureState.ENTRY -> params.entryIndicator.backgroundDimens
+                    else ->
+                        params.activeIndicator.backgroundDimens.copy(
+                            edgeCornerRadius =
+                            if (currentState == GestureState.INACTIVE ||
+                                currentState == GestureState.CANCELLED
+                            )
+                                params.entryIndicator.backgroundDimens.edgeCornerRadius
+                            else
+                                params.activeIndicator.backgroundDimens.edgeCornerRadius
+                        )
+                }
+            ),
+            animate = animated
+        )
+    }
+
+    /**
+     * Update arrow state. If state has not changed, this is a no-op.
+     *
+     * Transitioning to active/inactive will indicate whether or not releasing touch will trigger
+     * the back action.
+     */
+    private fun updateArrowState(newState: GestureState, force: Boolean = false) {
+        if (!force && currentState == newState) return
+
+        if (DEBUG) Log.d(TAG, "updateArrowState $currentState -> $newState")
+        previousState = currentState
+        currentState = newState
+        if (currentState == GestureState.GONE) {
+            mView.cancelAlphaAnimations()
+            mView.visibility = View.GONE
+        } else {
+            mView.visibility = View.VISIBLE
+        }
+
+        when (currentState) {
+            // Transitioning to GONE never animates since the arrow is (presumably) already off the
+            // screen
+            GestureState.GONE -> updateRestingArrowDimens(animated = false, currentState)
+            GestureState.ENTRY -> {
+                updateYPosition(startY)
+                updateRestingArrowDimens(animated = true, currentState)
+            }
+            GestureState.ACTIVE -> {
+                backAnimation?.setTriggerBack(true)
+                updateRestingArrowDimens(animated = true, currentState)
+                // Vibrate the first time we transition to ACTIVE
+                if (!hasHapticPlayed) {
+                    hasHapticPlayed = true
+                    vibrationTime = SystemClock.uptimeMillis()
+                    vibratorHelper.vibrate(VibrationEffect.EFFECT_TICK)
+                }
+            }
+            GestureState.INACTIVE -> {
+                backAnimation?.setTriggerBack(false)
+                updateRestingArrowDimens(animated = true, currentState)
+            }
+            GestureState.FLUNG -> playFlingBackAnimation()
+            GestureState.COMMITTED -> playCommitBackAnimation()
+            GestureState.CANCELLED -> playCancelBackAnimation()
+        }
+    }
+
+    private fun scheduleFailsafe() {
+        if (!ENABLE_FAILSAFE) return
+        cancelFailsafe()
+        if (DEBUG) Log.d(TAG, "scheduleFailsafe")
+        mainHandler.postDelayed(failsafeRunnable, FAILSAFE_DELAY_MS)
+    }
+
+    private fun cancelFailsafe() {
+        if (DEBUG) Log.d(TAG, "cancelFailsafe")
+        mainHandler.removeCallbacks(failsafeRunnable)
+    }
+
+    private fun onFailsafe() {
+        if (DEBUG) Log.d(TAG, "onFailsafe")
+        updateArrowState(GestureState.GONE, force = true)
+    }
+
+    override fun dump(pw: PrintWriter) {
+        pw.println("$TAG:")
+        pw.println("  currentState=$currentState")
+        pw.println("  isLeftPanel=$mView.isLeftPanel")
+    }
+
+    init {
+        if (DEBUG) mView.drawDebugInfo = { canvas ->
+            val debugStrings = listOf(
+                "$currentState",
+                "startX=$startX",
+                "startY=$startY",
+                "xDelta=${"%.1f".format(totalTouchDelta)}",
+                "xTranslation=${"%.1f".format(previousXTranslation)}",
+                "pre=${"%.0f".format(preThresholdStretchProgress(previousXTranslation) * 100)}%",
+                "post=${"%.0f".format(fullScreenStretchProgress(previousXTranslation) * 100)}%"
+            )
+            val debugPaint = Paint().apply {
+                color = Color.WHITE
+            }
+            val debugInfoBottom = debugStrings.size * 32f + 4f
+            canvas.drawRect(
+                4f,
+                4f,
+                canvas.width.toFloat(),
+                debugStrings.size * 32f + 4f,
+                debugPaint
+            )
+            debugPaint.apply {
+                color = Color.BLACK
+                textSize = 32f
+            }
+            var offset = 32f
+            for (debugText in debugStrings) {
+                canvas.drawText(debugText, 10f, offset, debugPaint)
+                offset += 32f
+            }
+            debugPaint.apply {
+                color = Color.RED
+                style = Paint.Style.STROKE
+                strokeWidth = 4f
+            }
+            val canvasWidth = canvas.width.toFloat()
+            val canvasHeight = canvas.height.toFloat()
+            canvas.drawRect(0f, 0f, canvasWidth, canvasHeight, debugPaint)
+
+            fun drawVerticalLine(x: Float, color: Int) {
+                debugPaint.color = color
+                val x = if (mView.isLeftPanel) x else canvasWidth - x
+                canvas.drawLine(x, debugInfoBottom, x, canvas.height.toFloat(), debugPaint)
+            }
+
+            drawVerticalLine(x = params.swipeTriggerThreshold, color = Color.BLUE)
+            drawVerticalLine(x = startX, color = Color.GREEN)
+            drawVerticalLine(x = previousXTranslation, color = Color.DKGRAY)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index ea41fe7..3039d9d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -62,6 +62,8 @@
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.navigationbar.NavigationModeController;
@@ -82,13 +84,16 @@
 import com.android.systemui.tracing.nano.EdgeBackGestureHandlerProto;
 import com.android.systemui.tracing.nano.SystemUiTraceProto;
 import com.android.wm.shell.back.BackAnimation;
+import com.android.wm.shell.pip.Pip;
 
 import java.io.PrintWriter;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 
 import javax.inject.Inject;
 
@@ -145,16 +150,6 @@
                 mPackageName = "_UNKNOWN";
             }
         }
-
-        @Override
-        public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
-            mIsInPipMode = true;
-        }
-
-        @Override
-        public void onActivityUnpinned() {
-            mIsInPipMode = false;
-        }
     };
 
     private DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
@@ -182,9 +177,11 @@
     private final PluginManager mPluginManager;
     private final ProtoTracer mProtoTracer;
     private final NavigationModeController mNavigationModeController;
+    private final BackPanelController.Factory mBackPanelControllerFactory;
     private final ViewConfiguration mViewConfiguration;
     private final WindowManager mWindowManager;
     private final IWindowManager mWindowManagerService;
+    private final Optional<Pip> mPipOptional;
     private final FalsingManager mFalsingManager;
     // Activities which should not trigger Back gesture.
     private final List<ComponentName> mGestureBlockingActivities = new ArrayList<>();
@@ -199,6 +196,7 @@
     private final Region mExcludeRegion = new Region();
     private final Region mUnrestrictedExcludeRegion = new Region();
     private final LatencyTracker mLatencyTracker;
+    private final FeatureFlags mFeatureFlags;
 
     // The left side edge width where touch down is allowed
     private int mEdgeWidthLeft;
@@ -214,6 +212,8 @@
     // We temporarily disable back gesture when user is quickswitching
     // between apps of different orientations
     private boolean mDisabledForQuickstep;
+    // This gets updated when the value of PipTransitionState#isInPip changes.
+    private boolean mIsInPip;
 
     private final PointF mDownPoint = new PointF();
     private final PointF mEndPoint = new PointF();
@@ -229,7 +229,7 @@
     private boolean mIsNavBarShownTransiently;
     private boolean mIsBackGestureAllowed;
     private boolean mGestureBlockingActivityRunning;
-    private boolean mIsInPipMode;
+    private boolean mIsNewBackAffordanceEnabled;
 
     private InputMonitor mInputMonitor;
     private InputChannelCompat.InputEventReceiver mInputEventReceiver;
@@ -297,13 +297,26 @@
         }
     };
 
+    private final Consumer<Boolean> mOnIsInPipStateChangedListener =
+            (isInPip) -> mIsInPip = isInPip;
 
-    EdgeBackGestureHandler(Context context, OverviewProxyService overviewProxyService,
-            SysUiState sysUiState, PluginManager pluginManager, @Main Executor executor,
-            BroadcastDispatcher broadcastDispatcher, ProtoTracer protoTracer,
-            NavigationModeController navigationModeController, ViewConfiguration viewConfiguration,
-            WindowManager windowManager, IWindowManager windowManagerService,
-            FalsingManager falsingManager, LatencyTracker latencyTracker) {
+    EdgeBackGestureHandler(
+            Context context,
+            OverviewProxyService overviewProxyService,
+            SysUiState sysUiState,
+            PluginManager pluginManager,
+            @Main Executor executor,
+            BroadcastDispatcher broadcastDispatcher,
+            ProtoTracer protoTracer,
+            NavigationModeController navigationModeController,
+            BackPanelController.Factory backPanelControllerFactory,
+            ViewConfiguration viewConfiguration,
+            WindowManager windowManager,
+            IWindowManager windowManagerService,
+            Optional<Pip> pipOptional,
+            FalsingManager falsingManager,
+            LatencyTracker latencyTracker,
+            FeatureFlags featureFlags) {
         super(broadcastDispatcher);
         mContext = context;
         mDisplayId = context.getDisplayId();
@@ -313,11 +326,14 @@
         mPluginManager = pluginManager;
         mProtoTracer = protoTracer;
         mNavigationModeController = navigationModeController;
+        mBackPanelControllerFactory = backPanelControllerFactory;
         mViewConfiguration = viewConfiguration;
         mWindowManager = windowManager;
         mWindowManagerService = windowManagerService;
+        mPipOptional = pipOptional;
         mFalsingManager = falsingManager;
         mLatencyTracker = latencyTracker;
+        mFeatureFlags = featureFlags;
         ComponentName recentsComponentName = ComponentName.unflattenFromString(
                 context.getString(com.android.internal.R.string.config_recentsComponentName));
         if (recentsComponentName != null) {
@@ -474,6 +490,7 @@
             mPluginManager.removePluginListener(this);
             TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
             DeviceConfig.removeOnPropertiesChangedListener(mOnPropertiesChangedListener);
+            mPipOptional.ifPresent(pip -> pip.setOnIsInPipStateChangedListener(null));
 
             try {
                 mWindowManagerService.unregisterSystemGestureExclusionListener(
@@ -491,6 +508,8 @@
             TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
             DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
                     mMainExecutor::execute, mOnPropertiesChangedListener);
+            mPipOptional.ifPresent(
+                    pip -> pip.setOnIsInPipStateChangedListener(mOnIsInPipStateChangedListener));
 
             try {
                 mWindowManagerService.registerSystemGestureExclusionListener(
@@ -507,8 +526,8 @@
                     Choreographer.getInstance(), this::onInputEvent);
 
             // Add a nav bar panel window
-            setEdgeBackPlugin(
-                    new NavigationBarEdgePanel(mContext, mBackAnimation, mLatencyTracker));
+            mIsNewBackAffordanceEnabled = mFeatureFlags.isEnabled(Flags.NEW_BACK_AFFORDANCE);
+            resetEdgeBackPlugin();
             mPluginManager.addPluginListener(
                     this, NavigationEdgeBackPlugin.class, /*allowMultiple=*/ false);
         }
@@ -523,7 +542,17 @@
 
     @Override
     public void onPluginDisconnected(NavigationEdgeBackPlugin plugin) {
-        setEdgeBackPlugin(new NavigationBarEdgePanel(mContext, mBackAnimation, mLatencyTracker));
+        resetEdgeBackPlugin();
+    }
+
+    private void resetEdgeBackPlugin() {
+        if (mIsNewBackAffordanceEnabled) {
+            setEdgeBackPlugin(
+                    mBackPanelControllerFactory.create(mContext, mBackAnimation));
+        } else {
+            setEdgeBackPlugin(
+                    new NavigationBarEdgePanel(mContext, mBackAnimation, mLatencyTracker));
+        }
     }
 
     private void setEdgeBackPlugin(NavigationEdgeBackPlugin edgeBackPlugin) {
@@ -653,7 +682,7 @@
     private boolean isWithinTouchRegion(int x, int y) {
         // If the point is inside the PiP or Nav bar overlay excluded bounds, then ignore the back
         // gesture
-        final boolean isInsidePip = mIsInPipMode && mPipExcludedBounds.contains(x, y);
+        final boolean isInsidePip = mIsInPip && mPipExcludedBounds.contains(x, y);
         if (isInsidePip || mNavBarOverlayExcludedBounds.contains(x, y)) {
             return false;
         }
@@ -906,7 +935,7 @@
         pw.println("  mInRejectedExclusion=" + mInRejectedExclusion);
         pw.println("  mExcludeRegion=" + mExcludeRegion);
         pw.println("  mUnrestrictedExcludeRegion=" + mUnrestrictedExcludeRegion);
-        pw.println("  mIsInPipMode=" + mIsInPipMode);
+        pw.println("  mIsInPip=" + mIsInPip);
         pw.println("  mPipExcludedBounds=" + mPipExcludedBounds);
         pw.println("  mNavBarOverlayExcludedBounds=" + mNavBarOverlayExcludedBounds);
         pw.println("  mEdgeWidthLeft=" + mEdgeWidthLeft);
@@ -948,8 +977,12 @@
 
     public void setBackAnimation(BackAnimation backAnimation) {
         mBackAnimation = backAnimation;
-        if (mEdgeBackPlugin != null && mEdgeBackPlugin instanceof NavigationBarEdgePanel) {
-            ((NavigationBarEdgePanel) mEdgeBackPlugin).setBackAnimation(backAnimation);
+        if (mEdgeBackPlugin != null) {
+            if (mEdgeBackPlugin instanceof NavigationBarEdgePanel) {
+                ((NavigationBarEdgePanel) mEdgeBackPlugin).setBackAnimation(backAnimation);
+            } else if (mEdgeBackPlugin instanceof BackPanelController) {
+                ((BackPanelController) mEdgeBackPlugin).setBackAnimation(backAnimation);
+            }
         }
     }
 
@@ -967,20 +1000,31 @@
         private final BroadcastDispatcher mBroadcastDispatcher;
         private final ProtoTracer mProtoTracer;
         private final NavigationModeController mNavigationModeController;
+        private final BackPanelController.Factory mBackPanelControllerFactory;
         private final ViewConfiguration mViewConfiguration;
         private final WindowManager mWindowManager;
         private final IWindowManager mWindowManagerService;
+        private final Optional<Pip> mPipOptional;
         private final FalsingManager mFalsingManager;
         private final LatencyTracker mLatencyTracker;
+        private final FeatureFlags mFeatureFlags;
 
         @Inject
         public Factory(OverviewProxyService overviewProxyService,
-                SysUiState sysUiState, PluginManager pluginManager, @Main Executor executor,
-                BroadcastDispatcher broadcastDispatcher, ProtoTracer protoTracer,
-                NavigationModeController navigationModeController,
-                ViewConfiguration viewConfiguration, WindowManager windowManager,
-                IWindowManager windowManagerService, FalsingManager falsingManager,
-                LatencyTracker latencyTracker) {
+                       SysUiState sysUiState,
+                       PluginManager pluginManager,
+                       @Main Executor executor,
+                       BroadcastDispatcher broadcastDispatcher,
+                       ProtoTracer protoTracer,
+                       NavigationModeController navigationModeController,
+                       BackPanelController.Factory backPanelControllerFactory,
+                       ViewConfiguration viewConfiguration,
+                       WindowManager windowManager,
+                       IWindowManager windowManagerService,
+                       Optional<Pip> pipOptional,
+                       FalsingManager falsingManager,
+                       LatencyTracker latencyTracker,
+                       FeatureFlags featureFlags) {
             mOverviewProxyService = overviewProxyService;
             mSysUiState = sysUiState;
             mPluginManager = pluginManager;
@@ -988,19 +1032,35 @@
             mBroadcastDispatcher = broadcastDispatcher;
             mProtoTracer = protoTracer;
             mNavigationModeController = navigationModeController;
+            mBackPanelControllerFactory = backPanelControllerFactory;
             mViewConfiguration = viewConfiguration;
             mWindowManager = windowManager;
             mWindowManagerService = windowManagerService;
+            mPipOptional = pipOptional;
             mFalsingManager = falsingManager;
             mLatencyTracker = latencyTracker;
+            mFeatureFlags = featureFlags;
         }
 
         /** Construct a {@link EdgeBackGestureHandler}. */
         public EdgeBackGestureHandler create(Context context) {
-            return new EdgeBackGestureHandler(context, mOverviewProxyService, mSysUiState,
-                    mPluginManager, mExecutor, mBroadcastDispatcher, mProtoTracer,
-                    mNavigationModeController, mViewConfiguration, mWindowManager,
-                    mWindowManagerService, mFalsingManager, mLatencyTracker);
+            return new EdgeBackGestureHandler(
+                    context,
+                    mOverviewProxyService,
+                    mSysUiState,
+                    mPluginManager,
+                    mExecutor,
+                    mBroadcastDispatcher,
+                    mProtoTracer,
+                    mNavigationModeController,
+                    mBackPanelControllerFactory,
+                    mViewConfiguration,
+                    mWindowManager,
+                    mWindowManagerService,
+                    mPipOptional,
+                    mFalsingManager,
+                    mLatencyTracker,
+                    mFeatureFlags);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
new file mode 100644
index 0000000..a3fb58d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -0,0 +1,140 @@
+package com.android.systemui.navigationbar.gestural
+
+import android.content.res.Resources
+import com.android.systemui.R
+
+data class EdgePanelParams(private var resources: Resources) {
+
+    data class ArrowDimens(
+        val length: Float = 0f,
+        val height: Float = 0f
+    )
+
+    data class BackgroundDimens(
+        val width: Float = 0f,
+        val height: Float = 0f,
+        val edgeCornerRadius: Float = 0f,
+        val farCornerRadius: Float = 0f
+    )
+
+    data class BackIndicatorDimens(
+        val horizontalTranslation: Float = 0f,
+        val arrowDimens: ArrowDimens = ArrowDimens(),
+        val backgroundDimens: BackgroundDimens = BackgroundDimens()
+    )
+
+    var arrowThickness: Float = 0f
+        private set
+    var entryIndicator = BackIndicatorDimens()
+        private set
+    var activeIndicator = BackIndicatorDimens()
+        private set
+    var preThresholdIndicator = BackIndicatorDimens()
+        private set
+    var fullyStretchedIndicator = BackIndicatorDimens()
+        private set
+    var cancelledArrowDimens = ArrowDimens()
+
+    // navigation bar edge constants
+    var arrowPaddingEnd: Int = 0
+        private set
+
+    // The closest to y
+    var minArrowYPosition: Int = 0
+        private set
+    var fingerOffset: Int = 0
+        private set
+    var swipeTriggerThreshold: Float = 0f
+        private set
+    var swipeProgressThreshold: Float = 0f
+        private set
+
+    // The minimum delta needed to change direction / stop triggering back
+    var minDeltaForSwitch: Int = 0
+        private set
+
+    init {
+        update(resources)
+    }
+
+    private fun getDimen(id: Int): Float {
+        return resources.getDimension(id)
+    }
+
+    private fun getPx(id: Int): Int {
+        return resources.getDimensionPixelSize(id)
+    }
+
+    fun update(resources: Resources) {
+        this.resources = resources
+        arrowThickness = getDimen(R.dimen.navigation_edge_arrow_thickness)
+        arrowPaddingEnd = getPx(R.dimen.navigation_edge_panel_padding)
+        minArrowYPosition = getPx(R.dimen.navigation_edge_arrow_min_y)
+        fingerOffset = getPx(R.dimen.navigation_edge_finger_offset)
+        swipeTriggerThreshold = getDimen(R.dimen.navigation_edge_action_drag_threshold)
+        swipeProgressThreshold = getDimen(R.dimen.navigation_edge_action_progress_threshold)
+        minDeltaForSwitch = getPx(R.dimen.navigation_edge_minimum_x_delta_for_switch)
+
+        entryIndicator = BackIndicatorDimens(
+            horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin),
+            arrowDimens = ArrowDimens(
+                length = getDimen(R.dimen.navigation_edge_entry_arrow_length),
+                height = getDimen(R.dimen.navigation_edge_entry_arrow_height),
+            ),
+            backgroundDimens = BackgroundDimens(
+                width = getDimen(R.dimen.navigation_edge_entry_background_width),
+                height = getDimen(R.dimen.navigation_edge_entry_background_height),
+                edgeCornerRadius = getDimen(R.dimen.navigation_edge_entry_edge_corners),
+                farCornerRadius = getDimen(R.dimen.navigation_edge_entry_far_corners)
+            )
+        )
+
+        activeIndicator = BackIndicatorDimens(
+            horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin),
+            arrowDimens = ArrowDimens(
+                length = getDimen(R.dimen.navigation_edge_active_arrow_length),
+                height = getDimen(R.dimen.navigation_edge_active_arrow_height),
+            ),
+            backgroundDimens = BackgroundDimens(
+                width = getDimen(R.dimen.navigation_edge_active_background_width),
+                height = getDimen(R.dimen.navigation_edge_active_background_height),
+                edgeCornerRadius = getDimen(R.dimen.navigation_edge_active_edge_corners),
+                farCornerRadius = getDimen(R.dimen.navigation_edge_active_far_corners)
+
+            )
+        )
+
+        preThresholdIndicator = BackIndicatorDimens(
+            horizontalTranslation = getDimen(R.dimen.navigation_edge_pre_threshold_margin),
+            arrowDimens = ArrowDimens(
+                length = entryIndicator.arrowDimens.length,
+                height = entryIndicator.arrowDimens.height,
+            ),
+            backgroundDimens = BackgroundDimens(
+                width = getDimen(R.dimen.navigation_edge_pre_threshold_background_width),
+                height = getDimen(R.dimen.navigation_edge_pre_threshold_background_height),
+                edgeCornerRadius = getDimen(R.dimen.navigation_edge_pre_threshold_edge_corners),
+                farCornerRadius = getDimen(R.dimen.navigation_edge_pre_threshold_far_corners)
+            )
+        )
+
+        fullyStretchedIndicator = BackIndicatorDimens(
+            horizontalTranslation = getDimen(R.dimen.navigation_edge_stretch_margin),
+            arrowDimens = ArrowDimens(
+                length = getDimen(R.dimen.navigation_edge_stretched_arrow_length),
+                height = getDimen(R.dimen.navigation_edge_stretched_arrow_height),
+            ),
+            backgroundDimens = BackgroundDimens(
+                width = getDimen(R.dimen.navigation_edge_stretch_background_width),
+                height = getDimen(R.dimen.navigation_edge_stretch_background_height),
+                edgeCornerRadius = getDimen(R.dimen.navigation_edge_stretch_edge_corners),
+                farCornerRadius = getDimen(R.dimen.navigation_edge_stretch_far_corners)
+            )
+        )
+
+        cancelledArrowDimens = ArrowDimens(
+            length = getDimen(R.dimen.navigation_edge_cancelled_arrow_length),
+            height = getDimen(R.dimen.navigation_edge_cancelled_arrow_height)
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 1a7bd8c..18be0aa 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -289,7 +289,7 @@
             if (DEBUG) Log.d(TAG, "Updating widget: " + appWidgetId);
             PeopleSpaceTile tile = getTileForExistingWidget(appWidgetId);
             if (tile == null) {
-                Log.e(TAG, "Matching conversation not found for shortcut ID");
+                Log.e(TAG, "Matching conversation not found for widget " + appWidgetId);
             }
             updateAppWidgetOptionsAndView(appWidgetId, tile);
             widgetIdToTile.put(appWidgetId, tile);
@@ -308,7 +308,7 @@
         if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + " for: " + key.toString());
 
         if (!PeopleTileKey.isValid(key)) {
-            Log.e(TAG, "Cannot update invalid widget");
+            Log.e(TAG, "Invalid tile key updating widget " + appWidgetId);
             return;
         }
         RemoteViews views = PeopleTileViewHelper.createRemoteViews(mContext, tile, appWidgetId,
@@ -330,7 +330,7 @@
     /** Updates tile in app widget options and the current view. */
     public void updateAppWidgetOptionsAndView(int appWidgetId, PeopleSpaceTile tile) {
         if (tile == null) {
-            if (DEBUG) Log.w(TAG, "Storing null tile");
+            Log.w(TAG, "Storing null tile for widget " + appWidgetId);
         }
         synchronized (mTiles) {
             mTiles.put(appWidgetId, tile);
@@ -348,7 +348,7 @@
         try {
             return getTileForExistingWidgetThrowing(appWidgetId);
         } catch (Exception e) {
-            Log.e(TAG, "failed to retrieve tile for widget ID " + appWidgetId, e);
+            Log.e(TAG, "failed to retrieve tile for existing widget " + appWidgetId, e);
             return null;
         }
     }
@@ -388,7 +388,7 @@
             boolean supplementFromStorage) throws
             PackageManager.NameNotFoundException {
         if (!PeopleTileKey.isValid(key)) {
-            Log.e(TAG, "PeopleTileKey invalid: " + key.toString());
+            Log.e(TAG, "Invalid tile key finding tile for existing widget " + appWidgetId);
             return null;
         }
 
@@ -423,7 +423,7 @@
             // Add current state.
             return getTileWithCurrentState(storedTile.build(), ACTION_BOOT_COMPLETED);
         } catch (RemoteException e) {
-            Log.e(TAG, "getTileFromPersistentStorage failing", e);
+            Log.e(TAG, "getTileFromPersistentStorage failing for widget " + appWidgetId, e);
             return null;
         }
     }
@@ -591,10 +591,7 @@
         if (DEBUG) Log.d(TAG, "Augmenting tile for existing widget: " + widgetId);
         PeopleSpaceTile tile = getTileForExistingWidget(widgetId);
         if (tile == null) {
-            if (DEBUG) {
-                Log.w(TAG, "Widget: " + widgetId
-                        + ". Null tile for existing widget, skipping update.");
-            }
+            Log.w(TAG, "Null tile for existing widget " + widgetId + ", skipping update.");
             return Optional.empty();
         }
         String contactUriString = mSharedPrefs.getString(String.valueOf(widgetId), null);
@@ -816,7 +813,7 @@
             tile = getTileFromPersistentStorage(key, appWidgetId,  /* supplementFromStorage= */
                     false);
         } catch (PackageManager.NameNotFoundException e) {
-            Log.e(TAG, "Cannot add widget since app was uninstalled");
+            Log.e(TAG, "Cannot add widget " + appWidgetId + " since app was uninstalled");
             return;
         }
         if (tile == null) {
@@ -851,7 +848,7 @@
                     Collections.singletonList(tile.getId()),
                     tile.getUserHandle(), LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
         } catch (Exception e) {
-            Log.w(TAG, "failed to cache shortcut", e);
+            Log.w(TAG, "failed to cache shortcut for widget " + appWidgetId, e);
         }
         PeopleSpaceTile finalTile = tile;
         mBgExecutor.execute(
@@ -862,7 +859,7 @@
     public void registerConversationListenerIfNeeded(int widgetId, PeopleTileKey key) {
         // Retrieve storage needed for registration.
         if (!PeopleTileKey.isValid(key)) {
-            if (DEBUG) Log.w(TAG, "Could not register listener for widget: " + widgetId);
+            Log.w(TAG, "Invalid tile key registering listener for widget " + widgetId);
             return;
         }
         TileConversationListener newListener = new TileConversationListener();
@@ -911,7 +908,7 @@
                         widgetSp.getInt(USER_ID, INVALID_USER_ID),
                         widgetSp.getString(PACKAGE_NAME, null));
                 if (!PeopleTileKey.isValid(key)) {
-                    if (DEBUG) Log.e(TAG, "Could not delete " + widgetId);
+                    Log.e(TAG, "Invalid tile key trying to remove widget " + widgetId);
                     return;
                 }
                 storedWidgetIdsForKey = new HashSet<>(
@@ -1083,7 +1080,8 @@
                 synchronized (mLock) {
                     existingTile = getTileForExistingWidgetThrowing(appWidgetId);
                     if (existingTile == null) {
-                        Log.e(TAG, "Matching conversation not found for shortcut ID");
+                        Log.e(TAG, "Matching conversation not found for widget "
+                                + appWidgetId);
                         continue;
                     }
                     updatedTile = getTileWithCurrentState(existingTile, entryPoint);
@@ -1091,7 +1089,7 @@
                 }
             } catch (PackageManager.NameNotFoundException e) {
                 // Delete data for uninstalled widgets.
-                Log.e(TAG, "package no longer found for tile", e);
+                Log.e(TAG, "Package no longer found for widget " + appWidgetId, e);
                 JobScheduler jobScheduler = mContext.getSystemService(JobScheduler.class);
                 if (jobScheduler != null
                         && jobScheduler.getPendingJob(PeopleBackupFollowUpJob.JOB_ID) != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 05e8c02..90fc1d7 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -55,6 +55,7 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.settingslib.Utils;
@@ -62,6 +63,7 @@
 import com.android.settingslib.utils.PowerUtil;
 import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
+import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.SysUISingleton;
@@ -93,6 +95,8 @@
     private static final String TAG_TEMPERATURE = "high_temp";
     private static final String TAG_AUTO_SAVER = "auto_saver";
 
+    private static final String INTERACTION_JANK_TAG = "start_power_saver";
+
     private static final int SHOWING_NOTHING = 0;
     private static final int SHOWING_WARNING = 1;
     private static final int SHOWING_INVALID_CHARGER = 3;
@@ -707,7 +711,9 @@
         });
         WeakReference<View> ref = mBatteryControllerLazy.get().getLastPowerSaverStartView();
         if (ref != null && ref.get() != null && ref.get().isAggregatedVisible()) {
-            mDialogLaunchAnimator.showFromView(d, ref.get());
+            mDialogLaunchAnimator.showFromView(d, ref.get(),
+                    new DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                            INTERACTION_JANK_TAG));
         } else {
             d.show();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index 6f05852..0288c9f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -45,16 +45,18 @@
 import androidx.recyclerview.widget.RecyclerView
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_FOOTER_DOT
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.Dumpable
 import com.android.systemui.R
+import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
-import com.android.systemui.shared.system.SysUiStatsLog
 import com.android.systemui.settings.UserTracker
+import com.android.systemui.shared.system.SysUiStatsLog
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.util.DeviceConfigProxy
 import com.android.systemui.util.indentIfPossible
@@ -81,6 +83,7 @@
 ) : IForegroundServiceObserver.Stub(), Dumpable {
 
     companion object {
+        private const val INTERACTION_JANK_TAG = "active_background_apps"
         private val LOG_TAG = FgsManagerController::class.java.simpleName
         private const val DEFAULT_TASK_MANAGER_ENABLED = true
         private const val DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT = false
@@ -153,31 +156,38 @@
 
             currentProfileIds.addAll(userTracker.userProfiles.map { it.id })
 
-            deviceConfigProxy.addOnPropertiesChangedListener(NAMESPACE_SYSTEMUI,
-                    backgroundExecutor) {
+            deviceConfigProxy.addOnPropertiesChangedListener(
+                NAMESPACE_SYSTEMUI,
+                backgroundExecutor
+            ) {
                 isAvailable = it.getBoolean(TASK_MANAGER_ENABLED, isAvailable)
                 showFooterDot =
-                        it.getBoolean(TASK_MANAGER_SHOW_FOOTER_DOT, showFooterDot)
+                    it.getBoolean(TASK_MANAGER_SHOW_FOOTER_DOT, showFooterDot)
             }
 
-            isAvailable = deviceConfigProxy.getBoolean(NAMESPACE_SYSTEMUI,
-                    TASK_MANAGER_ENABLED, DEFAULT_TASK_MANAGER_ENABLED)
-            showFooterDot = deviceConfigProxy.getBoolean(NAMESPACE_SYSTEMUI,
-                    TASK_MANAGER_SHOW_FOOTER_DOT, DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT)
+            isAvailable = deviceConfigProxy.getBoolean(
+                NAMESPACE_SYSTEMUI,
+                TASK_MANAGER_ENABLED, DEFAULT_TASK_MANAGER_ENABLED
+            )
+            showFooterDot = deviceConfigProxy.getBoolean(
+                NAMESPACE_SYSTEMUI,
+                TASK_MANAGER_SHOW_FOOTER_DOT, DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT
+            )
 
             dumpManager.registerDumpable(this)
 
             broadcastDispatcher.registerReceiver(
-                    object : BroadcastReceiver() {
-                        override fun onReceive(context: Context, intent: Intent) {
-                            if (intent.action == Intent.ACTION_SHOW_FOREGROUND_SERVICE_MANAGER) {
-                                showDialog(null)
-                            }
+                object : BroadcastReceiver() {
+                    override fun onReceive(context: Context, intent: Intent) {
+                        if (intent.action == Intent.ACTION_SHOW_FOREGROUND_SERVICE_MANAGER) {
+                            showDialog(null)
                         }
-                    },
-                    IntentFilter(Intent.ACTION_SHOW_FOREGROUND_SERVICE_MANAGER),
-                    executor = mainExecutor,
-                    flags = Context.RECEIVER_NOT_EXPORTED)
+                    }
+                },
+                IntentFilter(Intent.ACTION_SHOW_FOREGROUND_SERVICE_MANAGER),
+                executor = mainExecutor,
+                flags = Context.RECEIVER_NOT_EXPORTED
+            )
 
             initialized = true
         }
@@ -193,10 +203,12 @@
             val userPackageKey = UserPackage(userId, packageName)
             if (isForeground) {
                 runningServiceTokens.getOrPut(userPackageKey) { StartTimeAndTokens(systemClock) }
-                        .addToken(token)
+                    .addToken(token)
             } else {
                 if (runningServiceTokens[userPackageKey]?.also {
-                            it.removeToken(token) }?.isEmpty() == true) {
+                    it.removeToken(token)
+                }?.isEmpty() == true
+                ) {
                     runningServiceTokens.remove(userPackageKey)
                 }
             }
@@ -209,7 +221,7 @@
 
     @GuardedBy("lock")
     val onNumberOfPackagesChangedListeners: MutableSet<OnNumberOfPackagesChangedListener> =
-            mutableSetOf()
+        mutableSetOf()
 
     @GuardedBy("lock")
     val onDialogDismissedListeners: MutableSet<OnDialogDismissedListener> = mutableSetOf()
@@ -284,7 +296,7 @@
                 recyclerView.adapter = appListAdapter
 
                 val topSpacing = dialogContext.resources
-                        .getDimensionPixelSize(R.dimen.fgs_manager_list_top_spacing)
+                    .getDimensionPixelSize(R.dimen.fgs_manager_list_top_spacing)
                 dialog.setView(recyclerView, 0, topSpacing, 0, 0)
 
                 this.dialog = dialog
@@ -302,7 +314,15 @@
 
                 mainExecutor.execute {
                     viewLaunchedFrom
-                            ?.let { dialogLaunchAnimator.showFromView(dialog, it) } ?: dialog.show()
+                        ?.let {
+                            dialogLaunchAnimator.showFromView(
+                                dialog, it,
+                                cuj = DialogCuj(
+                                    InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                                    INTERACTION_JANK_TAG
+                                )
+                            )
+                        } ?: dialog.show()
                 }
 
                 backgroundExecutor.execute {
@@ -329,11 +349,14 @@
 
         addedPackages.forEach {
             val ai = packageManager.getApplicationInfoAsUser(it.packageName, 0, it.userId)
-            runningApps[it] = RunningApp(it.userId, it.packageName,
-                    runningServiceTokens[it]!!.startTime, it.uiControl,
-                    packageManager.getApplicationLabel(ai),
-                    packageManager.getUserBadgedIcon(
-                            packageManager.getApplicationIcon(ai), UserHandle.of(it.userId)))
+            runningApps[it] = RunningApp(
+                it.userId, it.packageName,
+                runningServiceTokens[it]!!.startTime, it.uiControl,
+                packageManager.getApplicationLabel(ai),
+                packageManager.getUserBadgedIcon(
+                    packageManager.getApplicationIcon(ai), UserHandle.of(it.userId)
+                )
+            )
             logEvent(stopped = false, it.packageName, it.userId, runningApps[it]!!.timeStarted)
         }
 
@@ -349,7 +372,7 @@
 
         mainExecutor.execute {
             appListAdapter
-                    .setData(runningApps.values.toList().sortedByDescending { it.timeStarted })
+                .setData(runningApps.values.toList().sortedByDescending { it.timeStarted })
         }
     }
 
@@ -367,8 +390,10 @@
         }
         backgroundExecutor.execute {
             val uid = packageManager.getPackageUidAsUser(packageName, userId)
-            SysUiStatsLog.write(SysUiStatsLog.TASK_MANAGER_EVENT_REPORTED, uid, event,
-                    timeLogged - timeStarted)
+            SysUiStatsLog.write(
+                SysUiStatsLog.TASK_MANAGER_EVENT_REPORTED, uid, event,
+                timeLogged - timeStarted
+            )
         }
     }
 
@@ -379,8 +404,10 @@
         private var data: List<RunningApp> = listOf()
 
         override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppItemViewHolder {
-            return AppItemViewHolder(LayoutInflater.from(parent.context)
-                    .inflate(R.layout.fgs_manager_app_item, parent, false))
+            return AppItemViewHolder(
+                LayoutInflater.from(parent.context)
+                    .inflate(R.layout.fgs_manager_app_item, parent, false)
+            )
         }
 
         override fun onBindViewHolder(holder: AppItemViewHolder, position: Int) {
@@ -392,8 +419,9 @@
                 iconView.setImageDrawable(runningApp.icon)
                 appLabelView.text = runningApp.appLabel
                 durationView.text = DateUtils.formatDuration(
-                        max(systemClock.elapsedRealtime() - runningApp.timeStarted, 60000),
-                        DateUtils.LENGTH_MEDIUM)
+                    max(systemClock.elapsedRealtime() - runningApp.timeStarted, 60000),
+                    DateUtils.LENGTH_MEDIUM
+                )
                 stopButton.setOnClickListener {
                     stopButton.setText(R.string.fgs_manager_app_item_stop_button_stopped_label)
                     stopPackage(runningApp.userId, runningApp.packageName, runningApp.timeStarted)
@@ -431,12 +459,12 @@
                 }
 
                 override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int):
-                        Boolean {
+                    Boolean {
                     return oldData[oldItemPosition] == newData[newItemPosition]
                 }
 
                 override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int):
-                        Boolean {
+                    Boolean {
                     return oldData[oldItemPosition].stopped == newData[newItemPosition].stopped
                 }
             }).dispatchUpdatesTo(this)
@@ -462,7 +490,7 @@
 
         fun updateUiControl() {
             backgroundRestrictionExemptionReason =
-                    activityManager.getBackgroundRestrictionExemptionReason(uid)
+                activityManager.getBackgroundRestrictionExemptionReason(uid)
             uiControl = when (backgroundRestrictionExemptionReason) {
                 PowerExemptionManager.REASON_SYSTEM_UID,
                 PowerExemptionManager.REASON_DEVICE_DEMO_MODE -> UIControl.HIDE_ENTRY
@@ -523,8 +551,10 @@
         fun dump(pw: PrintWriter) {
             pw.println("StartTimeAndTokens: [")
             pw.indentIfPossible {
-                pw.println("startTime=$startTime (time running =" +
-                        " ${systemClock.elapsedRealtime() - startTime}ms)")
+                pw.println(
+                    "startTime=$startTime (time running =" +
+                        " ${systemClock.elapsedRealtime() - startTime}ms)"
+                )
                 pw.println("tokens: [")
                 pw.indentIfPossible {
                     for (token in tokens) {
@@ -572,8 +602,10 @@
             pw.indentIfPossible {
                 pw.println("userId=$userId")
                 pw.println("packageName=$packageName")
-                pw.println("timeStarted=$timeStarted (time since start =" +
-                        " ${systemClock.elapsedRealtime() - timeStarted}ms)")
+                pw.println(
+                    "timeStarted=$timeStarted (time since start =" +
+                        " ${systemClock.elapsedRealtime() - timeStarted}ms)"
+                )
                 pw.println("uiControl=$uiControl")
                 pw.println("appLabel=$appLabel")
                 pw.println("icon=$icon")
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index ce50ddf..fcafead 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -283,6 +283,7 @@
                 .inflate(R.layout.qs_paged_page, this, false);
         page.setMinRows(mMinRows);
         page.setMaxColumns(mMaxColumns);
+        page.setSelected(false);
         return page;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
index ba6b1dd..875493d7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
@@ -17,6 +17,7 @@
 package com.android.systemui.qs;
 
 import static com.android.systemui.qs.dagger.QSFragmentModule.QS_FGS_MANAGER_FOOTER_VIEW;
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
 
 import android.content.Context;
 import android.view.View;
@@ -141,8 +142,8 @@
 
     public void handleRefreshState() {
         mMainExecutor.execute(() -> {
-            CharSequence text = mContext.getResources().getQuantityString(
-                    R.plurals.fgs_manager_footer_label, mNumPackages, mNumPackages);
+            CharSequence text = icuMessageFormat(mContext.getResources(),
+                    R.string.fgs_manager_footer_label, mNumPackages);
             mFooterText.setText(text);
             mNumberView.setText(Integer.toString(mNumPackages));
             mNumberView.setContentDescription(text);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index d03a2e5..8c5e6cc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -57,7 +57,6 @@
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.util.LifecycleFragment;
-import com.android.systemui.util.Utils;
 
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -624,7 +623,6 @@
         if (mQSAnimator != null) {
             mQSAnimator.setPosition(expansion);
         }
-        updateMediaPositions();
     }
 
     private void setAlphaAnimationProgress(float progress) {
@@ -644,10 +642,11 @@
         if (mLastQSExpansion == 1.0f) {
             // Fully expanded, let's set the layout bounds as clip bounds. This is necessary because
             // it's a scrollview and otherwise wouldn't be clipped. However, we set the horizontal
-            // bounds so the pages go to the ends of QSContainerImpl
-            ViewGroup.MarginLayoutParams lp =
-                    (ViewGroup.MarginLayoutParams) mQSPanelScrollView.getLayoutParams();
-            mQsBounds.set(-lp.leftMargin, 0, mQSPanelScrollView.getWidth() + lp.rightMargin,
+            // bounds so the pages go to the ends of QSContainerImpl (most cases) or its parent
+            // (large screen portrait)
+            int sideMargin = getResources().getDimensionPixelSize(
+                    R.dimen.qs_tiles_page_horizontal_margin) * 2;
+            mQsBounds.set(-sideMargin, 0, mQSPanelScrollView.getWidth() + sideMargin,
                     mQSPanelScrollView.getHeight());
         }
         mQSPanelScrollView.setClipBounds(mQsBounds);
@@ -660,54 +659,6 @@
                         - mQSPanelScrollView.getPaddingBottom());
     }
 
-    private void updateMediaPositions() {
-        if (Utils.useQsMediaPlayer(getContext())) {
-            mContainer.getLocationOnScreen(mTmpLocation);
-            float absoluteBottomPosition = mTmpLocation[1] + mContainer.getHeight();
-            // The Media can be scrolled off screen by default, let's offset it
-            float expandedMediaPosition = absoluteBottomPosition - mQSPanelScrollView.getScrollY()
-                    + mQSPanelScrollView.getScrollRange();
-            pinToBottom(expandedMediaPosition, mQsMediaHost, true /* expanded */);
-            // The expanded media host should never move above the laid out position
-            pinToBottom(absoluteBottomPosition, mQqsMediaHost, false /* expanded */);
-        }
-    }
-
-    private void pinToBottom(float absoluteBottomPosition, MediaHost mediaHost, boolean expanded) {
-        View hostView = mediaHost.getHostView();
-        // On keyguard we cross-fade to expanded, so no need to pin it.
-        // If the collapsed qs isn't visible, we also just keep it at the laid out position.
-        if (mLastQSExpansion > 0 && !isKeyguardState() && mQqsMediaHost.getVisible()) {
-            float targetPosition = absoluteBottomPosition - getTotalBottomMargin(hostView)
-                    - hostView.getHeight();
-            float currentPosition = mediaHost.getCurrentBounds().top
-                    - hostView.getTranslationY();
-            float translationY = targetPosition - currentPosition;
-            if (expanded) {
-                // Never go below the laid out position. This is necessary since the qs panel can
-                // change in height and we don't want to ever go below it's position
-                translationY = Math.min(translationY, 0);
-            } else {
-                translationY = Math.max(translationY, 0);
-            }
-            hostView.setTranslationY(translationY);
-        } else {
-            hostView.setTranslationY(0);
-        }
-    }
-
-    private float getTotalBottomMargin(View startView) {
-        int result = 0;
-        View child = startView;
-        View parent = (View) startView.getParent();
-        while (!(parent instanceof QSContainerImpl) && parent != null) {
-            result += parent.getHeight() - child.getBottom();
-            child = parent;
-            parent = (View) parent.getParent();
-        }
-        return result;
-    }
-
     private boolean headerWillBeAnimating() {
         return mState == StatusBarState.KEYGUARD && mShowCollapsedOnKeyguard
                 && !isKeyguardState();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index 584de6e..87fcce4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -80,9 +80,11 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
+import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.Background;
@@ -108,6 +110,8 @@
     protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final boolean DEBUG_FORCE_VISIBLE = false;
 
+    private static final String INTERACTION_JANK_TAG = "managed_device_info";
+
     private final TextView mFooterText;
     private final ImageView mPrimaryFooterIcon;
     private Context mContext;
@@ -557,7 +561,8 @@
 
                 mDialog.setView(view);
                 if (mView.isAggregatedVisible()) {
-                    mDialogLaunchAnimator.showFromView(mDialog, mView);
+                    mDialogLaunchAnimator.showFromView(mDialog, mView, new DialogCuj(
+                            InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG));
                 } else {
                     mDialog.show();
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index fbdabc7..a1c66b3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -396,7 +396,6 @@
     }
 
     void saveTilesToSettings(List<String> tileSpecs) {
-        if (tileSpecs.contains("work")) Log.wtfStack(TAG, "Saving work tile");
         mSecureSettings.putStringForUser(TILES_SETTING, TextUtils.join(",", tileSpecs),
                 null /* tag */, false /* default */, mCurrentUser,
                 true /* overrideable by restore */);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 1488231..a92c7e3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -39,6 +39,7 @@
 import com.android.systemui.qs.tiles.DataSaverTile;
 import com.android.systemui.qs.tiles.DeviceControlsTile;
 import com.android.systemui.qs.tiles.DndTile;
+import com.android.systemui.qs.tiles.DreamTile;
 import com.android.systemui.qs.tiles.FlashlightTile;
 import com.android.systemui.qs.tiles.HotspotTile;
 import com.android.systemui.qs.tiles.InternetTile;
@@ -96,6 +97,7 @@
     private final Provider<QuickAccessWalletTile> mQuickAccessWalletTileProvider;
     private final Provider<QRCodeScannerTile> mQRCodeScannerTileProvider;
     private final Provider<OneHandedModeTile> mOneHandedModeTileProvider;
+    private final Provider<DreamTile> mDreamTileProvider;
 
     private final Lazy<QSHost> mQsHostLazy;
     private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
@@ -132,7 +134,8 @@
             Provider<QuickAccessWalletTile> quickAccessWalletTileProvider,
             Provider<QRCodeScannerTile> qrCodeScannerTileProvider,
             Provider<OneHandedModeTile> oneHandedModeTileProvider,
-            Provider<ColorCorrectionTile> colorCorrectionTileProvider) {
+            Provider<ColorCorrectionTile> colorCorrectionTileProvider,
+            Provider<DreamTile> dreamTileProvider) {
         mQsHostLazy = qsHostLazy;
         mCustomTileBuilderProvider = customTileBuilderProvider;
 
@@ -165,6 +168,7 @@
         mQRCodeScannerTileProvider = qrCodeScannerTileProvider;
         mOneHandedModeTileProvider = oneHandedModeTileProvider;
         mColorCorrectionTileProvider = colorCorrectionTileProvider;
+        mDreamTileProvider = dreamTileProvider;
     }
 
     /** Creates a tile with a type based on {@code tileSpec} */
@@ -238,6 +242,8 @@
                 return mOneHandedModeTileProvider.get();
             case "color_correction":
                 return mColorCorrectionTileProvider.get();
+            case "dream":
+                return mDreamTileProvider.get();
         }
 
         // Custom tiles
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 59164de..5147d59 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -670,7 +670,8 @@
         "qr_code_scanner" to R.array.tile_states_qr_code_scanner,
         "alarm" to R.array.tile_states_alarm,
         "onehanded" to R.array.tile_states_onehanded,
-        "color_correction" to R.array.tile_states_color_correction
+        "color_correction" to R.array.tile_states_color_correction,
+        "dream" to R.array.tile_states_dream
     )
 
     fun getSubtitleId(spec: String?): Int {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index f736231..9a0d0d9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -16,12 +16,12 @@
 
 package com.android.systemui.qs.tiles;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
-import android.content.Context;
 import android.content.Intent;
-import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserManager;
@@ -134,9 +134,10 @@
         state.contentDescription = mContext.getString(
                 R.string.accessibility_quick_settings_bluetooth);
         state.stateDescription = "";
+
         if (enabled) {
             if (connected) {
-                state.icon = new BluetoothConnectedTileIcon();
+                state.icon = ResourceIcon.get(R.drawable.qs_bluetooth_icon_on);
                 if (!TextUtils.isEmpty(mController.getConnectedDeviceName())) {
                     state.label = mController.getConnectedDeviceName();
                 }
@@ -145,21 +146,19 @@
                                 + ", " + state.secondaryLabel;
             } else if (state.isTransient) {
                 state.icon = ResourceIcon.get(
-                        com.android.internal.R.drawable.ic_bluetooth_transient_animation);
+                        R.drawable.qs_bluetooth_icon_search);
                 state.stateDescription = state.secondaryLabel;
             } else {
                 state.icon =
-                        ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth);
+                        ResourceIcon.get(R.drawable.qs_bluetooth_icon_off);
                 state.stateDescription = mContext.getString(R.string.accessibility_not_connected);
             }
             state.state = Tile.STATE_ACTIVE;
         } else {
-            state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth);
+            state.icon = ResourceIcon.get(R.drawable.qs_bluetooth_icon_off);
             state.state = Tile.STATE_INACTIVE;
         }
 
-        state.dualLabelContentDescription = mContext.getResources().getString(
-                R.string.accessibility_quick_settings_open_settings, getTileLabel());
         state.expandedAccessibilityClassName = Switch.class.getName();
     }
 
@@ -185,10 +184,8 @@
         List<CachedBluetoothDevice> connectedDevices = mController.getConnectedDevices();
         if (enabled && connected && !connectedDevices.isEmpty()) {
             if (connectedDevices.size() > 1) {
-                // TODO(b/76102598): add a new string for "X connected devices" after P
-                return mContext.getResources().getQuantityString(
-                        R.plurals.quick_settings_hotspot_secondary_label_num_devices,
-                        connectedDevices.size(),
+                return icuMessageFormat(mContext.getResources(),
+                        R.string.quick_settings_hotspot_secondary_label_num_devices,
                         connectedDevices.size());
             }
 
@@ -244,22 +241,4 @@
             refreshState();
         }
     };
-
-    /**
-     * Bluetooth icon wrapper (when connected with no battery indicator) for Quick Settings. This is
-     * used instead of {@link com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon} in order to
-     * use a context that reflects dark/light theme attributes.
-     */
-    private class BluetoothConnectedTileIcon extends Icon {
-
-        BluetoothConnectedTileIcon() {
-            // Do nothing. Default constructor to limit visibility.
-        }
-
-        @Override
-        public Drawable getDrawable(Context context) {
-            // This method returns Pair<Drawable, String> - the first value is the drawable.
-            return context.getDrawable(R.drawable.ic_bluetooth_connected);
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 4afd39e3..dce137f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -33,10 +33,12 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.app.MediaRouteDialogPresenter;
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
+import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -63,6 +65,9 @@
 
 /** Quick settings tile: Cast **/
 public class CastTile extends QSTileImpl<BooleanState> {
+
+    private static final String INTERACTION_JANK_TAG = "cast";
+
     private static final Intent CAST_SETTINGS =
             new Intent(Settings.ACTION_CAST_SETTINGS);
 
@@ -211,7 +216,9 @@
 
             mUiHandler.post(() -> {
                 if (view != null) {
-                    mDialogLaunchAnimator.showFromView(dialog, view);
+                    mDialogLaunchAnimator.showFromView(dialog, view,
+                            new DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                                    INTERACTION_JANK_TAG));
                 } else {
                     dialog.show();
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
index 1bbe411..9fdf594 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java
@@ -24,10 +24,12 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
+import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -46,6 +48,8 @@
 public class DataSaverTile extends QSTileImpl<BooleanState> implements
         DataSaverController.Listener{
 
+    private static final String INTERACTION_JANK_TAG = "start_data_saver";
+
     private final DataSaverController mDataSaverController;
     private final DialogLaunchAnimator mDialogLaunchAnimator;
 
@@ -102,7 +106,9 @@
             dialog.setShowForAllUsers(true);
 
             if (view != null) {
-                mDialogLaunchAnimator.showFromView(dialog, view);
+                mDialogLaunchAnimator.showFromView(dialog, view, new DialogCuj(
+                        InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                        INTERACTION_JANK_TAG));
             } else {
                 dialog.show();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 6cff4cd..3dcfbc0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -39,11 +39,13 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.notification.EnableZenModeDialog;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
+import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -71,6 +73,8 @@
     private static final Intent ZEN_PRIORITY_SETTINGS =
             new Intent(Settings.ACTION_ZEN_MODE_PRIORITY_SETTINGS);
 
+    private static final String INTERACTION_JANK_TAG = "start_zen_mode";
+
     private final ZenModeController mController;
     private final SharedPreferences mSharedPreferences;
     private final SettingObserver mSettingZenDuration;
@@ -175,7 +179,10 @@
                     mUiHandler.post(() -> {
                         Dialog dialog = makeZenModeDialog();
                         if (view != null) {
-                            mDialogLaunchAnimator.showFromView(dialog, view, false);
+                            mDialogLaunchAnimator.showFromView(dialog, view, new DialogCuj(
+                                            InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                                            INTERACTION_JANK_TAG),
+                                    /* animateBackgroundBoundsChange= */ false);
                         } else {
                             dialog.show();
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java
new file mode 100644
index 0000000..bebd580
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.service.dreams.IDreamManager;
+import android.service.quicksettings.Tile;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.R;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dreams.dagger.DreamModule;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.SettingObserver;
+import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.util.settings.SecureSettings;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/** Quick settings tile: Screensaver (dream) **/
+public class DreamTile extends QSTileImpl<QSTile.BooleanState> {
+
+    private static final String LOG_TAG = "QSDream";
+    // TODO: consider 1 animated icon instead
+    private final Icon mIconDocked = ResourceIcon.get(R.drawable.ic_qs_screen_saver);
+    private final Icon mIconUndocked = ResourceIcon.get(R.drawable.ic_qs_screen_saver_undocked);
+    private final IDreamManager mDreamManager;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+    private final SettingObserver mEnabledSettingObserver;
+    private final SettingObserver mDreamSettingObserver;
+    private final UserTracker mUserTracker;
+    private final boolean mDreamSupported;
+    private final boolean mDreamOnlyEnabledForSystemUser;
+
+    private boolean mIsDocked = false;
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
+                mIsDocked = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, -1)
+                        != Intent.EXTRA_DOCK_STATE_UNDOCKED;
+            }
+            refreshState();
+        }
+    };
+
+    @Inject
+    public DreamTile(
+            QSHost host,
+            @Background Looper backgroundLooper,
+            @Main Handler mainHandler,
+            FalsingManager falsingManager,
+            MetricsLogger metricsLogger,
+            StatusBarStateController statusBarStateController,
+            ActivityStarter activityStarter,
+            QSLogger qsLogger,
+            IDreamManager dreamManager,
+            SecureSettings secureSettings,
+            BroadcastDispatcher broadcastDispatcher,
+            UserTracker userTracker,
+            @Named(DreamModule.DREAM_SUPPORTED) boolean dreamSupported,
+            @Named(DreamModule.DREAM_ONLY_ENABLED_FOR_SYSTEM_USER)
+                    boolean dreamOnlyEnabledForSystemUser
+    ) {
+        super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
+                statusBarStateController, activityStarter, qsLogger);
+        mDreamManager = dreamManager;
+        mBroadcastDispatcher = broadcastDispatcher;
+        mEnabledSettingObserver = new SettingObserver(secureSettings, mHandler,
+                Settings.Secure.SCREENSAVER_ENABLED) {
+            @Override
+            protected void handleValueChanged(int value, boolean observedChange) {
+                refreshState();
+            }
+        };
+        mDreamSettingObserver = new SettingObserver(secureSettings, mHandler,
+                Settings.Secure.SCREENSAVER_COMPONENTS) {
+            @Override
+            protected void handleValueChanged(int value, boolean observedChange) {
+                refreshState();
+            }
+        };
+        mUserTracker = userTracker;
+        mDreamSupported = dreamSupported;
+        mDreamOnlyEnabledForSystemUser = dreamOnlyEnabledForSystemUser;
+    }
+
+    @Override
+    public void handleSetListening(boolean listening) {
+        super.handleSetListening(listening);
+
+        if (listening) {
+            final IntentFilter filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_DREAMING_STARTED);
+            filter.addAction(Intent.ACTION_DREAMING_STOPPED);
+            filter.addAction(Intent.ACTION_DOCK_EVENT);
+            mBroadcastDispatcher.registerReceiver(mReceiver, filter);
+        } else {
+            mBroadcastDispatcher.unregisterReceiver(mReceiver);
+        }
+        mEnabledSettingObserver.setListening(listening);
+        mDreamSettingObserver.setListening(listening);
+    }
+
+    @Override
+    public BooleanState newTileState() {
+        return new BooleanState();
+    }
+
+    @Override
+    protected void handleClick(@Nullable View view) {
+        try {
+            if (mDreamManager.isDreaming()) {
+                mDreamManager.awaken();
+            } else {
+                mDreamManager.dream();
+            }
+        } catch (RemoteException e) {
+            Log.e(LOG_TAG, "Can't dream", e);
+        }
+    }
+
+    @Override
+    protected void handleLongClick(@Nullable View view) {
+        try {
+            // Need to wake on long click so bouncer->settings works.
+            mDreamManager.awaken();
+        } catch (RemoteException e) {
+            Log.e(LOG_TAG, "Can't awaken", e);
+        }
+        super.handleLongClick(view);
+    }
+
+    @Override
+    protected void handleUpdateState(BooleanState state, Object arg) {
+        state.label = getTileLabel();
+        state.secondaryLabel = getActiveDreamName();
+        state.contentDescription = getContentDescription(state.secondaryLabel);
+        state.icon = mIsDocked ? mIconDocked : mIconUndocked;
+
+        if (getActiveDream() == null || !isScreensaverEnabled()) {
+            state.state = Tile.STATE_UNAVAILABLE;
+        } else {
+            state.state = isDreaming() ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+        }
+    }
+
+    @Nullable
+    @Override
+    public Intent getLongClickIntent() {
+        return new Intent(Settings.ACTION_DREAM_SETTINGS);
+    }
+
+    @Override
+    public CharSequence getTileLabel() {
+        return mContext.getString(R.string.quick_settings_screensaver_label);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        // Only enable for devices that have dreams for the user(s) that can dream.
+        // For now, restrict to debug users.
+        return Build.isDebuggable()
+                && mDreamSupported
+                && (!mDreamOnlyEnabledForSystemUser || mUserTracker.getUserHandle().isSystem());
+    }
+
+    @VisibleForTesting
+    protected CharSequence getContentDescription(CharSequence dreamName) {
+        return !TextUtils.isEmpty(dreamName)
+                ? getTileLabel() + ", " + dreamName : getTileLabel();
+    }
+
+    private boolean isDreaming() {
+        try {
+            return mDreamManager.isDreaming();
+        } catch (RemoteException e) {
+            Log.e(LOG_TAG, "Can't check if dreaming", e);
+            return false;
+        }
+    }
+
+    private ComponentName getActiveDream() {
+        try {
+            final ComponentName[] dreams = mDreamManager.getDreamComponents();
+            return dreams != null && dreams.length > 0 ? dreams[0] : null;
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to get active dream", e);
+            return null;
+        }
+    }
+
+    private CharSequence getActiveDreamName() {
+        final ComponentName componentName = getActiveDream();
+        if (componentName != null) {
+            PackageManager pm = mContext.getPackageManager();
+            try {
+                ServiceInfo ri = pm.getServiceInfo(componentName, 0);
+                if (ri != null) {
+                    return ri.loadLabel(pm);
+                }
+            } catch (PackageManager.NameNotFoundException exc) {
+                return null; // uninstalled?
+            }
+        }
+        return null;
+    }
+
+    private boolean isScreensaverEnabled() {
+        return mEnabledSettingObserver.getValue() == 1;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 7c8e77b..b6f6e93 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.qs.tiles;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.content.Intent;
 import android.os.Handler;
 import android.os.Looper;
@@ -186,9 +188,8 @@
             return mContext.getString(
                     R.string.quick_settings_hotspot_secondary_label_data_saver_enabled);
         } else if (numConnectedDevices > 0 && isActive) {
-            return mContext.getResources().getQuantityString(
-                    R.plurals.quick_settings_hotspot_secondary_label_num_devices,
-                    numConnectedDevices,
+            return icuMessageFormat(mContext.getResources(),
+                    R.string.quick_settings_hotspot_secondary_label_num_devices,
                     numConnectedDevices);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 177c82e..600874f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -57,6 +57,7 @@
 /** Quick settings tile: Rotation **/
 public class RotationLockTile extends QSTileImpl<BooleanState> implements
         BatteryController.BatteryStateChangeCallback {
+    private static final String EMPTY_SECONDARY_STRING = "";
 
     private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_auto_rotate);
     private final RotationLockController mController;
@@ -144,13 +145,15 @@
                         && mController.isCameraRotationEnabled();
         state.value = !rotationLocked;
         state.label = mContext.getString(R.string.quick_settings_rotation_unlocked_label);
-        state.icon = mIcon;
+        state.icon = ResourceIcon.get(R.drawable.qs_auto_rotate_icon_off);
         state.contentDescription = getAccessibilityString(rotationLocked);
-        if (!rotationLocked && cameraRotation) {
-            state.secondaryLabel = mContext.getResources().getString(
-                    R.string.rotation_lock_camera_rotation_on);
+        if (!rotationLocked) {
+            state.secondaryLabel = cameraRotation ? mContext.getResources().getString(
+                    R.string.rotation_lock_camera_rotation_on)
+                    : EMPTY_SECONDARY_STRING;
+            state.icon = ResourceIcon.get(R.drawable.qs_auto_rotate_icon_on);
         } else {
-            state.secondaryLabel = "";
+            state.secondaryLabel = EMPTY_SECONDARY_STRING;
         }
         state.stateDescription = state.secondaryLabel;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index 45e43ee..02d30c52 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -27,8 +27,10 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
+import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -52,6 +54,8 @@
 public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
         implements RecordingController.RecordingStateChangeCallback {
     private static final String TAG = "ScreenRecordTile";
+    private static final String INTERACTION_JANK_TAG = "screen_record";
+
     private final RecordingController mController;
     private final KeyguardDismissUtil mKeyguardDismissUtil;
     private final KeyguardStateController mKeyguardStateController;
@@ -165,7 +169,8 @@
 
         ActivityStarter.OnDismissAction dismissAction = () -> {
             if (shouldAnimateFromView) {
-                mDialogLaunchAnimator.showFromView(dialog, view);
+                mDialogLaunchAnimator.showFromView(dialog, view, new DialogCuj(
+                        InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG));
             } else {
                 dialog.show();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
index 4386169..8566ca3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
@@ -19,7 +19,9 @@
 import android.os.Handler
 import android.util.Log
 import android.view.View
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.UiEventLogger
+import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
@@ -45,6 +47,7 @@
     private val keyguardStateController: KeyguardStateController
 ) {
     companion object {
+        private const val INTERACTION_JANK_TAG = "internet"
         var internetDialog: InternetDialog? = null
     }
 
@@ -61,12 +64,20 @@
             }
             return
         } else {
-            internetDialog = InternetDialog(context, this, internetDialogController,
-                    canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler,
-                    executor, keyguardStateController)
+            internetDialog = InternetDialog(
+                context, this, internetDialogController,
+                canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler,
+                executor, keyguardStateController
+            )
             if (view != null) {
-                dialogLaunchAnimator.showFromView(internetDialog!!, view,
-                    animateBackgroundBoundsChange = true)
+                dialogLaunchAnimator.showFromView(
+                    internetDialog!!, view,
+                    animateBackgroundBoundsChange = true,
+                    cuj = DialogCuj(
+                        InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                        INTERACTION_JANK_TAG
+                    )
+                )
             } else {
                 internetDialog?.show()
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
index 88aa734..260a371 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
@@ -25,8 +25,10 @@
 import android.view.LayoutInflater
 import android.view.View
 import androidx.annotation.VisibleForTesting
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.R
+import com.android.systemui.animation.DialogCuj
 import com.android.systemui.animation.DialogLaunchAnimator
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.plugins.ActivityStarter
@@ -67,6 +69,7 @@
     )
 
     companion object {
+        private const val INTERACTION_JANK_TAG = "switch_user"
         private val USER_SETTINGS_INTENT = Intent(Settings.ACTION_USER_SETTINGS)
     }
 
@@ -89,14 +92,16 @@
                 if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
                     uiEventLogger.log(QSUserSwitcherEvent.QS_USER_MORE_SETTINGS)
                     val controller = dialogLaunchAnimator.createActivityLaunchController(
-                        getButton(BUTTON_NEUTRAL))
+                        getButton(BUTTON_NEUTRAL)
+                    )
 
                     if (controller == null) {
                         dismiss()
                     }
 
                     activityStarter.postStartActivityDismissingKeyguard(
-                        USER_SETTINGS_INTENT, 0, controller)
+                        USER_SETTINGS_INTENT, 0, controller
+                    )
                 }
             }, false /* dismissOnClick */)
             val gridFrame = LayoutInflater.from(this.context)
@@ -107,7 +112,13 @@
 
             adapter.linkToViewGroup(gridFrame.findViewById(R.id.grid))
 
-            dialogLaunchAnimator.showFromView(this, view)
+            dialogLaunchAnimator.showFromView(
+                this, view,
+                cuj = DialogCuj(
+                    InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                    INTERACTION_JANK_TAG
+                )
+            )
             uiEventLogger.log(QSUserSwitcherEvent.QS_USER_DETAIL_OPEN)
             adapter.injectDialogShower(DialogShowerImpl(this, dialogLaunchAnimator))
         }
@@ -128,4 +139,4 @@
     interface DialogShower : DialogInterface {
         fun showDialog(dialog: Dialog)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 9768e70..6c58c45 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -297,12 +297,6 @@
         }
 
         @Override
-        public Rect getNonMinimizedSplitScreenSecondaryBounds() {
-            // Deprecated
-            return null;
-        }
-
-        @Override
         public void setNavBarButtonAlpha(float alpha, boolean animate) {
             verifyCallerAndClearCallingIdentityPostMain("setNavBarButtonAlpha", () ->
                     notifyNavBarButtonAlphaChanged(alpha, animate));
@@ -349,17 +343,6 @@
         }
 
         @Override
-        public void handleImageAsScreenshot(Bitmap screenImage, Rect locationInScreen,
-                                            Insets visibleInsets, int taskId) {
-            // Deprecated
-        }
-
-        @Override
-        public void setSplitScreenMinimized(boolean minimized) {
-            // Deprecated
-        }
-
-        @Override
         public void notifySwipeToHomeFinished() {
             verifyCallerAndClearCallingIdentity("notifySwipeToHomeFinished", () ->
                     mPipOptional.ifPresent(
@@ -736,7 +719,7 @@
     }
 
     private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded,
-            boolean bouncerShowing, boolean isDozing) {
+            boolean bouncerShowing, boolean isDozing, boolean panelExpanded) {
         mSysUiState.setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
                         keyguardShowing && !keyguardOccluded)
                 .setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
index d3ae198..236ba1f 100644
--- a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
@@ -56,6 +56,8 @@
         ):
                 BcSmartspaceDataPlugin.SmartspaceView {
             val ssView = plugin.getView(parent)
+            // Currently, this is only used to provide SmartspaceView on Dream surface.
+            ssView.setIsDreaming(true)
             ssView.registerDataProvider(plugin)
 
             ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter {
@@ -81,4 +83,4 @@
             return ssView
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
index 6cfbb43..07455a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
@@ -66,7 +66,7 @@
      * @param entry entry to show
      */
     public void showNotification(@NonNull NotificationEntry entry) {
-        mLogger.logShowNotification(entry.getKey());
+        mLogger.logShowNotification(entry);
         addAlertEntry(entry);
         updateNotification(entry.getKey(), true /* alert */);
         entry.setInterruption();
@@ -320,7 +320,7 @@
          * @param updatePostTime whether or not to refresh the post time
          */
         public void updateEntry(boolean updatePostTime) {
-            mLogger.logUpdateEntry(mEntry.getKey(), updatePostTime);
+            mLogger.logUpdateEntry(mEntry, updatePostTime);
 
             long currentTime = mClock.currentTimeMillis();
             mEarliestRemovaltime = currentTime + mMinimumDisplayTime;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index c1ea6bf..9d80d5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -178,7 +178,7 @@
     val touchHelper = DragDownHelper(falsingManager, falsingCollector, this, context)
 
     private val splitShadeOverScroller: SplitShadeLockScreenOverScroller by lazy {
-        splitShadeOverScrollerFactory.create(qS, nsslController)
+        splitShadeOverScrollerFactory.create({ qS }, { nsslController })
     }
 
     private val phoneShadeOverScroller: SingleShadeLockScreenOverScroller by lazy {
@@ -911,4 +911,4 @@
         host.getLocationOnScreen(temp2)
         return expandCallback.getChildAtRawPosition(x + temp2[0], y + temp2[1])
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index d71dec8..5cdd01f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -68,6 +68,7 @@
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 import com.android.systemui.statusbar.policy.RemoteInputView;
 import com.android.systemui.util.DumpUtilsKt;
+import com.android.systemui.util.ListenerSet;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -75,6 +76,7 @@
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import java.util.function.Consumer;
 
 import dagger.Lazy;
 
@@ -118,6 +120,8 @@
     protected Callback mCallback;
 
     private final List<RemoteInputController.Callback> mControllerCallbacks = new ArrayList<>();
+    private final ListenerSet<Consumer<NotificationEntry>> mActionPressListeners =
+            new ListenerSet<>();
 
     private final InteractionHandler mInteractionHandler = new InteractionHandler() {
 
@@ -401,6 +405,14 @@
         }
     }
 
+    public void addActionPressListener(Consumer<NotificationEntry> listener) {
+        mActionPressListeners.addIfAbsent(listener);
+    }
+
+    public void removeActionPressListener(Consumer<NotificationEntry> listener) {
+        mActionPressListeners.remove(listener);
+    }
+
     /**
      * Activates a given {@link RemoteInput}
      *
@@ -634,6 +646,9 @@
         if (mRemoteInputListener != null) {
             mRemoteInputListener.releaseNotificationIfKeptForRemoteInputHistory(entry);
         }
+        for (Consumer<NotificationEntry> listener : mActionPressListeners) {
+            listener.accept(entry);
+        }
     }
 
     /** Returns whether the notification should be lifetime extended for smart reply history */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 0d60401..a146340 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -229,6 +229,17 @@
         mActualWidth = actualWidth;
     }
 
+    @Override
+    public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
+        super.getBoundsOnScreen(outRect, clipToParent);
+        final int actualWidth = getActualWidth();
+        if (isLayoutRtl()) {
+            outRect.left = outRect.right - actualWidth;
+        } else {
+            outRect.right = outRect.left + actualWidth;
+        }
+    }
+
     /**
      * @return Actual width of shelf, accounting for possible ongoing width animation
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt b/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
index 96ce6b4..13d8adb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
@@ -9,6 +9,7 @@
 import com.android.internal.annotations.VisibleForTesting
 import com.android.systemui.R
 import com.android.systemui.animation.Interpolators
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.qs.QS
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.phone.ScrimController
@@ -16,16 +17,18 @@
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import java.io.PrintWriter
 
 class SplitShadeLockScreenOverScroller
 @AssistedInject
 constructor(
     configurationController: ConfigurationController,
+    dumpManager: DumpManager,
     private val context: Context,
     private val scrimController: ScrimController,
     private val statusBarStateController: SysuiStatusBarStateController,
-    @Assisted private val qS: QS,
-    @Assisted private val nsslController: NotificationStackScrollLayoutController
+    @Assisted private val qSProvider: () -> QS,
+    @Assisted private val nsslControllerProvider: () -> NotificationStackScrollLayoutController
 ) : LockScreenShadeOverScroller {
 
     private var releaseOverScrollAnimator: Animator? = null
@@ -34,6 +37,12 @@
     private var maxOverScrollAmount = 0
     private var previousOverscrollAmount = 0
 
+    private val qS: QS
+        get() = qSProvider()
+
+    private val nsslController: NotificationStackScrollLayoutController
+        get() = nsslControllerProvider()
+
     init {
         updateResources()
         configurationController.addCallback(
@@ -42,6 +51,9 @@
                     updateResources()
                 }
             })
+        dumpManager.registerDumpable("SplitShadeLockscreenOverScroller") { printWriter, _ ->
+            dump(printWriter)
+        }
     }
 
     private fun updateResources() {
@@ -114,11 +126,25 @@
         releaseOverScrollAnimator = null
     }
 
+    private fun dump(printWriter: PrintWriter) {
+        printWriter.println(
+            """
+            SplitShadeLockScreenOverScroller:
+                Resources:
+                    transitionToFullShadeDistance: $transitionToFullShadeDistance
+                    maxOverScrollAmount: $maxOverScrollAmount
+                    releaseOverScrollDuration: $releaseOverScrollDuration
+                State:
+                    previousOverscrollAmount: $previousOverscrollAmount
+                    expansionDragDownAmount: $expansionDragDownAmount
+            """.trimIndent())
+    }
+
     @AssistedFactory
     fun interface Factory {
         fun create(
-            qS: QS,
-            nsslController: NotificationStackScrollLayoutController
+            qSProvider: () -> QS,
+            nsslControllerProvider: () -> NotificationStackScrollLayoutController
         ): SplitShadeLockScreenOverScroller
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarState.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarState.java
index 718bc5c..f78b067 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarState.java
@@ -22,18 +22,21 @@
 public class StatusBarState {
 
     /**
-     * The status bar is in the "normal" shade mode.
+     * The status bar is in the "normal", unlocked mode or the device is still locked but we're
+     * accessing camera from power button double-tap shortcut.
      */
     public static final int SHADE = 0;
 
     /**
-     * Status bar is currently the Keyguard.
+     * Status bar is currently the Keyguard. In single column mode, when you swipe from the top of
+     * the keyguard to expand QS immediately, it's still KEYGUARD state.
      */
     public static final int KEYGUARD = 1;
 
     /**
-     * Status bar is in the special mode, where it is fully interactive but still locked. So
-     * dismissing the shade will still show the bouncer.
+     * Status bar is in the special mode, where it was transitioned from lockscreen to shade.
+     * Depending on user's security settings, dismissing the shade will either show the
+     * bouncer or go directly to unlocked {@link #SHADE} mode.
      */
     public static final int SHADE_LOCKED = 2;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
index 5df593b..558bcac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
@@ -61,7 +61,7 @@
     private val systemClock: SystemClock,
     private val uiEventLogger: UiEventLogger
 ) {
-    private var pluggedIn: Boolean? = null
+    private var pluggedIn: Boolean = false
     private val rippleEnabled: Boolean = featureFlags.isEnabled(Flags.CHARGING_RIPPLE) &&
             !SystemProperties.getBoolean("persist.debug.suppress-charging-ripple", false)
     private var normalizedPortPosX: Float = context.resources.getFloat(
@@ -99,15 +99,17 @@
                 nowPluggedIn: Boolean,
                 charging: Boolean
             ) {
-                // Suppresses the ripple when the state change comes from wireless charging.
-                if (batteryController.isPluggedInWireless) {
+                // Suppresses the ripple when the state change comes from wireless charging or
+                // its dock.
+                if (batteryController.isPluggedInWireless ||
+                        batteryController.isChargingSourceDock) {
                     return
                 }
-                val wasPluggedIn = pluggedIn
-                pluggedIn = nowPluggedIn
-                if ((wasPluggedIn == null || !wasPluggedIn) && nowPluggedIn) {
+
+                if (!pluggedIn && nowPluggedIn) {
                     startRippleWithDebounce()
                 }
+                pluggedIn = nowPluggedIn
             }
         }
         batteryController.addCallback(batteryStateChangeCallback)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
index d49e1e6..a1dc7b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
@@ -73,6 +73,9 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
+import com.android.systemui.log.LogBuffer;
+import com.android.systemui.log.LogLevel;
+import com.android.systemui.log.dagger.StatusBarNetworkControllerLog;
 import com.android.systemui.qs.tiles.dialog.InternetDialogFactory;
 import com.android.systemui.settings.CurrentUserTracker;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -94,9 +97,12 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 
+import kotlin.Unit;
+
 /** Platform implementation of the network controller. **/
 @SysUISingleton
 public class NetworkControllerImpl extends BroadcastReceiver
@@ -133,6 +139,7 @@
     private final CarrierConfigTracker mCarrierConfigTracker;
     private final FeatureFlags mFeatureFlags;
     private final DumpManager mDumpManager;
+    private final LogBuffer mLogBuffer;
 
     private TelephonyCallback.ActiveDataSubscriptionIdListener mPhoneStateListener;
     private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -231,7 +238,8 @@
             @Main Handler handler,
             InternetDialogFactory internetDialogFactory,
             FeatureFlags featureFlags,
-            DumpManager dumpManager) {
+            DumpManager dumpManager,
+            @StatusBarNetworkControllerLog LogBuffer logBuffer) {
         this(context, connectivityManager,
                 telephonyManager,
                 telephonyListenerManager,
@@ -251,7 +259,8 @@
                 trackerFactory,
                 handler,
                 featureFlags,
-                dumpManager);
+                dumpManager,
+                logBuffer);
         mReceiverHandler.post(mRegisterListeners);
         mInternetDialogFactory = internetDialogFactory;
     }
@@ -276,7 +285,8 @@
             WifiStatusTrackerFactory trackerFactory,
             @Main Handler handler,
             FeatureFlags featureFlags,
-            DumpManager dumpManager
+            DumpManager dumpManager,
+            LogBuffer logBuffer
     ) {
         mContext = context;
         mTelephonyListenerManager = telephonyListenerManager;
@@ -297,6 +307,7 @@
         mCarrierConfigTracker = carrierConfigTracker;
         mFeatureFlags = featureFlags;
         mDumpManager = dumpManager;
+        mLogBuffer = logBuffer;
 
         // telephony
         mPhone = telephonyManager;
@@ -770,6 +781,17 @@
             Log.d(TAG, "onReceive: intent=" + intent);
         }
         final String action = intent.getAction();
+        mLogBuffer.log(
+                TAG,
+                LogLevel.INFO,
+                logMessage -> {
+                    logMessage.setStr1(action);
+                    return Unit.INSTANCE;
+                },
+                logMessage -> String.format(
+                        Locale.US,
+                        "Received broadcast with action \"%s\"",
+                        logMessage.getStr1()));
         switch (action) {
             case ConnectivityManager.CONNECTIVITY_ACTION:
                 updateConnectivity();
@@ -937,6 +959,12 @@
                         : lhs.getSimSlotIndex() - rhs.getSimSlotIndex();
             }
         });
+        Log.i(
+                TAG,
+                String.format(
+                        Locale.US,
+                        "Subscriptions changed: %s",
+                        createSubscriptionChangeStatement(mCurrentSubscriptions, subscriptions)));
         mCurrentSubscriptions = subscriptions;
 
         SparseArray<MobileSignalController> cachedControllers =
@@ -1154,6 +1182,7 @@
         pw.print("  hasVoiceCallingFeature()=");
         pw.println(hasVoiceCallingFeature());
         pw.println("  mListening=" + mListening);
+        pw.println("  mActiveMobileDataSubscription=" + mActiveMobileDataSubscription);
 
         pw.println("  - connectivity ------");
         pw.print("  mConnectedTransports=");
@@ -1473,4 +1502,23 @@
      * get created will also run on the BG Looper.
      */
     private final Runnable mRegisterListeners = () -> registerListeners();
+
+    /** Returns a logging statement for the given old and new list of {@link SubscriptionInfo} */
+    private static String createSubscriptionChangeStatement(
+            final @Nullable List<SubscriptionInfo> oldSubscriptions,
+            final @Nullable List<SubscriptionInfo> newSubscriptions) {
+        return String.format(
+                Locale.US,
+                "old=%s, new=%s",
+                toSubscriptionIds(oldSubscriptions),
+                toSubscriptionIds(newSubscriptions));
+    }
+
+    /** Returns to a list of subscription IDs for the given list of {@link SubscriptionInfo} */
+    @Nullable
+    private static List<Integer> toSubscriptionIds(
+            final @Nullable List<SubscriptionInfo> subscriptions) {
+        return subscriptions != null ? subscriptions.stream().map(
+                SubscriptionInfo::getSubscriptionId).collect(Collectors.toList()) : null;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index 29411e6..03d66ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -21,6 +21,7 @@
 import android.os.Handler;
 import android.service.dreams.IDreamManager;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.animation.ActivityLaunchAnimator;
@@ -317,7 +318,8 @@
      */
     @Provides
     @SysUISingleton
-    static DialogLaunchAnimator provideDialogLaunchAnimator(IDreamManager dreamManager) {
-        return new DialogLaunchAnimator(dreamManager);
+    static DialogLaunchAnimator provideDialogLaunchAnimator(IDreamManager dreamManager,
+            InteractionJankMonitor interactionJankMonitor) {
+        return new DialogLaunchAnimator(dreamManager, interactionJankMonitor);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index a35bced..a509fca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -37,6 +37,8 @@
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.BcSmartspaceDataPlugin
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
@@ -44,13 +46,11 @@
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.util.concurrency.Execution
 import com.android.systemui.util.settings.SecureSettings
-import java.lang.RuntimeException
 import java.util.Optional
 import java.util.concurrent.Executor
 import javax.inject.Inject
@@ -71,6 +71,7 @@
     private val configurationController: ConfigurationController,
     private val statusBarStateController: StatusBarStateController,
     private val deviceProvisionedController: DeviceProvisionedController,
+    private val bypassController: KeyguardBypassController,
     private val execution: Execution,
     @Main private val uiExecutor: Executor,
     @Main private val handler: Handler,
@@ -154,6 +155,13 @@
             }
         }
 
+    private val bypassStateChangedListener =
+        object : KeyguardBypassController.OnBypassStateChangedListener {
+            override fun onBypassStateChanged(isEnabled: Boolean) {
+                updateBypassEnabled()
+            }
+        }
+
     init {
         deviceProvisionedController.addCallback(deviceProvisionedListener)
     }
@@ -164,6 +172,11 @@
         return featureFlags.isEnabled(Flags.SMARTSPACE) && plugin != null
     }
 
+    private fun updateBypassEnabled() {
+        val bypassEnabled = bypassController.bypassEnabled
+        smartspaceViews.forEach { it.setKeyguardBypassEnabled(bypassEnabled) }
+    }
+
     /**
      * Constructs the smartspace view and connects it to the smartspace service.
      */
@@ -211,6 +224,7 @@
             }
         })
         ssView.setFalsingManager(falsingManager)
+        ssView.setKeyguardBypassEnabled(bypassController.bypassEnabled)
         return (ssView as View).apply { addOnAttachStateChangeListener(stateChangeListener) }
     }
 
@@ -248,11 +262,13 @@
         )
         configurationController.addCallback(configChangeListener)
         statusBarStateController.addCallback(statusBarStateListener)
+        bypassController.registerOnBypassStateChangedListener(bypassStateChangedListener)
 
         plugin.registerSmartspaceEventNotifier {
                 e -> session?.notifySmartspaceEvent(e)
         }
 
+        updateBypassEnabled()
         reloadSmartspace()
     }
 
@@ -276,6 +292,7 @@
         contentResolver.unregisterContentObserver(settingsObserver)
         configurationController.removeCallback(configChangeListener)
         statusBarStateController.removeCallback(statusBarStateListener)
+        bypassController.unregisterOnBypassStateChangedListener(bypassStateChangedListener)
         session = null
 
         plugin?.registerSmartspaceEventNotifier(null)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
index a0ccd57..1be4c04 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
@@ -80,7 +80,7 @@
 
     @VisibleForTesting
     boolean isDynamicPrivacyEnabled() {
-        return !mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(
+        return mLockscreenUserManager.userAllowsNotificationsInPublic(
                 mLockscreenUserManager.getCurrentUserId());
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index df412ed..8cb18a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -260,7 +260,7 @@
 
         Intent browserIntent = getTaskIntent(taskId, userId);
         Notification.Builder builder =
-                new Notification.Builder(mContext, NotificationChannels.GENERAL);
+                new Notification.Builder(mContext, NotificationChannels.INSTANT);
         if (browserIntent != null && browserIntent.isWebIntent()) {
             // Make sure that this doesn't resolve back to an instant app
             browserIntent
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
index f6a55e6..c4947ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
@@ -48,8 +48,7 @@
     fun assertLegacyPipelineEnabled(): Unit =
         check(!isNewPipelineEnabled()) { "Old pipeline code running w/ new pipeline enabled" }
 
-    fun isNewPipelineEnabled(): Boolean =
-        featureFlags.isEnabled(Flags.NEW_NOTIFICATION_PIPELINE_RENDERING)
+    fun isNewPipelineEnabled(): Boolean = true
 
     fun isDevLoggingEnabled(): Boolean =
         featureFlags.isEnabled(Flags.NOTIFICATION_PIPELINE_DEVELOPER_LOGGING)
@@ -57,4 +56,7 @@
     fun isSmartspaceDedupingEnabled(): Boolean =
             featureFlags.isEnabled(Flags.SMARTSPACE) &&
                     featureFlags.isEnabled(Flags.SMARTSPACE_DEDUPING)
-}
\ No newline at end of file
+
+    fun removeUnrankedNotifs(): Boolean =
+        featureFlags.isEnabled(Flags.REMOVE_UNRANKED_NOTIFICATIONS)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManagerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManagerLogger.kt
index 2397005..52dcf02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManagerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManagerLogger.kt
@@ -17,18 +17,32 @@
 package com.android.systemui.statusbar.notification
 
 import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
 import com.android.systemui.log.LogLevel.DEBUG
 import com.android.systemui.log.LogLevel.INFO
 import com.android.systemui.log.LogLevel.WARNING
+import com.android.systemui.log.LogMessage
 import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.util.Compile
 import javax.inject.Inject
 
 /** Logger for [NotificationEntryManager]. */
 class NotificationEntryManagerLogger @Inject constructor(
+    notifPipelineFlags: NotifPipelineFlags,
     @NotificationLog private val buffer: LogBuffer
 ) {
+    private val devLoggingEnabled by lazy { notifPipelineFlags.isDevLoggingEnabled() }
+
+    private inline fun devLog(
+        level: LogLevel,
+        initializer: LogMessage.() -> Unit,
+        noinline printer: LogMessage.() -> String
+    ) {
+        if (Compile.IS_DEBUG && devLoggingEnabled) buffer.log(TAG, level, initializer, printer)
+    }
+
     fun logNotifAdded(key: String) {
-        buffer.log(TAG, INFO, {
+        devLog(INFO, {
             str1 = key
         }, {
             "NOTIF ADDED $str1"
@@ -36,7 +50,7 @@
     }
 
     fun logNotifUpdated(key: String) {
-        buffer.log(TAG, INFO, {
+        devLog(INFO, {
             str1 = key
         }, {
             "NOTIF UPDATED $str1"
@@ -44,7 +58,7 @@
     }
 
     fun logInflationAborted(key: String, status: String, reason: String) {
-        buffer.log(TAG, DEBUG, {
+        devLog(DEBUG, {
             str1 = key
             str2 = status
             str3 = reason
@@ -54,7 +68,7 @@
     }
 
     fun logNotifInflated(key: String, isNew: Boolean) {
-        buffer.log(TAG, DEBUG, {
+        devLog(DEBUG, {
             str1 = key
             bool1 = isNew
         }, {
@@ -63,7 +77,7 @@
     }
 
     fun logRemovalIntercepted(key: String) {
-        buffer.log(TAG, INFO, {
+        devLog(INFO, {
             str1 = key
         }, {
             "NOTIF REMOVE INTERCEPTED for $str1"
@@ -71,7 +85,7 @@
     }
 
     fun logLifetimeExtended(key: String, extenderName: String, status: String) {
-        buffer.log(TAG, INFO, {
+        devLog(INFO, {
             str1 = key
             str2 = extenderName
             str3 = status
@@ -81,7 +95,7 @@
     }
 
     fun logNotifRemoved(key: String, removedByUser: Boolean) {
-        buffer.log(TAG, INFO, {
+        devLog(INFO, {
             str1 = key
             bool1 = removedByUser
         }, {
@@ -90,7 +104,7 @@
     }
 
     fun logFilterAndSort(reason: String) {
-        buffer.log(TAG, INFO, {
+        devLog(INFO, {
             str1 = reason
         }, {
             "FILTER AND SORT reason=$str1"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
new file mode 100644
index 0000000..ed80f33
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
@@ -0,0 +1,14 @@
+set noparent
+
+# Bug component: 78010
+
+aaliomer@google.com
+aroederer@google.com
+jeffdq@google.com
+juliacr@google.com
+juliatuttle@google.com
+lynhan@google.com
+steell@google.com
+yurilin@google.com
+
+per-file MediaNotificationProcessor.java = ethibodeau@google.com, asc@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
index 6be8a49..f6a572e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.collection;
 
+import static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
 import static com.android.systemui.statusbar.notification.collection.NotifCollection.REASON_NOT_CANCELED;
 import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.NOT_DISMISSED;
 
@@ -52,7 +53,7 @@
                     sb,
                     true,
                     includeRecordKeeping,
-                    interactionTracker.hasUserInteractedWith(entry.getKey()));
+                    interactionTracker.hasUserInteractedWith(logKey(entry)));
             if (entry instanceof GroupEntry) {
                 GroupEntry ge = (GroupEntry) entry;
                 NotificationEntry summary = ge.getSummary();
@@ -63,7 +64,7 @@
                             sb,
                             true,
                             includeRecordKeeping,
-                            interactionTracker.hasUserInteractedWith(summary.getKey()));
+                            interactionTracker.hasUserInteractedWith(logKey(summary)));
                 }
                 List<NotificationEntry> children = ge.getChildren();
                 for (int childIndex = 0;  childIndex < children.size(); childIndex++) {
@@ -74,7 +75,7 @@
                             sb,
                             true,
                             includeRecordKeeping,
-                            interactionTracker.hasUserInteractedWith(child.getKey()));
+                            interactionTracker.hasUserInteractedWith(logKey(child)));
                 }
             }
         }
@@ -115,12 +116,19 @@
     ) {
         sb.append(indent)
                 .append("[").append(index).append("] ")
-                .append(entry.getKey());
+                .append(index.length() == 1 ? " " : "")
+                .append(logKey(entry));
 
         if (includeParent) {
             sb.append(" (parent=")
-                    .append(entry.getParent() != null ? entry.getParent().getKey() : null)
+                    .append(logKey(entry.getParent()))
                     .append(")");
+
+            NotificationEntry notifEntry = entry.getRepresentativeEntry();
+            if (notifEntry != null) {
+                sb.append(" rank=")
+                        .append(notifEntry.getRanking().getRank());
+            }
         }
 
         if (entry.getSection() != null) {
@@ -178,15 +186,15 @@
 
             if (notifEntry.getAttachState().getSuppressedChanges().getParent() != null) {
                 rksb.append("suppressedParent=")
-                        .append(notifEntry.getAttachState().getSuppressedChanges()
-                                .getParent().getKey())
+                        .append(logKey(notifEntry.getAttachState().getSuppressedChanges()
+                                .getParent()))
                         .append(" ");
             }
 
             if (notifEntry.getAttachState().getSuppressedChanges().getSection() != null) {
                 rksb.append("suppressedSection=")
                         .append(notifEntry.getAttachState().getSuppressedChanges()
-                                .getSection())
+                                .getSection().getLabel())
                         .append(" ");
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index 6085096..e345aab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -89,6 +89,7 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.InternalNotifUpdater;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionLogger;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionLoggerKt;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifEvent;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
@@ -104,11 +105,13 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Queue;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 import javax.inject.Inject;
@@ -156,6 +159,8 @@
     private final List<NotifLifetimeExtender> mLifetimeExtenders = new ArrayList<>();
     private final List<NotifDismissInterceptor> mDismissInterceptors = new ArrayList<>();
 
+    private Set<String> mNotificationsWithoutRankings = Collections.emptySet();
+
     private Queue<NotifEvent> mEventQueue = new ArrayDeque<>();
 
     private boolean mAttached = false;
@@ -266,13 +271,14 @@
             requireNonNull(stats);
             NotificationEntry storedEntry = mNotificationSet.get(entry.getKey());
             if (storedEntry == null) {
-                mLogger.logNonExistentNotifDismissed(entry.getKey());
+                mLogger.logNonExistentNotifDismissed(entry);
                 continue;
             }
             if (entry != storedEntry) {
                 throw mEulogizer.record(
                         new IllegalStateException("Invalid entry: "
-                                + "different stored and dismissed entries for " + entry.getKey()));
+                                + "different stored and dismissed entries for " + logKey(entry)
+                                + " stored=@" + Integer.toHexString(storedEntry.hashCode())));
             }
 
             if (entry.getDismissState() == DISMISSED) {
@@ -281,7 +287,7 @@
 
             updateDismissInterceptors(entry);
             if (isDismissIntercepted(entry)) {
-                mLogger.logNotifDismissedIntercepted(entry.getKey());
+                mLogger.logNotifDismissedIntercepted(entry);
                 continue;
             }
 
@@ -298,7 +304,7 @@
                             stats.notificationVisibility);
                 } catch (RemoteException e) {
                     // system process is dead if we're here.
-                    mLogger.logRemoteExceptionOnNotificationClear(entry.getKey(), e);
+                    mLogger.logRemoteExceptionOnNotificationClear(entry, e);
                 }
             }
         }
@@ -341,7 +347,7 @@
                 // interceptors the chance to filter the notification
                 updateDismissInterceptors(entry);
                 if (isDismissIntercepted(entry)) {
-                    mLogger.logNotifClearAllDismissalIntercepted(entry.getKey());
+                    mLogger.logNotifClearAllDismissalIntercepted(entry);
                 }
                 entries.remove(i);
             }
@@ -362,7 +368,7 @@
             NotificationEntry entry = entries.get(i);
 
             entry.setDismissState(DISMISSED);
-            mLogger.logNotifDismissed(entry.getKey());
+            mLogger.logNotifDismissed(entry);
 
             if (isCanceled(entry)) {
                 canceledEntries.add(entry);
@@ -415,12 +421,12 @@
             int reason) {
         Assert.isMainThread();
 
-        mLogger.logNotifRemoved(sbn.getKey(), reason);
+        mLogger.logNotifRemoved(sbn, reason);
 
         final NotificationEntry entry = mNotificationSet.get(sbn.getKey());
         if (entry == null) {
             // TODO (b/160008901): Throw an exception here
-            mLogger.logNoNotificationToRemoveWithKey(sbn.getKey(), reason);
+            mLogger.logNoNotificationToRemoveWithKey(sbn, reason);
             return;
         }
 
@@ -463,7 +469,7 @@
             mEventQueue.add(new BindEntryEvent(entry, sbn));
             mNotificationSet.put(sbn.getKey(), entry);
 
-            mLogger.logNotifPosted(sbn.getKey());
+            mLogger.logNotifPosted(entry);
             mEventQueue.add(new EntryAddedEvent(entry));
 
         } else {
@@ -482,7 +488,7 @@
             entry.setSbn(sbn);
             mEventQueue.add(new BindEntryEvent(entry, sbn));
 
-            mLogger.logNotifUpdated(sbn.getKey());
+            mLogger.logNotifUpdated(entry);
             mEventQueue.add(new EntryUpdatedEvent(entry, true /* fromSystem */));
         }
     }
@@ -497,12 +503,12 @@
         if (mNotificationSet.get(entry.getKey()) != entry) {
             throw mEulogizer.record(
                     new IllegalStateException("No notification to remove with key "
-                            + entry.getKey()));
+                            + logKey(entry)));
         }
 
         if (!isCanceled(entry)) {
             throw mEulogizer.record(
-                    new IllegalStateException("Cannot remove notification " + entry.getKey()
+                    new IllegalStateException("Cannot remove notification " + logKey(entry)
                             + ": has not been marked for removal"));
         }
 
@@ -513,7 +519,7 @@
         }
 
         if (!isLifetimeExtended(entry)) {
-            mLogger.logNotifReleased(entry.getKey());
+            mLogger.logNotifReleased(entry);
             mNotificationSet.remove(entry.getKey());
             cancelDismissInterception(entry);
             mEventQueue.add(new EntryRemovedEvent(entry, entry.mCancellationReason));
@@ -558,6 +564,7 @@
     }
 
     private void applyRanking(@NonNull RankingMap rankingMap) {
+        ArrayMap<String, NotificationEntry> currentEntriesWithoutRankings = null;
         for (NotificationEntry entry : mNotificationSet.values()) {
             if (!isCanceled(entry)) {
 
@@ -579,10 +586,27 @@
                         }
                     }
                 } else {
-                    mLogger.logRankingMissing(entry.getKey(), rankingMap);
+                    if (currentEntriesWithoutRankings == null) {
+                        currentEntriesWithoutRankings = new ArrayMap<>();
+                    }
+                    currentEntriesWithoutRankings.put(entry.getKey(), entry);
                 }
             }
         }
+        NotifCollectionLoggerKt.maybeLogInconsistentRankings(
+                mLogger,
+                mNotificationsWithoutRankings,
+                currentEntriesWithoutRankings,
+                rankingMap
+        );
+        mNotificationsWithoutRankings = currentEntriesWithoutRankings == null
+                ? Collections.emptySet() : currentEntriesWithoutRankings.keySet();
+        if (currentEntriesWithoutRankings != null && mNotifPipelineFlags.removeUnrankedNotifs()) {
+            for (NotificationEntry entry : currentEntriesWithoutRankings.values()) {
+                entry.mCancellationReason = REASON_UNKNOWN;
+                tryRemoveNotification(entry);
+            }
+        }
         mEventQueue.add(new RankingAppliedEvent());
     }
 
@@ -609,18 +633,24 @@
         }
         checkForReentrantCall();
 
-        if (!entry.mLifetimeExtenders.remove(extender)) {
-            throw mEulogizer.record(new IllegalStateException(
-                    String.format(
-                            "Cannot end lifetime extension for extender \"%s\" (%s)",
-                            extender.getName(),
-                            extender)));
+        NotificationEntry collectionEntry = getEntry(entry.getKey());
+        String logKey = logKey(entry);
+        String collectionEntryIs = collectionEntry == null ? "null"
+                : entry == collectionEntry ? "same" : "different";
+
+        if (entry != collectionEntry) {
+            // TODO: We should probably make this throw, but that's too risky right now
+            mLogger.logEntryBeingExtendedNotInCollection(entry, extender, collectionEntryIs);
         }
 
-        mLogger.logLifetimeExtensionEnded(
-                entry.getKey(),
-                extender,
-                entry.mLifetimeExtenders.size());
+        if (!entry.mLifetimeExtenders.remove(extender)) {
+            throw mEulogizer.record(new IllegalStateException(
+                    String.format("Cannot end lifetime extension for extender \"%s\""
+                                    + " of entry %s (collection entry is %s)",
+                            extender.getName(), logKey, collectionEntryIs)));
+        }
+
+        mLogger.logLifetimeExtensionEnded(entry, extender, entry.mLifetimeExtenders.size());
 
         if (!isLifetimeExtended(entry)) {
             if (tryRemoveNotification(entry)) {
@@ -647,7 +677,7 @@
         mAmDispatchingToOtherCode = true;
         for (NotifLifetimeExtender extender : mLifetimeExtenders) {
             if (extender.maybeExtendLifetime(entry, entry.mCancellationReason)) {
-                mLogger.logLifetimeExtended(entry.getKey(), extender);
+                mLogger.logLifetimeExtended(entry, extender);
                 entry.mLifetimeExtenders.add(extender);
             }
         }
@@ -820,16 +850,19 @@
     @Override
     public void dump(PrintWriter pw, @NonNull String[] args) {
         final List<NotificationEntry> entries = new ArrayList<>(getAllNotifs());
+        entries.sort(Comparator.comparing(NotificationEntry::getKey));
 
-        pw.println("\t" + TAG + " unsorted/unfiltered notifications:");
-        if (entries.size() == 0) {
-            pw.println("\t\t None");
-        }
+        pw.println("\t" + TAG + " unsorted/unfiltered notifications: " + entries.size());
         pw.println(
                 ListDumper.dumpList(
                         entries,
                         true,
                         "\t\t"));
+
+        pw.println("\n\tmNotificationsWithoutRankings: " + mNotificationsWithoutRankings.size());
+        for (String key : mNotificationsWithoutRankings) {
+            pw.println("\t * : " + key);
+        }
     }
 
     private final BatchableNotificationHandler mNotifHandler = new BatchableNotificationHandler() {
@@ -908,17 +941,17 @@
         // Make sure we have the notification to update
         NotificationEntry entry = mNotificationSet.get(sbn.getKey());
         if (entry == null) {
-            mLogger.logNotifInternalUpdateFailed(sbn.getKey(), name, reason);
+            mLogger.logNotifInternalUpdateFailed(sbn, name, reason);
             return;
         }
-        mLogger.logNotifInternalUpdate(sbn.getKey(), name, reason);
+        mLogger.logNotifInternalUpdate(entry, name, reason);
 
         // First do the pieces of postNotification which are not about assuming the notification
         // was sent by the app
         entry.setSbn(sbn);
         mEventQueue.add(new BindEntryEvent(entry, sbn));
 
-        mLogger.logNotifUpdated(sbn.getKey());
+        mLogger.logNotifUpdated(entry);
         mEventQueue.add(new EntryUpdatedEvent(entry, false /* fromSystem */));
 
         // Skip the applyRanking step and go straight to dispatching the events
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
index 4daed77..6a3799b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java
@@ -79,6 +79,11 @@
         entry.abortTask();
     }
 
+    @Override
+    public void releaseViews(@NonNull NotificationEntry entry) {
+        requireBinder().releaseViews(entry);
+    }
+
     private NotificationContentInflater.InflationCallback wrapInflationCallback(
             InflationCallback callback) {
         return new NotificationContentInflater.InflationCallback() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index aedbd1b..0a16fb6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -175,6 +175,10 @@
     public boolean mRemoteEditImeAnimatingAway;
     public boolean mRemoteEditImeVisible;
     private boolean mExpandAnimationRunning;
+    /**
+     * Flag to determine if the entry is blockable by DnD filters
+     */
+    private boolean mBlockable;
 
     /**
      * @param sbn the StatusBarNotification from system server
@@ -253,6 +257,7 @@
         }
 
         mRanking = ranking.withAudiblyAlertedInfo(mRanking);
+        updateIsBlockable();
     }
 
     /*
@@ -781,15 +786,20 @@
      * or is not in an allowList).
      */
     public boolean isBlockable() {
+        return mBlockable;
+    }
+
+    private void updateIsBlockable() {
         if (getChannel() == null) {
-            return false;
+            mBlockable = false;
+            return;
         }
         if (getChannel().isImportanceLockedByCriticalDeviceFunction()
                 && !getChannel().isBlockable()) {
-            return false;
+            mBlockable = false;
+            return;
         }
-
-        return true;
+        mBlockable = true;
     }
 
     private boolean shouldSuppressVisualEffect(int effect) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index df2fe4e..6441d2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -579,11 +579,7 @@
                     if (existingSummary == null) {
                         group.setSummary(entry);
                     } else {
-                        mLogger.logDuplicateSummary(
-                                mIterationCount,
-                                group.getKey(),
-                                existingSummary.getKey(),
-                                entry.getKey());
+                        mLogger.logDuplicateSummary(mIterationCount, group, existingSummary, entry);
 
                         // Use whichever one was posted most recently
                         if (entry.getSbn().getPostTime()
@@ -990,7 +986,7 @@
         // Check for suppressed order changes
         if (!getStabilityManager().isEveryChangeAllowed()) {
             mForceReorderable = true;
-            boolean isSorted = isSorted(mNotifList, mTopLevelComparator);
+            boolean isSorted = isShadeSorted();
             mForceReorderable = false;
             if (!isSorted) {
                 getStabilityManager().onEntryReorderSuppressed();
@@ -999,9 +995,23 @@
         Trace.endSection();
     }
 
+    private boolean isShadeSorted() {
+        if (!isSorted(mNotifList, mTopLevelComparator)) {
+            return false;
+        }
+        for (ListEntry entry : mNotifList) {
+            if (entry instanceof GroupEntry) {
+                if (!isSorted(((GroupEntry) entry).getChildren(), mGroupChildrenComparator)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
     /** Determine whether the items in the list are sorted according to the comparator */
     @VisibleForTesting
-    public static <T> boolean isSorted(List<T> items, Comparator<T> comparator) {
+    public static <T> boolean isSorted(List<T> items, Comparator<? super T> comparator) {
         if (items.size() <= 1) {
             return true;
         }
@@ -1070,7 +1080,7 @@
         if (!Objects.equals(curr, prev)) {
             mLogger.logEntryAttachStateChanged(
                     mIterationCount,
-                    entry.getKey(),
+                    entry,
                     prev.getParent(),
                     curr.getParent());
 
@@ -1209,7 +1219,7 @@
     };
 
 
-    private final Comparator<ListEntry> mGroupChildrenComparator = (o1, o2) -> {
+    private final Comparator<NotificationEntry> mGroupChildrenComparator = (o1, o2) -> {
         int index1 = canReorder(o1) ? -1 : o1.getPreviousAttachState().getStableIndex();
         int index2 = canReorder(o2) ? -1 : o2.getPreviousAttachState().getStableIndex();
         int cmp = Integer.compare(index1, index2);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
index da0169b..a61db41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
@@ -18,7 +18,6 @@
 import android.app.Notification
 import android.app.Notification.GROUP_ALERT_SUMMARY
 import android.util.ArrayMap
-import android.util.ArraySet
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.NotificationRemoteInputManager
 import com.android.systemui.statusbar.notification.collection.GroupEntry
@@ -41,6 +40,7 @@
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.time.SystemClock
+import java.util.function.Consumer
 import javax.inject.Inject
 
 /**
@@ -85,6 +85,7 @@
         pipeline.addOnBeforeFinalizeFilterListener(::onBeforeFinalizeFilter)
         pipeline.addPromoter(mNotifPromoter)
         pipeline.addNotificationLifetimeExtender(mLifetimeExtender)
+        mRemoteInputManager.addActionPressListener(mActionPressListener)
     }
 
     private fun onHeadsUpViewBound(entry: NotificationEntry) {
@@ -448,6 +449,14 @@
                 (entry.sbn.notification.flags and Notification.FLAG_ONLY_ALERT_ONCE) == 0)
     }
 
+    /** When an action is pressed on a notification, end HeadsUp lifetime extension. */
+    private val mActionPressListener = Consumer<NotificationEntry> { entry ->
+        if (mNotifsExtendingLifetime.contains(entry)) {
+            val removeInMillis = mHeadsUpManager.getEarliestRemovalTime(entry.key)
+            mExecutor.executeDelayed({ endNotifLifetimeExtensionIfExtended(entry) }, removeInMillis)
+        }
+    }
+
     private val mLifetimeExtender = object : NotifLifetimeExtender {
         override fun getName() = TAG
 
@@ -503,6 +512,7 @@
     private val mOnHeadsUpChangedListener = object : OnHeadsUpChangedListener {
         override fun onHeadsUpStateChanged(entry: NotificationEntry, isHeadsUp: Boolean) {
             if (!isHeadsUp) {
+                mNotifPromoter.invalidateList()
                 mHeadsUpViewBinder.unbindHeadsUpView(entry)
                 endNotifLifetimeExtensionIfExtended(entry)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
index ff1c70c..ef63be0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
@@ -16,15 +16,15 @@
 
 package com.android.systemui.statusbar.notification.collection.coordinator;
 
-import com.android.keyguard.KeyguardUpdateMonitor;
+import androidx.annotation.NonNull;
+
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
-import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 
 import javax.inject.Inject;
@@ -36,27 +36,21 @@
 @CoordinatorScope
 public class KeyguardCoordinator implements Coordinator {
     private static final String TAG = "KeyguardCoordinator";
-    private final StatusBarStateController mStatusBarStateController;
-    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    private final HighPriorityProvider mHighPriorityProvider;
-    private final SectionHeaderVisibilityProvider mSectionHeaderVisibilityProvider;
     private final KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
+    private final SectionHeaderVisibilityProvider mSectionHeaderVisibilityProvider;
     private final SharedCoordinatorLogger mLogger;
+    private final StatusBarStateController mStatusBarStateController;
 
     @Inject
     public KeyguardCoordinator(
-            StatusBarStateController statusBarStateController,
-            KeyguardUpdateMonitor keyguardUpdateMonitor,
-            HighPriorityProvider highPriorityProvider,
-            SectionHeaderVisibilityProvider sectionHeaderVisibilityProvider,
             KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider,
-            SharedCoordinatorLogger logger) {
-        mStatusBarStateController = statusBarStateController;
-        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
-        mHighPriorityProvider = highPriorityProvider;
-        mSectionHeaderVisibilityProvider = sectionHeaderVisibilityProvider;
+            SectionHeaderVisibilityProvider sectionHeaderVisibilityProvider,
+            SharedCoordinatorLogger logger,
+            StatusBarStateController statusBarStateController) {
         mKeyguardNotificationVisibilityProvider = keyguardNotificationVisibilityProvider;
+        mSectionHeaderVisibilityProvider = sectionHeaderVisibilityProvider;
         mLogger = logger;
+        mStatusBarStateController = statusBarStateController;
     }
 
     @Override
@@ -72,7 +66,7 @@
 
     private final NotifFilter mNotifFilter = new NotifFilter(TAG) {
         @Override
-        public boolean shouldFilterOut(NotificationEntry entry, long now) {
+        public boolean shouldFilterOut(@NonNull NotificationEntry entry, long now) {
             return mKeyguardNotificationVisibilityProvider.shouldHideNotification(entry);
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
index 210fe8f..023c4ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
@@ -360,13 +360,13 @@
     }
 
     private void abortInflation(NotificationEntry entry, String reason) {
-        mLogger.logInflationAborted(entry.getKey(), reason);
+        mLogger.logInflationAborted(entry, reason);
         mNotifInflater.abortInflation(entry);
         mInflatingNotifs.remove(entry);
     }
 
     private void onInflationFinished(NotificationEntry entry, NotifViewController controller) {
-        mLogger.logNotifInflated(entry.getKey());
+        mLogger.logNotifInflated(entry);
         mInflatingNotifs.remove(entry);
         mViewBarn.registerViewForEntry(entry, controller);
         mInflationStates.put(entry, STATE_INFLATED);
@@ -376,6 +376,7 @@
 
     private void freeNotifViews(NotificationEntry entry) {
         mViewBarn.removeViewForEntry(entry);
+        mNotifInflater.releaseViews(entry);
         // TODO: clear the entry's row here, or even better, stop setting the row on the entry!
         mInflationStates.put(entry, STATE_UNINFLATED);
     }
@@ -397,20 +398,20 @@
             return false;
         }
         if (isBeyondGroupInitializationWindow(group, now)) {
-            mLogger.logGroupInflationTookTooLong(group.getKey());
+            mLogger.logGroupInflationTookTooLong(group);
             return false;
         }
         if (mInflatingNotifs.contains(group.getSummary())) {
-            mLogger.logDelayingGroupRelease(group.getKey(), group.getSummary().getKey());
+            mLogger.logDelayingGroupRelease(group, group.getSummary());
             return true;
         }
         for (NotificationEntry child : group.getChildren()) {
             if (mInflatingNotifs.contains(child) && !child.wasAttachedInPreviousPass()) {
-                mLogger.logDelayingGroupRelease(group.getKey(), child.getKey());
+                mLogger.logDelayingGroupRelease(group, child);
                 return true;
             }
         }
-        mLogger.logDoneWaitingForGroupInflation(group.getKey());
+        mLogger.logDoneWaitingForGroupInflation(group);
         return false;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorLogger.kt
index f835250..30f1315 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorLogger.kt
@@ -19,48 +19,51 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel
 import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.statusbar.notification.collection.GroupEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.logKey
 import javax.inject.Inject
 
 class PreparationCoordinatorLogger @Inject constructor(
     @NotificationLog private val buffer: LogBuffer
 ) {
-    fun logNotifInflated(key: String) {
+    fun logNotifInflated(entry: NotificationEntry) {
         buffer.log(TAG, LogLevel.DEBUG, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "NOTIF INFLATED $str1"
         })
     }
 
-    fun logInflationAborted(key: String, reason: String) {
+    fun logInflationAborted(entry: NotificationEntry, reason: String) {
         buffer.log(TAG, LogLevel.DEBUG, {
-            str1 = key
+            str1 = entry.logKey
             str2 = reason
         }, {
             "NOTIF INFLATION ABORTED $str1 reason=$str2"
         })
     }
 
-    fun logDoneWaitingForGroupInflation(groupKey: String) {
+    fun logDoneWaitingForGroupInflation(group: GroupEntry) {
         buffer.log(TAG, LogLevel.DEBUG, {
-            str1 = groupKey
+            str1 = group.logKey
         }, {
             "Finished inflating all members of group $str1, releasing group"
         })
     }
 
-    fun logGroupInflationTookTooLong(groupKey: String) {
+    fun logGroupInflationTookTooLong(group: GroupEntry) {
         buffer.log(TAG, LogLevel.WARNING, {
-            str1 = groupKey
+            str1 = group.logKey
         }, {
             "Group inflation took too long for $str1, releasing children early"
         })
     }
 
-    fun logDelayingGroupRelease(groupKey: String, childKey: String) {
+    fun logDelayingGroupRelease(group: GroupEntry, child: NotificationEntry) {
         buffer.log(TAG, LogLevel.DEBUG, {
-            str1 = groupKey
-            str2 = childKey
+            str1 = group.logKey
+            str2 = child.logKey
         }, {
             "Delaying release of group $str1 because child $str2 is still inflating"
         })
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
index 57fd197..5ac4813 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
@@ -20,7 +20,6 @@
 import android.annotation.Nullable;
 
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.notification.SectionClassifier;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -28,6 +27,7 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
 import com.android.systemui.statusbar.notification.collection.render.NodeController;
 import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
 import com.android.systemui.statusbar.notification.dagger.AlertingHeader;
@@ -51,7 +51,7 @@
     public static final boolean SHOW_ALL_SECTIONS = false;
     private final StatusBarStateController mStatusBarStateController;
     private final HighPriorityProvider mHighPriorityProvider;
-    private final SectionClassifier mSectionClassifier;
+    private final SectionStyleProvider mSectionStyleProvider;
     private final NodeController mSilentNodeController;
     private final SectionHeaderController mSilentHeaderController;
     private final NodeController mAlertingHeaderController;
@@ -62,13 +62,13 @@
     public RankingCoordinator(
             StatusBarStateController statusBarStateController,
             HighPriorityProvider highPriorityProvider,
-            SectionClassifier sectionClassifier,
+            SectionStyleProvider sectionStyleProvider,
             @AlertingHeader NodeController alertingHeaderController,
             @SilentHeader SectionHeaderController silentHeaderController,
             @SilentHeader NodeController silentNodeController) {
         mStatusBarStateController = statusBarStateController;
         mHighPriorityProvider = highPriorityProvider;
-        mSectionClassifier = sectionClassifier;
+        mSectionStyleProvider = sectionStyleProvider;
         mAlertingHeaderController = alertingHeaderController;
         mSilentNodeController = silentNodeController;
         mSilentHeaderController = silentHeaderController;
@@ -77,7 +77,7 @@
     @Override
     public void attach(NotifPipeline pipeline) {
         mStatusBarStateController.addCallback(mStatusBarStateCallback);
-        mSectionClassifier.setMinimizedSections(Collections.singleton(mMinimizedNotifSectioner));
+        mSectionStyleProvider.setMinimizedSections(Collections.singleton(mMinimizedNotifSectioner));
 
         pipeline.addPreGroupFilter(mSuspendedFilter);
         pipeline.addPreGroupFilter(mDndVisualEffectsFilter);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
index 4e9d3ac..1494574 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
@@ -19,11 +19,11 @@
 import android.content.Context
 import com.android.systemui.R
 import com.android.systemui.statusbar.notification.AssistantFeedbackController
-import com.android.systemui.statusbar.notification.SectionClassifier
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
 import com.android.systemui.statusbar.notification.collection.render.NotifRowController
 import javax.inject.Inject
 
@@ -35,7 +35,7 @@
 class RowAppearanceCoordinator @Inject internal constructor(
     context: Context,
     private var mAssistantFeedbackController: AssistantFeedbackController,
-    private var mSectionClassifier: SectionClassifier
+    private var mSectionStyleProvider: SectionStyleProvider
 ) : Coordinator {
 
     private var entryToExpand: NotificationEntry? = null
@@ -55,7 +55,7 @@
 
     private fun onBeforeRenderList(list: List<ListEntry>) {
         entryToExpand = list.firstOrNull()?.representativeEntry?.takeIf { entry ->
-            !mSectionClassifier.isMinimizedSection(entry.section!!)
+            !mSectionStyleProvider.isMinimizedSection(entry.section!!)
         }
     }
 
@@ -68,4 +68,4 @@
         // Show the "alerted" bell icon
         controller.setLastAudiblyAlertedMs(entry.lastAudiblyAlertedMs)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
index 31a13e6..bae16fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
@@ -16,15 +16,18 @@
 
 package com.android.systemui.statusbar.notification.collection.coordinator
 
+import android.util.Log
 import com.android.internal.widget.MessagingGroup
 import com.android.internal.widget.MessagingMessage
 import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
 import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager
 import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.Compile
 import javax.inject.Inject
 
 /**
@@ -38,24 +41,52 @@
     private val mLockscreenUserManager: NotificationLockscreenUserManager,
     private val mGutsManager: NotificationGutsManager,
     private val mKeyguardUpdateMonitor: KeyguardUpdateMonitor
-) : Coordinator, UserChangedListener, ConfigurationController.ConfigurationListener {
+) : Coordinator, ConfigurationController.ConfigurationListener {
 
+    private var mIsSwitchingUser = false
     private var mReinflateNotificationsOnUserSwitched = false
     private var mDispatchUiModeChangeOnUserSwitched = false
     private var mPipeline: NotifPipeline? = null
 
+    private val mKeyguardUpdateCallback = object : KeyguardUpdateMonitorCallback() {
+        override fun onUserSwitching(userId: Int) {
+            log { "ViewConfigCoordinator.onUserSwitching(userId=$userId)" }
+            mIsSwitchingUser = true
+        }
+
+        override fun onUserSwitchComplete(userId: Int) {
+            log { "ViewConfigCoordinator.onUserSwitchComplete(userId=$userId)" }
+            mIsSwitchingUser = false
+            applyChangesOnUserSwitched()
+        }
+    }
+
+    private val mUserChangedListener = object : UserChangedListener {
+        override fun onUserChanged(userId: Int) {
+            log { "ViewConfigCoordinator.onUserChanged(userId=$userId)" }
+            applyChangesOnUserSwitched()
+        }
+    }
+
     override fun attach(pipeline: NotifPipeline) {
         mPipeline = pipeline
         if (pipeline.isNewPipelineEnabled) {
-            mLockscreenUserManager.addUserChangedListener(this)
+            mLockscreenUserManager.addUserChangedListener(mUserChangedListener)
             mConfigurationController.addCallback(this)
+            mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback)
         }
     }
 
     override fun onDensityOrFontScaleChanged() {
+        log {
+            val keyguardIsSwitchingUser = mKeyguardUpdateMonitor.isSwitchingUser
+            "ViewConfigCoordinator.onDensityOrFontScaleChanged()" +
+                    " isSwitchingUser=$mIsSwitchingUser" +
+                    " keyguardUpdateMonitor.isSwitchingUser=$keyguardIsSwitchingUser"
+        }
         MessagingMessage.dropCache()
         MessagingGroup.dropCache()
-        if (!mKeyguardUpdateMonitor.isSwitchingUser) {
+        if (!mIsSwitchingUser) {
             updateNotificationsOnDensityOrFontScaleChanged()
         } else {
             mReinflateNotificationsOnUserSwitched = true
@@ -63,7 +94,13 @@
     }
 
     override fun onUiModeChanged() {
-        if (!mKeyguardUpdateMonitor.isSwitchingUser) {
+        log {
+            val keyguardIsSwitchingUser = mKeyguardUpdateMonitor.isSwitchingUser
+            "ViewConfigCoordinator.onUiModeChanged()" +
+                    " isSwitchingUser=$mIsSwitchingUser" +
+                    " keyguardUpdateMonitor.isSwitchingUser=$keyguardIsSwitchingUser"
+        }
+        if (!mIsSwitchingUser) {
             updateNotificationsOnUiModeChanged()
         } else {
             mDispatchUiModeChangeOnUserSwitched = true
@@ -74,7 +111,7 @@
         onDensityOrFontScaleChanged()
     }
 
-    override fun onUserChanged(userId: Int) {
+    private fun applyChangesOnUserSwitched() {
         if (mReinflateNotificationsOnUserSwitched) {
             updateNotificationsOnDensityOrFontScaleChanged()
             mReinflateNotificationsOnUserSwitched = false
@@ -86,9 +123,9 @@
     }
 
     private fun updateNotificationsOnUiModeChanged() {
+        log { "ViewConfigCoordinator.updateNotificationsOnUiModeChanged()" }
         mPipeline?.allNotifs?.forEach { entry ->
-            val row = entry.row
-            row?.onUiModeChanged()
+            entry.row?.onUiModeChanged()
         }
     }
 
@@ -101,4 +138,13 @@
             }
         }
     }
+
+    private inline fun log(message: () -> String) {
+        if (DEBUG) Log.d(TAG, message())
+    }
+
+    companion object {
+        private const val TAG = "ViewConfigCoordinator"
+        private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG)
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
index d7bd95c..b9d23b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
@@ -16,8 +16,9 @@
 
 package com.android.systemui.statusbar.notification.collection.coordinator;
 
-import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
-import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
+
+import android.util.Log;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
@@ -35,6 +36,7 @@
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
 import com.android.systemui.statusbar.phone.NotifPanelEvents;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.util.Compile;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 
 import java.io.PrintWriter;
@@ -54,6 +56,8 @@
 @SysUISingleton
 public class VisualStabilityCoordinator implements Coordinator, Dumpable,
         NotifPanelEvents.Listener {
+    public static final String TAG = "VisualStability";
+    public static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
     private final DelayableExecutor mDelayableExecutor;
     private final HeadsUpManager mHeadsUpManager;
     private final NotifPanelEvents mNotifPanelEvents;
@@ -61,7 +65,8 @@
     private final VisualStabilityProvider mVisualStabilityProvider;
     private final WakefulnessLifecycle mWakefulnessLifecycle;
 
-    private boolean mScreenOn;
+    private boolean mSleepy = true;
+    private boolean mFullyDozed;
     private boolean mPanelExpanded;
     private boolean mPulsing;
     private boolean mNotifPanelCollapsing;
@@ -104,8 +109,8 @@
     @Override
     public void attach(NotifPipeline pipeline) {
         mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
-        mScreenOn = mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_AWAKE
-                || mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_WAKING;
+        mSleepy = mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP;
+        mFullyDozed = mStatusBarStateController.getDozeAmount() == 1f;
 
         mStatusBarStateController.addCallback(mStatusBarStateControllerListener);
         mPulsing = mStatusBarStateController.isPulsing();
@@ -113,6 +118,7 @@
 
         pipeline.setVisualStabilityManager(mNotifStabilityManager);
     }
+
     // TODO(b/203826051): Ensure stability manager can allow reordering off-screen
     //  HUNs to the top of the shade
     private final NotifStabilityManager mNotifStabilityManager =
@@ -174,9 +180,18 @@
                 }
             };
 
-    private void updateAllowedStates() {
+    private void updateAllowedStates(String field, boolean value) {
+        boolean wasPipelineRunAllowed = mPipelineRunAllowed;
+        boolean wasReorderingAllowed = mReorderingAllowed;
         mPipelineRunAllowed = !isPanelCollapsingOrLaunchingActivity();
         mReorderingAllowed = isReorderingAllowed();
+        if (DEBUG && (wasPipelineRunAllowed != mPipelineRunAllowed
+                || wasReorderingAllowed != mReorderingAllowed)) {
+            Log.d(TAG, "Stability allowances changed:"
+                    + "  pipelineRunAllowed " + wasPipelineRunAllowed + "->" + mPipelineRunAllowed
+                    + "  reorderingAllowed " + wasReorderingAllowed + "->" + mReorderingAllowed
+                    + "  when setting " + field + "=" + value);
+        }
         if ((mPipelineRunAllowed && mIsSuppressingPipelineRun)
                 || (mReorderingAllowed && (mIsSuppressingGroupChange
                         || isSuppressingSectionChange()
@@ -195,7 +210,7 @@
     }
 
     private boolean isReorderingAllowed() {
-        return (!mScreenOn || !mPanelExpanded) && !mPulsing;
+        return ((mFullyDozed && mSleepy) || !mPanelExpanded) && !mPulsing;
     }
 
     /**
@@ -235,27 +250,37 @@
                 @Override
                 public void onPulsingChanged(boolean pulsing) {
                     mPulsing = pulsing;
-                    updateAllowedStates();
+                    updateAllowedStates("pulsing", pulsing);
                 }
 
                 @Override
                 public void onExpandedChanged(boolean expanded) {
                     mPanelExpanded = expanded;
-                    updateAllowedStates();
+                    updateAllowedStates("panelExpanded", expanded);
+                }
+
+                @Override
+                public void onDozeAmountChanged(float linear, float eased) {
+                    final boolean fullyDozed = linear == 1f;
+                    mFullyDozed = fullyDozed;
+                    updateAllowedStates("fullyDozed", fullyDozed);
                 }
             };
 
     final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
         @Override
         public void onFinishedGoingToSleep() {
-            mScreenOn = false;
-            updateAllowedStates();
+            // NOTE: this method is called much earlier than what we consider "finished" going to
+            // sleep (the animation isn't done), so we also need to check the doze amount is not 1
+            // and use the combo to determine that the locked shade is not visible.
+            mSleepy = true;
+            updateAllowedStates("sleepy", true);
         }
 
         @Override
         public void onStartedWakingUp() {
-            mScreenOn = true;
-            updateAllowedStates();
+            mSleepy = false;
+            updateAllowedStates("sleepy", false);
         }
     };
 
@@ -265,7 +290,8 @@
         pw.println("  notifPanelCollapsing: " + mNotifPanelCollapsing);
         pw.println("  launchingNotifActivity: " + mNotifPanelLaunchingActivity);
         pw.println("reorderingAllowed: " + mReorderingAllowed);
-        pw.println("  screenOn: " + mScreenOn);
+        pw.println("  sleepy: " + mSleepy);
+        pw.println("  fullyDozed: " + mFullyDozed);
         pw.println("  panelExpanded: " + mPanelExpanded);
         pw.println("  pulsing: " + mPulsing);
         pw.println("isSuppressingPipelineRun: " + mIsSuppressingPipelineRun);
@@ -285,12 +311,12 @@
     @Override
     public void onPanelCollapsingChanged(boolean isCollapsing) {
         mNotifPanelCollapsing = isCollapsing;
-        updateAllowedStates();
+        updateAllowedStates("notifPanelCollapsing", isCollapsing);
     }
 
     @Override
     public void onLaunchingActivityChanged(boolean isLaunchingActivity) {
         mNotifPanelLaunchingActivity = isLaunchingActivity;
-        updateAllowedStates();
+        updateAllowedStates("notifPanelLaunchingActivity", isLaunchingActivity);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
index d98e7f7..567ec85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
@@ -47,6 +47,11 @@
     fun abortInflation(entry: NotificationEntry)
 
     /**
+     * Called to let the system remove the content views from the notification row.
+     */
+    fun releaseViews(entry: NotificationEntry)
+
+    /**
      * Callback once all the views are inflated and bound for a given NotificationEntry.
      */
     interface InflationCallback {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt
index 3475fcf..ee0b008 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt
@@ -31,6 +31,7 @@
     val smartActions: List<Notification.Action>,
     val smartReplies: List<CharSequence>,
     val isConversation: Boolean,
+    val isSnoozeEnabled: Boolean,
     val isMinimized: Boolean,
     val needsRedaction: Boolean,
 ) {
@@ -42,6 +43,7 @@
         ): Boolean = when {
             oldAdjustment === newAdjustment -> false
             oldAdjustment.isConversation != newAdjustment.isConversation -> true
+            oldAdjustment.isSnoozeEnabled != newAdjustment.isSnoozeEnabled -> true
             oldAdjustment.isMinimized != newAdjustment.isMinimized -> true
             oldAdjustment.needsRedaction != newAdjustment.needsRedaction -> true
             areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions) -> true
@@ -57,9 +59,9 @@
             first.size != second.size -> true
             else -> first.asSequence().zip(second.asSequence()).any {
                 (!TextUtils.equals(it.first.title, it.second.title)) ||
-                        (areDifferent(it.first.getIcon(), it.second.getIcon())) ||
-                        (it.first.actionIntent != it.second.actionIntent) ||
-                        (areDifferent(it.first.remoteInputs, it.second.remoteInputs))
+                    (areDifferent(it.first.getIcon(), it.second.getIcon())) ||
+                    (it.first.actionIntent != it.second.actionIntent) ||
+                    (areDifferent(it.first.remoteInputs, it.second.remoteInputs))
             }
         }
 
@@ -78,7 +80,7 @@
             first.size != second.size -> true
             else -> first.asSequence().zip(second.asSequence()).any {
                 (!TextUtils.equals(it.first.label, it.second.label)) ||
-                        (areDifferent(it.first.choices, it.second.choices))
+                    (areDifferent(it.first.choices, it.second.choices))
             }
         }
 
@@ -94,4 +96,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
index f7b6376..745d6fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
@@ -16,12 +16,18 @@
 
 package com.android.systemui.statusbar.notification.collection.inflation
 
+import android.database.ContentObserver
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
-import com.android.systemui.statusbar.notification.SectionClassifier
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
 import com.android.systemui.util.ListenerSet
+import com.android.systemui.util.settings.SecureSettings
 import javax.inject.Inject
 
 /**
@@ -30,14 +36,23 @@
  */
 @SysUISingleton
 class NotifUiAdjustmentProvider @Inject constructor(
+    @Main private val handler: Handler,
+    private val secureSettings: SecureSettings,
     private val lockscreenUserManager: NotificationLockscreenUserManager,
-    private val sectionClassifier: SectionClassifier,
+    private val sectionStyleProvider: SectionStyleProvider
 ) {
     private val dirtyListeners = ListenerSet<Runnable>()
+    private var isSnoozeEnabled = false
 
     fun addDirtyListener(listener: Runnable) {
         if (dirtyListeners.isEmpty()) {
             lockscreenUserManager.addNotificationStateChangedListener(notifStateChangedListener)
+            updateSnoozeEnabled()
+            secureSettings.registerContentObserverForUser(
+                SHOW_NOTIFICATION_SNOOZE,
+                settingsObserver,
+                UserHandle.USER_ALL
+            )
         }
         dirtyListeners.addIfAbsent(listener)
     }
@@ -46,6 +61,7 @@
         dirtyListeners.remove(listener)
         if (dirtyListeners.isEmpty()) {
             lockscreenUserManager.removeNotificationStateChangedListener(notifStateChangedListener)
+            secureSettings.unregisterContentObserver(settingsObserver)
         }
     }
 
@@ -54,10 +70,21 @@
             dirtyListeners.forEach(Runnable::run)
         }
 
+    private val settingsObserver = object : ContentObserver(handler) {
+        override fun onChange(selfChange: Boolean) {
+            updateSnoozeEnabled()
+            dirtyListeners.forEach(Runnable::run)
+        }
+    }
+
+    private fun updateSnoozeEnabled() {
+        isSnoozeEnabled = secureSettings.getInt(SHOW_NOTIFICATION_SNOOZE, 0) == 1
+    }
+
     private fun isEntryMinimized(entry: NotificationEntry): Boolean {
         val section = entry.section ?: error("Entry must have a section to determine if minimized")
         val parent = entry.parent ?: error("Entry must have a parent to determine if minimized")
-        val isMinimizedSection = sectionClassifier.isMinimizedSection(section)
+        val isMinimizedSection = sectionStyleProvider.isMinimizedSection(section)
         val isTopLevelEntry = parent == GroupEntry.ROOT_ENTRY
         val isGroupSummary = parent.summary == entry
         return isMinimizedSection && (isTopLevelEntry || isGroupSummary)
@@ -73,7 +100,8 @@
         smartActions = entry.ranking.smartActions,
         smartReplies = entry.ranking.smartReplies,
         isConversation = entry.ranking.isConversation,
+        isSnoozeEnabled = isSnoozeEnabled,
         isMinimized = isEntryMinimized(entry),
         needsRedaction = lockscreenUserManager.needsRedaction(entry),
     )
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java
index 3a4701c..46b467e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinder.java
@@ -50,4 +50,9 @@
             NotificationUiAdjustment oldAdjustment,
             NotificationUiAdjustment newAdjustment,
             NotificationRowContentBinder.InflationCallback callback);
+
+    /**
+     * Called when a notification is no longer likely to be displayed and can have its views freed.
+     */
+    void releaseViews(NotificationEntry entry);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index b84a797..528f720 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.notification.collection.inflation;
 
+import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
+import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED;
 import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;
 
 import static java.util.Objects.requireNonNull;
@@ -161,6 +163,18 @@
         }
     }
 
+    @Override
+    public void releaseViews(NotificationEntry entry) {
+        if (!entry.rowExists()) {
+            return;
+        }
+        final RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
+        params.markContentViewsFreeable(FLAG_CONTENT_VIEW_CONTRACTED);
+        params.markContentViewsFreeable(FLAG_CONTENT_VIEW_EXPANDED);
+        params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC);
+        mRowContentBindStage.requestRebind(entry, null);
+    }
+
     /**
      * Bind row to various controllers and managers. This is only called when the row is first
      * created.
@@ -249,6 +263,8 @@
         }
 
         RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
+        params.requireContentViews(FLAG_CONTENT_VIEW_CONTRACTED);
+        params.requireContentViews(FLAG_CONTENT_VIEW_EXPANDED);
         params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
         params.setUseLowPriority(isLowPriority);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt
index 263737e..ea66f3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt
@@ -25,12 +25,9 @@
     val sectioner: NotifSectioner,
     val index: Int
 ) {
-    val label: String
-        get() = "Section($index, $bucket, \"${sectioner.name}\")"
-
+    @PriorityBucket
+    val bucket: Int = sectioner.bucket
+    val label: String = "$index:$bucket:${sectioner.name}"
     val headerController: NodeController? = sectioner.headerNodeController
-
     val comparator: NotifComparator? = sectioner.comparator
-
-    @PriorityBucket val bucket: Int = sectioner.bucket
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
index f8bf85f..8d1759b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
@@ -23,8 +23,10 @@
 import com.android.systemui.log.dagger.NotificationLog
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
+import com.android.systemui.statusbar.notification.logKey
 import javax.inject.Inject
 
 class ShadeListBuilderLogger @Inject constructor(
@@ -110,12 +112,17 @@
         })
     }
 
-    fun logDuplicateSummary(buildId: Int, groupKey: String, existingKey: String, newKey: String) {
+    fun logDuplicateSummary(
+        buildId: Int,
+        group: GroupEntry,
+        existingSummary: NotificationEntry,
+        newSummary: NotificationEntry
+    ) {
         buffer.log(TAG, WARNING, {
             long1 = buildId.toLong()
-            str1 = groupKey
-            str2 = existingKey
-            str3 = newKey
+            str1 = group.logKey
+            str2 = existingSummary.logKey
+            str3 = newSummary.logKey
         }, {
             """(Build $long1) Duplicate summary for group "$str1": "$str2" vs. "$str3""""
         })
@@ -124,7 +131,7 @@
     fun logDuplicateTopLevelKey(buildId: Int, topLevelKey: String) {
         buffer.log(TAG, WARNING, {
             long1 = buildId.toLong()
-            str1 = topLevelKey
+            str1 = logKey(topLevelKey)
         }, {
             "(Build $long1) Duplicate top-level key: $str1"
         })
@@ -132,15 +139,15 @@
 
     fun logEntryAttachStateChanged(
         buildId: Int,
-        key: String,
+        entry: ListEntry,
         prevParent: GroupEntry?,
         newParent: GroupEntry?
     ) {
         buffer.log(TAG, INFO, {
             long1 = buildId.toLong()
-            str1 = key
-            str2 = prevParent?.key
-            str3 = newParent?.key
+            str1 = entry.logKey
+            str2 = prevParent?.logKey
+            str3 = newParent?.logKey
         }, {
 
             val action = if (str2 == null && str3 != null) {
@@ -160,8 +167,8 @@
     fun logParentChanged(buildId: Int, prevParent: GroupEntry?, newParent: GroupEntry?) {
         buffer.log(TAG, INFO, {
             long1 = buildId.toLong()
-            str1 = prevParent?.key
-            str2 = newParent?.key
+            str1 = prevParent?.logKey
+            str2 = newParent?.logKey
         }, {
             if (str1 == null && str2 != null) {
                 "(Build $long1)     Parent is {$str2}"
@@ -180,8 +187,8 @@
     ) {
         buffer.log(TAG, INFO, {
             long1 = buildId.toLong()
-            str1 = suppressedParent?.key
-            str2 = keepingParent?.key
+            str1 = suppressedParent?.logKey
+            str2 = keepingParent?.logKey
         }, {
             "(Build $long1)     Change of parent to '$str1' suppressed; keeping parent '$str2'"
         })
@@ -193,7 +200,7 @@
     ) {
         buffer.log(TAG, INFO, {
             long1 = buildId.toLong()
-            str1 = keepingParent?.key
+            str1 = keepingParent?.logKey
         }, {
             "(Build $long1)     Group pruning suppressed; keeping parent '$str1'"
         })
@@ -281,7 +288,7 @@
             val entry = entries[i]
             buffer.log(TAG, DEBUG, {
                 int1 = i
-                str1 = entry.key
+                str1 = entry.logKey
             }, {
                 "[$int1] $str1"
             })
@@ -289,7 +296,7 @@
             if (entry is GroupEntry) {
                 entry.summary?.let {
                     buffer.log(TAG, DEBUG, {
-                        str1 = it.key
+                        str1 = it.logKey
                     }, {
                         "  [*] $str1 (summary)"
                     })
@@ -298,7 +305,7 @@
                     val child = entry.children[j]
                     buffer.log(TAG, DEBUG, {
                         int1 = j
-                        str1 = child.key
+                        str1 = child.logKey
                     }, {
                         "  [$int1] $str1"
                     })
@@ -308,7 +315,7 @@
     }
 
     fun logPipelineRunSuppressed() =
-            buffer.log(TAG, INFO, {}) { "Suppressing pipeline run during animation." }
+        buffer.log(TAG, INFO, {}) { "Suppressing pipeline run during animation." }
 }
 
 private const val TAG = "ShadeListBuilder"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt
index 7e79367..ebcac6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt
@@ -19,6 +19,7 @@
 import android.os.RemoteException
 import android.service.notification.NotificationListenerService
 import android.service.notification.NotificationListenerService.RankingMap
+import android.service.notification.StatusBarNotification
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel.DEBUG
 import com.android.systemui.log.LogLevel.ERROR
@@ -65,9 +66,9 @@
 class NotifCollectionLogger @Inject constructor(
     @NotificationLog private val buffer: LogBuffer
 ) {
-    fun logNotifPosted(key: String) {
+    fun logNotifPosted(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "POSTED $str1"
         })
@@ -75,49 +76,49 @@
 
     fun logNotifGroupPosted(groupKey: String, batchSize: Int) {
         buffer.log(TAG, INFO, {
-            str1 = groupKey
+            str1 = logKey(groupKey)
             int1 = batchSize
         }, {
             "POSTED GROUP $str1 ($int1 events)"
         })
     }
 
-    fun logNotifUpdated(key: String) {
+    fun logNotifUpdated(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "UPDATED $str1"
         })
     }
 
-    fun logNotifRemoved(key: String, @CancellationReason reason: Int) {
+    fun logNotifRemoved(sbn: StatusBarNotification, @CancellationReason reason: Int) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = sbn.logKey
             int1 = reason
         }, {
             "REMOVED $str1 reason=${cancellationReasonDebugString(int1)}"
         })
     }
 
-    fun logNotifReleased(key: String) {
+    fun logNotifReleased(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "RELEASED $str1"
         })
     }
 
-    fun logNotifDismissed(key: String) {
+    fun logNotifDismissed(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "DISMISSED $str1"
         })
     }
 
-    fun logNonExistentNotifDismissed(key: String) {
+    fun logNonExistentNotifDismissed(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "DISMISSED Non Existent $str1"
         })
@@ -125,7 +126,7 @@
 
     fun logChildDismissed(entry: NotificationEntry) {
         buffer.log(TAG, DEBUG, {
-            str1 = entry.key
+            str1 = entry.logKey
         }, {
             "CHILD DISMISSED (inferred): $str1"
         })
@@ -141,31 +142,31 @@
 
     fun logDismissOnAlreadyCanceledEntry(entry: NotificationEntry) {
         buffer.log(TAG, DEBUG, {
-            str1 = entry.key
+            str1 = entry.logKey
         }, {
             "Dismiss on $str1, which was already canceled. Trying to remove..."
         })
     }
 
-    fun logNotifDismissedIntercepted(key: String) {
+    fun logNotifDismissedIntercepted(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "DISMISS INTERCEPTED $str1"
         })
     }
 
-    fun logNotifClearAllDismissalIntercepted(key: String) {
+    fun logNotifClearAllDismissalIntercepted(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "CLEAR ALL DISMISSAL INTERCEPTED $str1"
         })
     }
 
-    fun logNotifInternalUpdate(key: String, name: String, reason: String) {
+    fun logNotifInternalUpdate(entry: NotificationEntry, name: String, reason: String) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
             str2 = name
             str3 = reason
         }, {
@@ -173,9 +174,9 @@
         })
     }
 
-    fun logNotifInternalUpdateFailed(key: String, name: String, reason: String) {
+    fun logNotifInternalUpdateFailed(sbn: StatusBarNotification, name: String, reason: String) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = sbn.logKey
             str2 = name
             str3 = reason
         }, {
@@ -183,26 +184,49 @@
         })
     }
 
-    fun logNoNotificationToRemoveWithKey(key: String, @CancellationReason reason: Int) {
+    fun logNoNotificationToRemoveWithKey(
+        sbn: StatusBarNotification,
+        @CancellationReason reason: Int
+    ) {
         buffer.log(TAG, ERROR, {
-            str1 = key
+            str1 = sbn.logKey
             int1 = reason
         }, {
             "No notification to remove with key $str1 reason=${cancellationReasonDebugString(int1)}"
         })
     }
 
-    fun logRankingMissing(key: String, rankingMap: RankingMap) {
-        buffer.log(TAG, WARNING, { str1 = key }, { "Ranking update is missing ranking for $str1" })
-        buffer.log(TAG, DEBUG, {}, { "Ranking map contents:" })
-        for (entry in rankingMap.orderedKeys) {
-            buffer.log(TAG, DEBUG, { str1 = entry }, { "  $str1" })
-        }
+    fun logMissingRankings(
+        newlyInconsistentEntries: List<NotificationEntry>,
+        totalInconsistent: Int,
+        rankingMap: RankingMap
+    ) {
+        buffer.log(TAG, WARNING, {
+            int1 = totalInconsistent
+            int2 = newlyInconsistentEntries.size
+            str1 = newlyInconsistentEntries.joinToString { it.logKey ?: "null" }
+        }, {
+            "Ranking update is missing ranking for $int1 entries ($int2 new): $str1"
+        })
+        buffer.log(TAG, DEBUG, {
+            str1 = rankingMap.orderedKeys.map { logKey(it) ?: "null" }.toString()
+        }, {
+            "Ranking map contents: $str1"
+        })
     }
 
-    fun logRemoteExceptionOnNotificationClear(key: String, e: RemoteException) {
+    fun logRecoveredRankings(newlyConsistentKeys: List<String>) {
+        buffer.log(TAG, INFO, {
+            int1 = newlyConsistentKeys.size
+            str1 = newlyConsistentKeys.joinToString { logKey(it) ?: "null" }
+        }, {
+            "Ranking update now contains rankings for $int1 previously inconsistent entries: $str1"
+        })
+    }
+
+    fun logRemoteExceptionOnNotificationClear(entry: NotificationEntry, e: RemoteException) {
         buffer.log(TAG, WTF, {
-            str1 = key
+            str1 = entry.logKey
             str2 = e.toString()
         }, {
             "RemoteException while attempting to clear $str1:\n$str2"
@@ -217,9 +241,9 @@
         })
     }
 
-    fun logLifetimeExtended(key: String, extender: NotifLifetimeExtender) {
+    fun logLifetimeExtended(entry: NotificationEntry, extender: NotifLifetimeExtender) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
             str2 = extender.name
         }, {
             "LIFETIME EXTENDED: $str1 by $str2"
@@ -227,12 +251,12 @@
     }
 
     fun logLifetimeExtensionEnded(
-        key: String,
+        entry: NotificationEntry,
         extender: NotifLifetimeExtender,
         totalExtenders: Int
     ) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
             str2 = extender.name
             int1 = totalExtenders
         }, {
@@ -248,6 +272,20 @@
         })
     }
 
+    fun logEntryBeingExtendedNotInCollection(
+        entry: NotificationEntry,
+        extender: NotifLifetimeExtender,
+        collectionEntryIs: String
+    ) {
+        buffer.log(TAG, WARNING, {
+            str1 = entry.logKey
+            str2 = extender.name
+            str3 = collectionEntryIs
+        }, {
+            "While ending lifetime extension by $str2 of $str1, entry in collection is $str3"
+        })
+    }
+
     fun logFutureDismissalReused(dismissal: FutureDismissal) {
         buffer.log(TAG, INFO, {
             str1 = dismissal.label
@@ -324,4 +362,29 @@
     }
 }
 
+fun maybeLogInconsistentRankings(
+    logger: NotifCollectionLogger,
+    oldKeysWithoutRankings: Set<String>,
+    newEntriesWithoutRankings: Map<String, NotificationEntry>?,
+    rankingMap: RankingMap
+) {
+    if (oldKeysWithoutRankings.isEmpty() && newEntriesWithoutRankings == null) return
+    val newlyConsistent: List<String> = oldKeysWithoutRankings
+        .mapNotNull { key ->
+            key.takeIf { key !in (newEntriesWithoutRankings ?: emptyMap()) }
+                .takeIf { key in rankingMap.orderedKeys }
+        }.sorted()
+    if (newlyConsistent.isNotEmpty()) {
+        logger.logRecoveredRankings(newlyConsistent)
+    }
+    val newlyInconsistent: List<NotificationEntry> = newEntriesWithoutRankings
+        ?.mapNotNull { (key, entry) ->
+            entry.takeIf { key !in oldKeysWithoutRankings }
+        }?.sortedBy { it.key } ?: emptyList()
+    if (newlyInconsistent.isNotEmpty()) {
+        val totalInconsistent: Int = newEntriesWithoutRankings?.size ?: 0
+        logger.logMissingRankings(newlyInconsistent, totalInconsistent, rankingMap)
+    }
+}
+
 private const val TAG = "NotifCollection"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
index 68bdd18..82c7aae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification
+package com.android.systemui.statusbar.notification.collection.provider
 
 import android.content.Context
-import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
 import javax.inject.Inject
 
 /**
@@ -34,7 +34,7 @@
 class SectionHeaderVisibilityProvider @Inject constructor(
     context: Context
 ) {
-    var neverShowSectionHeaders = context.resources.getBoolean(R.bool.config_notification_never_show_section_headers)
-        private set
+    val neverShowSectionHeaders =
+        context.resources.getBoolean(R.bool.config_notification_never_show_section_headers)
     var sectionHeadersVisible = true
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionClassifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionClassifier.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
index 1f2d0fe..7b94830 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionClassifier.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification
+package com.android.systemui.statusbar.notification.collection.provider
 
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
@@ -26,7 +26,7 @@
  * NOTE: This class exists to avoid putting metadata like "isMinimized" on the NotifSection
  */
 @SysUISingleton
-class SectionClassifier @Inject constructor() {
+class SectionStyleProvider @Inject constructor() {
     private lateinit var lowPrioritySections: Set<NotifSectioner>
 
     /**
@@ -43,4 +43,4 @@
     fun isMinimizedSection(section: NotifSection): Boolean {
         return lowPrioritySections.contains(section.sectioner)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
index 8be710c..d234e54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
@@ -16,12 +16,12 @@
 
 package com.android.systemui.statusbar.notification.collection.render
 
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
 import com.android.systemui.util.Compile
 import com.android.systemui.util.traceSection
 
@@ -107,4 +107,4 @@
                 .apply { entry.children.forEach { children.add(buildNotifNode(this, it)) } }
         else -> throw RuntimeException("Unexpected entry: $entry")
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt
index 3501b44..38e3d49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt
@@ -19,20 +19,24 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel
 import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.statusbar.notification.NotifPipelineFlags
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
 import com.android.systemui.util.Compile
 import javax.inject.Inject
 
 class NodeSpecBuilderLogger @Inject constructor(
+    notifPipelineFlags: NotifPipelineFlags,
     @NotificationLog private val buffer: LogBuffer
 ) {
+    private val devLoggingEnabled by lazy { notifPipelineFlags.isDevLoggingEnabled() }
+
     fun logBuildNodeSpec(
         oldSections: Set<NotifSection?>,
         newHeaders: Map<NotifSection?, NodeController?>,
         newCounts: Map<NotifSection?, Int>,
         newSectionOrder: List<NotifSection?>
     ) {
-        if (!Compile.IS_DEBUG)
+        if (!(Compile.IS_DEBUG && devLoggingEnabled))
             return
 
         buffer.log(TAG, LogLevel.DEBUG, {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
index f460644..9a9941e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
@@ -123,7 +123,7 @@
                 when (childNode.parent) {
                     null -> {
                         // A new child (either newly created or coming from some other parent)
-                        logger.logAttachingChild(childNode.label, parentNode.label)
+                        logger.logAttachingChild(childNode.label, parentNode.label, index)
                         parentNode.addChildAt(childNode, index)
                         childNode.parent = parentNode
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt
index 4c03572..6d1071c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt
@@ -43,12 +43,13 @@
         })
     }
 
-    fun logAttachingChild(key: String, parent: String) {
+    fun logAttachingChild(key: String, parent: String, atIndex: Int) {
         buffer.log(TAG, LogLevel.DEBUG, {
             str1 = key
             str2 = parent
+            int1 = atIndex
         }, {
-            "Attaching view $str1 to $str2"
+            "Attaching view $str1 to $str2 at index $int1"
         })
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
index 6ed8107..51dc728 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
@@ -19,10 +19,10 @@
 import android.content.Context
 import android.view.View
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.util.traceSection
 import dagger.assisted.Assisted
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java
index 19cf9dc..5ef2b9e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java
@@ -83,7 +83,7 @@
         params.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp);
         params.requireContentViews(FLAG_CONTENT_VIEW_HEADS_UP);
         CancellationSignal signal = mStage.requestRebind(entry, en -> {
-            mLogger.entryBoundSuccessfully(entry.getKey());
+            mLogger.entryBoundSuccessfully(entry);
             en.getRow().setUsesIncreasedHeadsUpHeight(params.useIncreasedHeadsUpHeight());
             // requestRebing promises that if we called cancel before this callback would be
             // invoked, then we will not enter this callback, and because we always cancel before
@@ -94,7 +94,7 @@
             }
         });
         abortBindCallback(entry);
-        mLogger.startBindingHun(entry.getKey());
+        mLogger.startBindingHun(entry);
         mOngoingBindCallbacks.put(entry, signal);
     }
 
@@ -105,7 +105,7 @@
     public void abortBindCallback(NotificationEntry entry) {
         CancellationSignal ongoingBindCallback = mOngoingBindCallbacks.remove(entry);
         if (ongoingBindCallback != null) {
-            mLogger.currentOngoingBindingAborted(entry.getKey());
+            mLogger.currentOngoingBindingAborted(entry);
             ongoingBindCallback.cancel();
         }
     }
@@ -116,7 +116,7 @@
     public void unbindHeadsUpView(NotificationEntry entry) {
         abortBindCallback(entry);
         mStage.getStageParams(entry).markContentViewsFreeable(FLAG_CONTENT_VIEW_HEADS_UP);
-        mLogger.entryContentViewMarkedFreeable(entry.getKey());
-        mStage.requestRebind(entry, e -> mLogger.entryUnbound(e.getKey()));
+        mLogger.entryContentViewMarkedFreeable(entry);
+        mStage.requestRebind(entry, e -> mLogger.entryUnbound(e));
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt
index 50a6207..d1feaa0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt
@@ -3,44 +3,46 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel.INFO
 import com.android.systemui.log.dagger.NotificationHeadsUpLog
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.logKey
 import javax.inject.Inject
 
 class HeadsUpViewBinderLogger @Inject constructor(@NotificationHeadsUpLog val buffer: LogBuffer) {
-    fun startBindingHun(key: String) {
+    fun startBindingHun(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "start binding heads up entry $str1 "
         })
     }
 
-    fun currentOngoingBindingAborted(key: String) {
+    fun currentOngoingBindingAborted(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "aborted potential ongoing heads up entry binding $str1 "
         })
     }
 
-    fun entryBoundSuccessfully(key: String) {
+    fun entryBoundSuccessfully(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "heads up entry bound successfully $str1 "
         })
     }
 
-    fun entryUnbound(key: String) {
+    fun entryUnbound(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "heads up entry unbound successfully $str1 "
         })
     }
 
-    fun entryContentViewMarkedFreeable(key: String) {
+    fun entryContentViewMarkedFreeable(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "start unbinding heads up entry $str1 "
         })
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
index 6c99e3a..016b388 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
@@ -16,20 +16,19 @@
 
 package com.android.systemui.statusbar.notification.interruption
 
-import android.service.notification.StatusBarNotification
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel.DEBUG
 import com.android.systemui.log.LogLevel.INFO
-import com.android.systemui.log.dagger.NotificationHeadsUpLog
-import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.log.dagger.NotificationInterruptLog
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.logKey
 import javax.inject.Inject
 
 class NotificationInterruptLogger @Inject constructor(
-    @NotificationLog val notifBuffer: LogBuffer,
-    @NotificationHeadsUpLog val hunBuffer: LogBuffer
+    @NotificationInterruptLog val buffer: LogBuffer
 ) {
     fun logHeadsUpFeatureChanged(useHeadsUp: Boolean) {
-        hunBuffer.log(TAG, INFO, {
+        buffer.log(TAG, INFO, {
             bool1 = useHeadsUp
         }, {
             "heads up is enabled=$bool1"
@@ -37,118 +36,118 @@
     }
 
     fun logWillDismissAll() {
-        hunBuffer.log(TAG, INFO, {
+        buffer.log(TAG, INFO, {
         }, {
             "dismissing any existing heads up notification on disable event"
         })
     }
 
-    fun logNoBubbleNotAllowed(sbn: StatusBarNotification) {
-        notifBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoBubbleNotAllowed(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No bubble up: not allowed to bubble: $str1"
         })
     }
 
-    fun logNoBubbleNoMetadata(sbn: StatusBarNotification) {
-        notifBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoBubbleNoMetadata(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No bubble up: notification: $str1 doesn't have valid metadata"
         })
     }
 
     fun logNoHeadsUpFeatureDisabled() {
-        hunBuffer.log(TAG, DEBUG, {
+        buffer.log(TAG, DEBUG, {
         }, {
             "No heads up: no huns"
         })
     }
 
-    fun logNoHeadsUpPackageSnoozed(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoHeadsUpPackageSnoozed(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No alerting: snoozed package: $str1"
         })
     }
 
-    fun logNoHeadsUpAlreadyBubbled(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoHeadsUpAlreadyBubbled(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No heads up: in unlocked shade where notification is shown as a bubble: $str1"
         })
     }
 
-    fun logNoHeadsUpSuppressedByDnd(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoHeadsUpSuppressedByDnd(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No heads up: suppressed by DND: $str1"
         })
     }
 
-    fun logNoHeadsUpNotImportant(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoHeadsUpNotImportant(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No heads up: unimportant notification: $str1"
         })
     }
 
-    fun logNoHeadsUpNotInUse(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoHeadsUpNotInUse(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No heads up: not in use: $str1"
         })
     }
 
     fun logNoHeadsUpSuppressedBy(
-        sbn: StatusBarNotification,
+        entry: NotificationEntry,
         suppressor: NotificationInterruptSuppressor
     ) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
             str2 = suppressor.name
         }, {
             "No heads up: aborted by suppressor: $str2 sbnKey=$str1"
         })
     }
 
-    fun logHeadsUp(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logHeadsUp(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "Heads up: $str1"
         })
     }
 
-    fun logNoAlertingFilteredOut(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoAlertingFilteredOut(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No alerting: filtered notification: $str1"
         })
     }
 
-    fun logNoAlertingGroupAlertBehavior(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoAlertingGroupAlertBehavior(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No alerting: suppressed due to group alert behavior: $str1"
         })
     }
 
     fun logNoAlertingSuppressedBy(
-        sbn: StatusBarNotification,
+        entry: NotificationEntry,
         suppressor: NotificationInterruptSuppressor,
         awake: Boolean
     ) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
             str2 = suppressor.name
             bool1 = awake
         }, {
@@ -156,65 +155,65 @@
         })
     }
 
-    fun logNoAlertingRecentFullscreen(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoAlertingRecentFullscreen(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No alerting: recent fullscreen: $str1"
         })
     }
 
-    fun logNoPulsingSettingDisabled(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoPulsingSettingDisabled(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No pulsing: disabled by setting: $str1"
         })
     }
 
-    fun logNoPulsingBatteryDisabled(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoPulsingBatteryDisabled(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No pulsing: disabled by battery saver: $str1"
         })
     }
 
-    fun logNoPulsingNoAlert(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoPulsingNoAlert(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No pulsing: notification shouldn't alert: $str1"
         })
     }
 
-    fun logNoPulsingNoAmbientEffect(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoPulsingNoAmbientEffect(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No pulsing: ambient effect suppressed: $str1"
         })
     }
 
-    fun logNoPulsingNotImportant(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logNoPulsingNotImportant(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "No pulsing: not important enough: $str1"
         })
     }
 
-    fun logPulsing(sbn: StatusBarNotification) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = sbn.key
+    fun logPulsing(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "Pulsing: $str1"
         })
     }
 
-    fun keyguardHideNotification(key: String) {
-        hunBuffer.log(TAG, DEBUG, {
-            str1 = key
+    fun keyguardHideNotification(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
         }, {
             "Keyguard Hide Notification: $str1"
         })
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index e210f19..8378b69 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -147,14 +147,14 @@
         }
 
         if (!entry.canBubble()) {
-            mLogger.logNoBubbleNotAllowed(sbn);
+            mLogger.logNoBubbleNotAllowed(entry);
             return false;
         }
 
         if (entry.getBubbleMetadata() == null
                 || (entry.getBubbleMetadata().getShortcutId() == null
                     && entry.getBubbleMetadata().getIntent() == null)) {
-            mLogger.logNoBubbleNoMetadata(sbn);
+            mLogger.logNoBubbleNoMetadata(entry);
             return false;
         }
 
@@ -194,28 +194,32 @@
             return false;
         }
 
+        if (!canAlertHeadsUpCommon(entry)) {
+            return false;
+        }
+
         if (!canAlertAwakeCommon(entry)) {
             return false;
         }
 
         if (isSnoozedPackage(sbn)) {
-            mLogger.logNoHeadsUpPackageSnoozed(sbn);
+            mLogger.logNoHeadsUpPackageSnoozed(entry);
             return false;
         }
 
         boolean inShade = mStatusBarStateController.getState() == SHADE;
         if (entry.isBubble() && inShade) {
-            mLogger.logNoHeadsUpAlreadyBubbled(sbn);
+            mLogger.logNoHeadsUpAlreadyBubbled(entry);
             return false;
         }
 
         if (entry.shouldSuppressPeek()) {
-            mLogger.logNoHeadsUpSuppressedByDnd(sbn);
+            mLogger.logNoHeadsUpSuppressedByDnd(entry);
             return false;
         }
 
         if (entry.getImportance() < NotificationManager.IMPORTANCE_HIGH) {
-            mLogger.logNoHeadsUpNotImportant(sbn);
+            mLogger.logNoHeadsUpNotImportant(entry);
             return false;
         }
 
@@ -228,17 +232,17 @@
         boolean inUse = mPowerManager.isScreenOn() && !isDreaming;
 
         if (!inUse) {
-            mLogger.logNoHeadsUpNotInUse(sbn);
+            mLogger.logNoHeadsUpNotInUse(entry);
             return false;
         }
 
         for (int i = 0; i < mSuppressors.size(); i++) {
             if (mSuppressors.get(i).suppressAwakeHeadsUp(entry)) {
-                mLogger.logNoHeadsUpSuppressedBy(sbn, mSuppressors.get(i));
+                mLogger.logNoHeadsUpSuppressedBy(entry, mSuppressors.get(i));
                 return false;
             }
         }
-        mLogger.logHeadsUp(sbn);
+        mLogger.logHeadsUp(entry);
         return true;
     }
 
@@ -250,33 +254,36 @@
      * @return true if the entry should ambient pulse, false otherwise
      */
     private boolean shouldHeadsUpWhenDozing(NotificationEntry entry) {
-        StatusBarNotification sbn = entry.getSbn();
-
         if (!mAmbientDisplayConfiguration.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) {
-            mLogger.logNoPulsingSettingDisabled(sbn);
+            mLogger.logNoPulsingSettingDisabled(entry);
             return false;
         }
 
         if (mBatteryController.isAodPowerSave()) {
-            mLogger.logNoPulsingBatteryDisabled(sbn);
+            mLogger.logNoPulsingBatteryDisabled(entry);
             return false;
         }
 
         if (!canAlertCommon(entry)) {
-            mLogger.logNoPulsingNoAlert(sbn);
+            mLogger.logNoPulsingNoAlert(entry);
+            return false;
+        }
+
+        if (!canAlertHeadsUpCommon(entry)) {
+            mLogger.logNoPulsingNoAlert(entry);
             return false;
         }
 
         if (entry.shouldSuppressAmbient()) {
-            mLogger.logNoPulsingNoAmbientEffect(sbn);
+            mLogger.logNoPulsingNoAmbientEffect(entry);
             return false;
         }
 
         if (entry.getImportance() < NotificationManager.IMPORTANCE_DEFAULT) {
-            mLogger.logNoPulsingNotImportant(sbn);
+            mLogger.logNoPulsingNotImportant(entry);
             return false;
         }
-        mLogger.logPulsing(sbn);
+        mLogger.logPulsing(entry);
         return true;
     }
 
@@ -287,33 +294,43 @@
      * @return true if these checks pass, false if the notification should not alert
      */
     private boolean canAlertCommon(NotificationEntry entry) {
-        StatusBarNotification sbn = entry.getSbn();
-
         if (!mFlags.isNewPipelineEnabled() && mNotificationFilter.shouldFilterOut(entry)) {
-            mLogger.logNoAlertingFilteredOut(sbn);
-            return false;
-        }
-
-        // Don't alert notifications that are suppressed due to group alert behavior
-        if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) {
-            mLogger.logNoAlertingGroupAlertBehavior(sbn);
+            mLogger.logNoAlertingFilteredOut(entry);
             return false;
         }
 
         for (int i = 0; i < mSuppressors.size(); i++) {
             if (mSuppressors.get(i).suppressInterruptions(entry)) {
-                mLogger.logNoAlertingSuppressedBy(sbn, mSuppressors.get(i), /* awake */ false);
+                mLogger.logNoAlertingSuppressedBy(entry, mSuppressors.get(i), /* awake */ false);
                 return false;
             }
         }
 
-        if (entry.hasJustLaunchedFullScreenIntent()) {
-            mLogger.logNoAlertingRecentFullscreen(sbn);
+        if (mKeyguardNotificationVisibilityProvider.shouldHideNotification(entry)) {
+            mLogger.keyguardHideNotification(entry);
             return false;
         }
 
-        if (mKeyguardNotificationVisibilityProvider.shouldHideNotification(entry)) {
-            mLogger.keyguardHideNotification(entry.getKey());
+        return true;
+    }
+
+    /**
+     * Common checks for heads up notifications on regular and AOD displays.
+     *
+     * @param entry the entry to check
+     * @return true if these checks pass, false if the notification should not alert
+     */
+    private boolean canAlertHeadsUpCommon(NotificationEntry entry) {
+        StatusBarNotification sbn = entry.getSbn();
+
+        // Don't alert notifications that are suppressed due to group alert behavior
+        if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) {
+            mLogger.logNoAlertingGroupAlertBehavior(entry);
+            return false;
+        }
+
+        if (entry.hasJustLaunchedFullScreenIntent()) {
+            mLogger.logNoAlertingRecentFullscreen(entry);
             return false;
         }
 
@@ -331,7 +348,7 @@
 
         for (int i = 0; i < mSuppressors.size(); i++) {
             if (mSuppressors.get(i).suppressAwakeInterruptions(entry)) {
-                mLogger.logNoAlertingSuppressedBy(sbn, mSuppressors.get(i), /* awake */ true);
+                mLogger.logNoAlertingSuppressedBy(entry, mSuppressors.get(i), /* awake */ true);
                 return false;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index eb496ab..cd4a44e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -141,7 +141,7 @@
     public static final float DEFAULT_HEADER_VISIBLE_AMOUNT = 1.0f;
     private static final long RECENTLY_ALERTED_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30);
 
-    private boolean mUpdateBackgroundOnUpdate;
+    private boolean mUpdateSelfBackgroundOnUpdate;
     private boolean mNotificationTranslationFinished = false;
     private boolean mIsSnoozed;
     private boolean mIsFaded;
@@ -553,9 +553,28 @@
         updateLimits();
         updateShelfIconColor();
         updateRippleAllowed();
-        if (mUpdateBackgroundOnUpdate) {
-            mUpdateBackgroundOnUpdate = false;
-            updateBackgroundColors();
+        if (mUpdateSelfBackgroundOnUpdate) {
+            // Because this is triggered by UiMode change which we already propagated to children,
+            // we know that child rows will receive the same event, and will update their own
+            // backgrounds when they finish inflating, so propagating again would be redundant.
+            mUpdateSelfBackgroundOnUpdate = false;
+            updateBackgroundColorsOfSelf();
+        }
+    }
+
+    private void updateBackgroundColorsOfSelf() {
+        super.updateBackgroundColors();
+    }
+
+    @Override
+    public void updateBackgroundColors() {
+        // Because this call is made by the NSSL only on attached rows at the moment of the
+        // UiMode or Theme change, we have to propagate to our child views.
+        updateBackgroundColorsOfSelf();
+        if (mIsSummaryWithChildren) {
+            for (ExpandableNotificationRow child : mChildrenContainer.getAttachedChildren()) {
+                child.updateBackgroundColors();
+            }
         }
     }
 
@@ -1242,7 +1261,7 @@
     }
 
     public void onUiModeChanged() {
-        mUpdateBackgroundOnUpdate = true;
+        mUpdateSelfBackgroundOnUpdate = true;
         reInflateViews();
         if (mChildrenContainer != null) {
             for (ExpandableNotificationRow child : mChildrenContainer.getAttachedChildren()) {
@@ -2073,6 +2092,13 @@
 
     public void applyLaunchAnimationParams(LaunchAnimationParameters params) {
         if (params == null) {
+            // `null` params indicates the animation is over, which means we can't access
+            // params.getParentStartClipTopAmount() which has the value we want to restore.
+            // Fortunately, only NotificationShelf actually uses these values for anything other
+            // than this launch animation, so we can restore the value to 0 and it's right for now.
+            if (mNotificationParent != null) {
+                mNotificationParent.setClipTopAmount(0);
+            }
             return;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 599039d..a493a67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -19,6 +19,7 @@
 import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
 import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
 
 import android.util.Log;
 import android.view.View;
@@ -247,7 +248,7 @@
     @Override
     @NonNull
     public String getNodeLabel() {
-        return mView.getEntry().getKey();
+        return logKey(mView.getEntry());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index d71e7680..8f73b80 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -58,7 +58,6 @@
     private ArrayList<View> mMatchParentViews = new ArrayList<View>();
     private static Rect mClipRect = new Rect();
     private boolean mWillBeGone;
-    private int mMinClipTopAmount = 0;
     private boolean mClipToActualHeight = true;
     private boolean mChangingPosition = false;
     private ViewGroup mTransientContainer;
@@ -187,10 +186,12 @@
      * @param notifyListeners Whether the listener should be informed about the change.
      */
     public void setActualHeight(int actualHeight, boolean notifyListeners) {
-        mActualHeight = actualHeight;
-        updateClipping();
-        if (notifyListeners) {
-            notifyHeightChanged(false  /* needsAnimation */);
+        if (mActualHeight != actualHeight) {
+            mActualHeight = actualHeight;
+            updateClipping();
+            if (notifyListeners) {
+                notifyHeightChanged(false  /* needsAnimation */);
+            }
         }
     }
 
@@ -477,14 +478,6 @@
         mWillBeGone = willBeGone;
     }
 
-    public int getMinClipTopAmount() {
-        return mMinClipTopAmount;
-    }
-
-    public void setMinClipTopAmount(int minClipTopAmount) {
-        mMinClipTopAmount = minClipTopAmount;
-    }
-
     @Override
     public void setLayerType(int layerType, Paint paint) {
         // Allow resetting the layerType to NONE regardless of overlappingRendering
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
index c661408..99a24cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
@@ -67,6 +67,7 @@
         mConversationIconView = requireViewById(com.android.internal.R.id.conversation_icon);
         mConversationFacePile = requireViewById(com.android.internal.R.id.conversation_face_pile);
         mConversationSenderName = requireViewById(R.id.conversation_notification_sender);
+        applyTextColor(mConversationSenderName, mSecondaryTextColor);
         mFacePileSize = getResources()
                 .getDimensionPixelSize(R.dimen.conversation_single_line_face_pile_size);
         mFacePileAvatarSize = getResources()
@@ -75,6 +76,9 @@
                 .getDimensionPixelSize(R.dimen.conversation_single_line_avatar_size);
         mFacePileProtectionWidth = getResources().getDimensionPixelSize(
                 R.dimen.conversation_single_line_face_pile_protection_width);
+        mTransformationHelper.setCustomTransformation(
+                new FadeOutAndDownWithTitleTransformation(mConversationSenderName),
+                mConversationSenderName.getId());
         mTransformationHelper.addViewTransformingToSimilar(mConversationIconView);
         mTransformationHelper.addTransformedView(mConversationSenderName);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
index 56f8e08..77fd051 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
@@ -16,13 +16,14 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
 import android.content.res.Resources;
 import android.service.notification.StatusBarNotification;
 import android.util.TypedValue;
-import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -55,10 +56,8 @@
         mOverflowNumberPadding = res.getDimensionPixelSize(R.dimen.group_overflow_number_padding);
     }
 
-    private HybridNotificationView inflateHybridViewWithStyle(int style,
-            View contentView, ViewGroup parent) {
-        LayoutInflater inflater = new ContextThemeWrapper(mContext, style)
-                .getSystemService(LayoutInflater.class);
+    private HybridNotificationView inflateHybridView(View contentView, ViewGroup parent) {
+        LayoutInflater inflater = LayoutInflater.from(mContext);
         int layout = contentView instanceof ConversationLayout
                 ? R.layout.hybrid_conversation_notification
                 : R.layout.hybrid_notification;
@@ -91,16 +90,8 @@
     public HybridNotificationView bindFromNotification(HybridNotificationView reusableView,
             View contentView, StatusBarNotification notification,
             ViewGroup parent) {
-        return bindFromNotificationWithStyle(reusableView, contentView, notification,
-                R.style.HybridNotification, parent);
-    }
-
-    private HybridNotificationView bindFromNotificationWithStyle(
-            HybridNotificationView reusableView, View contentView,
-            StatusBarNotification notification,
-            int style, ViewGroup parent) {
         if (reusableView == null) {
-            reusableView = inflateHybridViewWithStyle(style, contentView, parent);
+            reusableView = inflateHybridView(contentView, parent);
         }
         CharSequence titleText = resolveTitle(notification.getNotification());
         CharSequence contentText = resolveText(notification.getNotification());
@@ -136,8 +127,8 @@
         if (!text.equals(reusableView.getText())) {
             reusableView.setText(text);
         }
-        String contentDescription = String.format(mContext.getResources().getQuantityString(
-                R.plurals.notification_group_overflow_description, number), number);
+        String contentDescription = icuMessageFormat(mContext.getResources(),
+                R.string.notification_group_overflow_description, number);
 
         reusableView.setContentDescription(contentDescription);
         reusableView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mOverflowNumberSize);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
index c0d85a6..fc9d9e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridNotificationView.java
@@ -16,13 +16,18 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static android.app.Notification.COLOR_INVALID;
+
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.TextView;
 
+import androidx.annotation.ColorInt;
+
 import com.android.keyguard.AlphaOptimizedLinearLayout;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.CrossFadeHelper;
@@ -40,6 +45,8 @@
     protected final ViewTransformationHelper mTransformationHelper = new ViewTransformationHelper();
     protected TextView mTitleView;
     protected TextView mTextView;
+    protected int mPrimaryTextColor = COLOR_INVALID;
+    protected int mSecondaryTextColor = COLOR_INVALID;
 
     public HybridNotificationView(Context context) {
         this(context, null);
@@ -69,42 +76,37 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
+        resolveThemeTextColors();
         mTitleView = findViewById(R.id.notification_title);
         mTextView = findViewById(R.id.notification_text);
+        applyTextColor(mTitleView, mPrimaryTextColor);
+        applyTextColor(mTextView, mSecondaryTextColor);
         mTransformationHelper.setCustomTransformation(
-                new ViewTransformationHelper.CustomTransformation() {
-                    @Override
-                    public boolean transformTo(TransformState ownState, TransformableView notification,
-                            float transformationAmount) {
-                        // We want to transform to the same y location as the title
-                        TransformState otherState = notification.getCurrentState(
-                                TRANSFORMING_VIEW_TITLE);
-                        CrossFadeHelper.fadeOut(mTextView, transformationAmount);
-                        if (otherState != null) {
-                            ownState.transformViewVerticalTo(otherState, transformationAmount);
-                            otherState.recycle();
-                        }
-                        return true;
-                    }
-
-                    @Override
-                    public boolean transformFrom(TransformState ownState,
-                            TransformableView notification, float transformationAmount) {
-                        // We want to transform from the same y location as the title
-                        TransformState otherState = notification.getCurrentState(
-                                TRANSFORMING_VIEW_TITLE);
-                        CrossFadeHelper.fadeIn(mTextView, transformationAmount, true /* remap */);
-                        if (otherState != null) {
-                            ownState.transformViewVerticalFrom(otherState, transformationAmount);
-                            otherState.recycle();
-                        }
-                        return true;
-                    }
-                }, TRANSFORMING_VIEW_TEXT);
+                new FadeOutAndDownWithTitleTransformation(mTextView),
+                TRANSFORMING_VIEW_TEXT);
         mTransformationHelper.addTransformedView(TRANSFORMING_VIEW_TITLE, mTitleView);
         mTransformationHelper.addTransformedView(TRANSFORMING_VIEW_TEXT, mTextView);
     }
 
+    protected void applyTextColor(TextView textView, @ColorInt int textColor) {
+        if (textColor != COLOR_INVALID) {
+            textView.setTextColor(textColor);
+        }
+    }
+
+    private void resolveThemeTextColors() {
+        try (TypedArray ta = mContext.getTheme().obtainStyledAttributes(
+                android.R.style.Theme_DeviceDefault_DayNight, new int[]{
+                        android.R.attr.textColorPrimary,
+                        android.R.attr.textColorSecondary
+                })) {
+            if (ta != null) {
+                mPrimaryTextColor = ta.getColor(0, mPrimaryTextColor);
+                mSecondaryTextColor = ta.getColor(1, mSecondaryTextColor);
+            }
+        }
+    }
+
     public void bind(@Nullable CharSequence title, @Nullable CharSequence text,
             @Nullable View contentView) {
         mTitleView.setText(title);
@@ -152,4 +154,40 @@
 
     @Override
     public void setNotificationFaded(boolean faded) {}
+
+    protected static class FadeOutAndDownWithTitleTransformation extends
+            ViewTransformationHelper.CustomTransformation {
+
+        private final View mView;
+
+        public FadeOutAndDownWithTitleTransformation(View view) {
+            mView = view;
+        }
+
+        @Override
+        public boolean transformTo(TransformState ownState, TransformableView notification,
+                float transformationAmount) {
+            // We want to transform to the same y location as the title
+            TransformState otherState = notification.getCurrentState(TRANSFORMING_VIEW_TITLE);
+            CrossFadeHelper.fadeOut(mView, transformationAmount);
+            if (otherState != null) {
+                ownState.transformViewVerticalTo(otherState, transformationAmount);
+                otherState.recycle();
+            }
+            return true;
+        }
+
+        @Override
+        public boolean transformFrom(TransformState ownState,
+                TransformableView notification, float transformationAmount) {
+            // We want to transform from the same y location as the title
+            TransformState otherState = notification.getCurrentState(TRANSFORMING_VIEW_TITLE);
+            CrossFadeHelper.fadeIn(mView, transformationAmount, true /* remap */);
+            if (otherState != null) {
+                ownState.transformViewVerticalFrom(otherState, transformationAmount);
+                otherState.recycle();
+            }
+            return true;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java
index f693ebb..ea564dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java
@@ -112,7 +112,8 @@
     public void manageRow(
             @NonNull NotificationEntry entry,
             @NonNull ExpandableNotificationRow row) {
-        mLogger.logManagedRow(entry.getKey());
+        mLogger.logManagedRow(entry);
+        mLogger.logManagedRow(entry);
 
         final BindEntry bindEntry = getBindEntry(entry);
         if (bindEntry == null) {
@@ -154,12 +155,12 @@
      * the real work once rather than repeatedly start and cancel it.
      */
     private void requestPipelineRun(NotificationEntry entry) {
-        mLogger.logRequestPipelineRun(entry.getKey());
+        mLogger.logRequestPipelineRun(entry);
 
         final BindEntry bindEntry = getBindEntry(entry);
         if (bindEntry.row == null) {
             // Row is not managed yet but may be soon. Stop for now.
-            mLogger.logRequestPipelineRowNotSet(entry.getKey());
+            mLogger.logRequestPipelineRowNotSet(entry);
             return;
         }
 
@@ -177,7 +178,7 @@
      * callbacks when the run finishes. If a run is already in progress, it is restarted.
      */
     private void startPipeline(NotificationEntry entry) {
-        mLogger.logStartPipeline(entry.getKey());
+        mLogger.logStartPipeline(entry);
 
         if (mStage == null) {
             throw new IllegalStateException("No stage was ever set on the pipeline");
@@ -193,7 +194,7 @@
         final BindEntry bindEntry = getBindEntry(entry);
         final Set<BindCallback> callbacks = bindEntry.callbacks;
 
-        mLogger.logFinishedPipeline(entry.getKey(), callbacks.size());
+        mLogger.logFinishedPipeline(entry, callbacks.size());
 
         bindEntry.invalidated = false;
         // Move all callbacks to separate list as callbacks may themselves add/remove callbacks.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt
index ec406f0..ab91926 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt
@@ -19,6 +19,8 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel.INFO
 import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.logKey
 import javax.inject.Inject
 
 class NotifBindPipelineLogger @Inject constructor(
@@ -32,41 +34,41 @@
         })
     }
 
-    fun logManagedRow(notifKey: String) {
+    fun logManagedRow(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = notifKey
+            str1 = entry.logKey
         }, {
             "Row set for notif: $str1"
         })
     }
 
-    fun logRequestPipelineRun(notifKey: String) {
+    fun logRequestPipelineRun(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = notifKey
+            str1 = entry.logKey
         }, {
             "Request pipeline run for notif: $str1"
         })
     }
 
-    fun logRequestPipelineRowNotSet(notifKey: String) {
+    fun logRequestPipelineRowNotSet(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = notifKey
+            str1 = entry.logKey
         }, {
             "Row is not set so pipeline will not run. notif = $str1"
         })
     }
 
-    fun logStartPipeline(notifKey: String) {
+    fun logStartPipeline(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = notifKey
+            str1 = entry.logKey
         }, {
             "Start pipeline for notif: $str1"
         })
     }
 
-    fun logFinishedPipeline(notifKey: String, numCallbacks: Int) {
+    fun logFinishedPipeline(entry: NotificationEntry, numCallbacks: Int) {
         buffer.log(TAG, INFO, {
-            str1 = notifKey
+            str1 = entry.logKey
             int1 = numCallbacks
         }, {
             "Finished pipeline for notif $str1 with $int1 callbacks"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index 134f24e..27aa4b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -266,9 +266,14 @@
         snooze.setOnClickListener(mOnSnoozeClick);
         */
 
-        if (mAppBubble == BUBBLE_PREFERENCE_ALL) {
-            ((TextView) findViewById(R.id.default_summary)).setText(getResources().getString(
+        TextView defaultSummaryTextView = findViewById(R.id.default_summary);
+        if (mAppBubble == BUBBLE_PREFERENCE_ALL
+                && BubblesManager.areBubblesEnabled(mContext, mSbn.getUser())) {
+            defaultSummaryTextView.setText(getResources().getString(
                     R.string.notification_channel_summary_default_with_bubbles, mAppName));
+        } else {
+            defaultSummaryTextView.setText(getResources().getString(
+                    R.string.notification_channel_summary_default));
         }
 
         findViewById(R.id.priority).setOnClickListener(mOnFavoriteClick);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
index 7269f55..512b049 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
@@ -243,11 +245,11 @@
     private SnoozeOption createOption(int minutes, int accessibilityActionId) {
         Resources res = getResources();
         boolean showInHours = minutes >= 60;
-        int pluralResId = showInHours
-                ? R.plurals.snoozeHourOptions
-                : R.plurals.snoozeMinuteOptions;
+        int stringResId = showInHours
+                ? R.string.snoozeHourOptions
+                : R.string.snoozeMinuteOptions;
         int count = showInHours ? (minutes / 60) : minutes;
-        String description = res.getQuantityString(pluralResId, count, count);
+        String description = icuMessageFormat(res, stringResId, count);
         String resultText = String.format(res.getString(R.string.snoozed_for_time), description);
         AccessibilityAction action = new AccessibilityAction(accessibilityActionId, description);
         final int index = resultText.indexOf(description);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java
index 3616f8f..81cf146 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java
@@ -57,7 +57,7 @@
             @NonNull StageCallback callback) {
         RowContentBindParams params = getStageParams(entry);
 
-        mLogger.logStageParams(entry.getKey(), params.toString());
+        mLogger.logStageParams(entry, params);
 
         // Resolve content to bind/unbind.
         @InflationFlag int inflationFlags = params.getContentViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt
index 29cce33..f9923b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt
@@ -19,17 +19,19 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel.INFO
 import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.logKey
 import javax.inject.Inject
 
 class RowContentBindStageLogger @Inject constructor(
     @NotificationLog private val buffer: LogBuffer
 ) {
-    fun logStageParams(notifKey: String, stageParams: String) {
+    fun logStageParams(entry: NotificationEntry, stageParams: RowContentBindParams) {
         buffer.log(TAG, INFO, {
-            str1 = notifKey
-            str2 = stageParams
+            str1 = entry.logKey
+            str2 = stageParams.toString()
         }, {
-            "Invalidated notif $str1 with params: \n$str2"
+            "Invalidated notif $str1 with params: $str2"
         })
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
index 7414bdc..5aaf63f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
@@ -74,11 +74,6 @@
         mSecondaryView = findSecondaryView();
         setVisible(false /* nowVisible */, false /* animate */);
         setSecondaryVisible(false /* nowVisible */, false /* animate */);
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
         setOutlineProvider(null);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index a552f99..a76f0827 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -1312,6 +1312,7 @@
             }
             float bottomRoundness = last ? currentBottomRoundness : 0.0f;
             child.setBottomRoundness(bottomRoundness, isShown() /* animate */);
+            child.setTopRoundness(0.0f, false /* animate */);
             last = false;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index c9d70d1..2fd02d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -19,6 +19,8 @@
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING;
 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;
 import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
+import static com.android.systemui.util.DumpUtilsKt.println;
+import static com.android.systemui.util.DumpUtilsKt.visibilityString;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
@@ -746,19 +748,20 @@
         }
     }
 
-    private void logHunSkippedForUnexpectedState(String key, boolean expected, boolean actual) {
+    private void logHunSkippedForUnexpectedState(ExpandableNotificationRow enr,
+            boolean expected, boolean actual) {
         if (mLogger == null) return;
-        mLogger.hunSkippedForUnexpectedState(key, expected, actual);
+        mLogger.hunSkippedForUnexpectedState(enr.getEntry(), expected, actual);
     }
 
-    private void logHunAnimationSkipped(String key, String reason) {
+    private void logHunAnimationSkipped(ExpandableNotificationRow enr, String reason) {
         if (mLogger == null) return;
-        mLogger.hunAnimationSkipped(key, reason);
+        mLogger.hunAnimationSkipped(enr.getEntry(), reason);
     }
 
-    private void logHunAnimationEventAdded(String key, int type) {
+    private void logHunAnimationEventAdded(ExpandableNotificationRow enr, int type) {
         if (mLogger == null) return;
-        mLogger.hunAnimationEventAdded(key, type);
+        mLogger.hunAnimationEventAdded(enr.getEntry(), type);
     }
 
     private void onDrawDebug(Canvas canvas) {
@@ -1323,10 +1326,24 @@
         if (mOnStackYChanged != null) {
             mOnStackYChanged.accept(listenerNeedsAnimation);
         }
+        updateStackEndHeightAndStackHeight(fraction);
+    }
+
+    @VisibleForTesting
+    public void updateStackEndHeightAndStackHeight(float fraction) {
+        final float oldStackHeight = mAmbientState.getStackHeight();
         if (mQsExpansionFraction <= 0 && !shouldSkipHeightUpdate()) {
             final float endHeight = updateStackEndHeight(
                     getHeight(), getEmptyBottomMargin(), mTopPadding);
             updateStackHeight(endHeight, fraction);
+        } else {
+            // Always updateStackHeight to prevent jumps in the stack height when this fraction
+            // suddenly reapplies after a freeze.
+            final float endHeight = mAmbientState.getStackEndHeight();
+            updateStackHeight(endHeight, fraction);
+        }
+        if (oldStackHeight != mAmbientState.getStackHeight()) {
+            requestChildrenUpdate();
         }
     }
 
@@ -1343,6 +1360,7 @@
         return stackEndHeight;
     }
 
+    @VisibleForTesting
     public void updateStackHeight(float endHeight, float fraction) {
         // During the (AOD<=>LS) transition where dozeAmount is changing,
         // apply dozeAmount to stack height instead of expansionFraction
@@ -1371,12 +1389,7 @@
      */
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     public void setExpandedHeight(float height) {
-        final float shadeBottom = getHeight() - getEmptyBottomMargin();
         final boolean skipHeightUpdate = shouldSkipHeightUpdate();
-        if (!skipHeightUpdate) {
-            final float expansionFraction = MathUtils.saturate(height / shadeBottom);
-            mAmbientState.setExpansionFraction(expansionFraction);
-        }
         updateStackPosition();
 
         if (!skipHeightUpdate) {
@@ -3162,7 +3175,7 @@
             if (isHeadsUp != row.isHeadsUp()) {
                 // For cases where we have a heads up showing and appearing again we shouldn't
                 // do the animations at all.
-                logHunSkippedForUnexpectedState(key, isHeadsUp, row.isHeadsUp());
+                logHunSkippedForUnexpectedState(row, isHeadsUp, row.isHeadsUp());
                 continue;
             }
             int type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_OTHER;
@@ -3180,7 +3193,7 @@
                 if (row.isChildInGroup()) {
                     // We can otherwise get stuck in there if it was just isolated
                     row.setHeadsUpAnimatingAway(false);
-                    logHunAnimationSkipped(key, "row is child in group");
+                    logHunAnimationSkipped(row, "row is child in group");
                     continue;
                 }
             } else {
@@ -3188,7 +3201,7 @@
                 if (viewState == null) {
                     // A view state was never generated for this view, so we don't need to animate
                     // this. This may happen with notification children.
-                    logHunAnimationSkipped(key, "row has no viewState");
+                    logHunAnimationSkipped(row, "row has no viewState");
                     continue;
                 }
                 if (isHeadsUp && (mAddedHeadsUpChildren.contains(row) || pinnedAndClosed)) {
@@ -3212,7 +3225,7 @@
                         + " onBottom=" + onBottom
                         + " row=" + row.getEntry().getKey());
             }
-            logHunAnimationEventAdded(key, type);
+            logHunAnimationEventAdded(row, type);
         }
         mHeadsUpChangeAnimations.clear();
         mAddedHeadsUpChildren.clear();
@@ -4348,8 +4361,6 @@
 
     /**
      * Update colors of "dismiss" and "empty shade" views.
-     *
-     * @param lightTheme True if light theme should be used.
      */
     @ShadeViewRefactor(RefactorComponent.DECORATOR)
     void updateDecorViews() {
@@ -4543,31 +4554,12 @@
         mClearAllInProgress = clearAllInProgress;
         mAmbientState.setClearAllInProgress(clearAllInProgress);
         mController.getNoticationRoundessManager().setClearAllInProgress(clearAllInProgress);
-        handleClearAllClipping();
     }
 
     boolean getClearAllInProgress() {
         return mClearAllInProgress;
     }
 
-    @ShadeViewRefactor(RefactorComponent.ADAPTER)
-    private void handleClearAllClipping() {
-        final int count = getChildCount();
-        boolean previousChildWillBeDismissed = false;
-        for (int i = 0; i < count; i++) {
-            ExpandableView child = (ExpandableView) getChildAt(i);
-            if (child.getVisibility() == GONE) {
-                continue;
-            }
-            if (mClearAllInProgress && previousChildWillBeDismissed) {
-                child.setMinClipTopAmount(child.getClipTopAmount());
-            } else {
-                child.setMinClipTopAmount(0);
-            }
-            previousChildWillBeDismissed = canChildBeCleared(child);
-        }
-    }
-
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public boolean isFooterViewNotGone() {
         return mFooterView != null
@@ -4784,8 +4776,7 @@
                 if (SPEW) {
                     Log.v(TAG, "generateHeadsUpAnimation: previous hun appear animation cancelled");
                 }
-                logHunAnimationSkipped(row.getEntry().getKey(),
-                        "previous hun appear animation cancelled");
+                logHunAnimationSkipped(row, "previous hun appear animation cancelled");
                 return;
             }
             mHeadsUpChangeAnimations.add(new Pair<>(row, isHeadsUp));
@@ -5041,6 +5032,19 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void setUnlockHintRunning(boolean running) {
         mAmbientState.setUnlockHintRunning(running);
+        if (!running) {
+            // re-calculate the stack height which was frozen while running this animation
+            updateStackPosition();
+        }
+    }
+
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    public void setPanelFlinging(boolean flinging) {
+        mAmbientState.setIsFlinging(flinging);
+        if (!flinging) {
+            // re-calculate the stack height which was frozen while flinging
+            updateStackPosition();
+        }
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -5051,30 +5055,31 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void dump(PrintWriter pwOriginal, String[] args) {
         IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
-        StringBuilder sb = new StringBuilder("[")
-                .append(this.getClass().getSimpleName()).append(":")
-                .append(" pulsing=").append(mPulsing ? "T" : "f")
-                .append(" expanded=").append(mIsExpanded ? "T" : "f")
-                .append(" headsUpPinned=").append(mInHeadsUpPinnedMode ? "T" : "f")
-                .append(" qsClipping=").append(mShouldUseRoundedRectClipping ? "T" : "f")
-                .append(" qsClipDismiss=").append(mDismissUsingRowTranslationX ? "T" : "f")
-                .append(" visibility=").append(DumpUtilsKt.visibilityString(getVisibility()))
-                .append(" alpha=").append(getAlpha())
-                .append(" scrollY=").append(mAmbientState.getScrollY())
-                .append(" maxTopPadding=").append(mMaxTopPadding)
-                .append(" showShelfOnly=").append(mShouldShowShelfOnly ? "T" : "f")
-                .append(" qsExpandFraction=").append(mQsExpansionFraction)
-                .append(" isCurrentUserSetup=").append(mIsCurrentUserSetup)
-                .append(" hideAmount=").append(mAmbientState.getHideAmount())
-                .append(" ambientStateSwipingUp=").append(mAmbientState.isSwipingUp())
-                .append(" maxDisplayedNotifications=").append(mMaxDisplayedNotifications)
-                .append(" intrinsicContentHeight=").append(mIntrinsicContentHeight)
-                .append(" contentHeight=").append(mContentHeight)
-                .append(" intrinsicPadding=").append(mIntrinsicPadding)
-                .append(" topPadding=").append(mTopPadding)
-                .append(" bottomPadding=").append(mBottomPadding)
-                .append("]");
-        pw.println(sb.toString());
+        pw.println("Internal state:");
+        DumpUtilsKt.withIncreasedIndent(pw, () -> {
+            println(pw, "pulsing", mPulsing);
+            println(pw, "expanded", mIsExpanded);
+            println(pw, "headsUpPinned", mInHeadsUpPinnedMode);
+            println(pw, "qsClipping", mShouldUseRoundedRectClipping);
+            println(pw, "qsClipDismiss", mDismissUsingRowTranslationX);
+            println(pw, "visibility", visibilityString(getVisibility()));
+            println(pw, "alpha", getAlpha());
+            println(pw, "scrollY", mAmbientState.getScrollY());
+            println(pw, "maxTopPadding", mMaxTopPadding);
+            println(pw, "showShelfOnly", mShouldShowShelfOnly);
+            println(pw, "qsExpandFraction", mQsExpansionFraction);
+            println(pw, "isCurrentUserSetup", mIsCurrentUserSetup);
+            println(pw, "hideAmount", mAmbientState.getHideAmount());
+            println(pw, "ambientStateSwipingUp", mAmbientState.isSwipingUp());
+            println(pw, "maxDisplayedNotifications", mMaxDisplayedNotifications);
+            println(pw, "intrinsicContentHeight", mIntrinsicContentHeight);
+            println(pw, "contentHeight", mContentHeight);
+            println(pw, "intrinsicPadding", mIntrinsicPadding);
+            println(pw, "topPadding", mTopPadding);
+            println(pw, "bottomPadding", mBottomPadding);
+        });
+        pw.println();
+        pw.println("Contents:");
         DumpUtilsKt.withIncreasedIndent(pw, () -> {
             int childCount = getChildCount();
             pw.println("Number of children: " + childCount);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 2493ccb..a0d940e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -68,6 +68,7 @@
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.KeyguardMediaController;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -156,6 +157,7 @@
     private final ConfigurationController mConfigurationController;
     private final ZenModeController mZenModeController;
     private final MetricsLogger mMetricsLogger;
+    private final DumpManager mDumpManager;
     private final FalsingCollector mFalsingCollector;
     private final FalsingManager mFalsingManager;
     private final Resources mResources;
@@ -635,6 +637,7 @@
             SysuiColorExtractor colorExtractor,
             NotificationLockscreenUserManager lockscreenUserManager,
             MetricsLogger metricsLogger,
+            DumpManager dumpManager,
             FalsingCollector falsingCollector,
             FalsingManager falsingManager,
             @Main Resources resources,
@@ -677,6 +680,7 @@
         mZenModeController = zenModeController;
         mLockscreenUserManager = lockscreenUserManager;
         mMetricsLogger = metricsLogger;
+        mDumpManager = dumpManager;
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
         mShadeTransitionController = shadeTransitionController;
         mFalsingCollector = falsingCollector;
@@ -728,6 +732,7 @@
             }
         });
         mView.setShadeController(mShadeController);
+        mDumpManager.registerDumpable(mView);
 
         mKeyguardBypassController.registerOnBypassStateChangedListener(
                 isEnabled -> mNotificationRoundnessManager.setShouldRoundPulsingViews(!isEnabled));
@@ -1190,6 +1195,10 @@
         mView.setUnlockHintRunning(running);
     }
 
+    public void setPanelFlinging(boolean flinging) {
+        mView.setPanelFlinging(flinging);
+    }
+
     public boolean isFooterViewNotGone() {
         return mView.isFooterViewNotGone();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt
index 04bf621..5f79c0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt
@@ -3,21 +3,27 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel.INFO
 import com.android.systemui.log.dagger.NotificationHeadsUpLog
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent.*
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.logKey
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_ADD
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_OTHER
 import javax.inject.Inject
 
 class NotificationStackScrollLogger @Inject constructor(
     @NotificationHeadsUpLog private val buffer: LogBuffer
 ) {
-    fun hunAnimationSkipped(key: String, reason: String) {
+    fun hunAnimationSkipped(entry: NotificationEntry, reason: String) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
             str2 = reason
         }, {
             "heads up animation skipped: key: $str1 reason: $str2"
         })
     }
-    fun hunAnimationEventAdded(key: String, type: Int) {
+    fun hunAnimationEventAdded(entry: NotificationEntry, type: Int) {
         val reason: String
         reason = if (type == ANIMATION_TYPE_HEADS_UP_DISAPPEAR) {
             "HEADS_UP_DISAPPEAR"
@@ -33,16 +39,16 @@
             type.toString()
         }
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
             str2 = reason
         }, {
             "heads up animation added: $str1 with type $str2"
         })
     }
 
-    fun hunSkippedForUnexpectedState(key: String, expected: Boolean, actual: Boolean) {
+    fun hunSkippedForUnexpectedState(entry: NotificationEntry, expected: Boolean, actual: Boolean) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
             bool1 = expected
             bool2 = actual
         }, {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt
index 77377af..cb4a088 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt
@@ -3,6 +3,7 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.LogLevel
 import com.android.systemui.log.dagger.NotificationHeadsUpLog
+import com.android.systemui.statusbar.notification.logKey
 import javax.inject.Inject
 
 class StackStateLogger @Inject constructor(
@@ -10,7 +11,7 @@
 ) {
     fun logHUNViewDisappearing(key: String) {
         buffer.log(TAG, LogLevel.INFO, {
-            str1 = key
+            str1 = logKey(key)
         }, {
             "Heads up view disappearing $str1 "
         })
@@ -18,7 +19,7 @@
 
     fun logHUNViewAppearing(key: String) {
         buffer.log(TAG, LogLevel.INFO, {
-            str1 = key
+            str1 = logKey(key)
         }, {
             "Heads up notification view appearing $str1 "
         })
@@ -26,7 +27,7 @@
 
     fun logHUNViewDisappearingWithRemoveEvent(key: String) {
         buffer.log(TAG, LogLevel.ERROR, {
-            str1 = key
+            str1 = logKey(key)
         }, {
             "Heads up view disappearing $str1 for ANIMATION_TYPE_REMOVE"
         })
@@ -34,7 +35,7 @@
 
     fun logHUNViewAppearingWithAddEvent(key: String) {
         buffer.log(TAG, LogLevel.ERROR, {
-            str1 = key
+            str1 = logKey(key)
         }, {
             "Heads up view disappearing $str1 for ANIMATION_TYPE_ADD"
         })
@@ -42,7 +43,7 @@
 
     fun disappearAnimationEnded(key: String) {
         buffer.log(TAG, LogLevel.INFO, {
-            str1 = key
+            str1 = logKey(key)
         }, {
             "Heads up notification disappear animation ended $str1 "
         })
@@ -50,7 +51,7 @@
 
     fun appearAnimationEnded(key: String) {
         buffer.log(TAG, LogLevel.INFO, {
-            str1 = key
+            str1 = logKey(key)
         }, {
             "Heads up notification appear animation ended $str1 "
         })
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index fc043b1..2c22bc6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -448,6 +448,8 @@
 
     void setBouncerShowing(boolean bouncerShowing);
 
+  void setBouncerShowingOverDream(boolean bouncerShowingOverDream);
+
     void collapseShade();
 
     int getWakefulnessState();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index ad59c1df..5181af7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -442,6 +442,7 @@
      */
     protected int mState; // TODO: remove this. Just use StatusBarStateController
     protected boolean mBouncerShowing;
+    private boolean mBouncerShowingOverDream;
 
     private final PhoneStatusBarPolicy mIconPolicy;
 
@@ -2353,15 +2354,7 @@
             pw.print  ("      ");
             mNotificationPanelViewController.dump(pw, args);
         }
-        pw.println("  mStackScroller: ");
-        if (mStackScroller != null) {
-            // Double indent until we rewrite the rest of this dump()
-            pw.increaseIndent();
-            pw.increaseIndent();
-            mStackScroller.dump(pw, args);
-            pw.decreaseIndent();
-            pw.decreaseIndent();
-        }
+        pw.println("  mStackScroller: " + mStackScroller + " (dump moved)");
         pw.println("  Theme:");
         String nightMode = mUiModeManager == null ? "null" : mUiModeManager.getNightMode() + "";
         pw.println("    dark theme: " + nightMode +
@@ -2516,6 +2509,12 @@
                     animate, intent.getPackage(), (adapter) -> {
                         ActivityOptions options = new ActivityOptions(
                                 CentralSurfaces.getActivityOptions(mDisplayId, adapter));
+
+                        // We know that the intent of the caller is to dismiss the keyguard and
+                        // this runnable is called right after the keyguard is solved, so we tell
+                        // WM that we should dismiss it to avoid flickers when opening an activity
+                        // that can also be shown over the keyguard.
+                        options.setDismissKeyguard();
                         options.setDisallowEnterPictureInPictureWhileLaunching(
                                 disallowEnterPictureInPictureWhileLaunching);
                         if (CameraIntents.isInsecureCameraIntent(intent)) {
@@ -3327,9 +3326,13 @@
 
     @Override
     public boolean onBackPressed() {
-        boolean isScrimmedBouncer = mScrimController.getState() == ScrimState.BOUNCER_SCRIMMED;
-        if (mStatusBarKeyguardViewManager.onBackPressed(isScrimmedBouncer /* hideImmediately */)) {
-            if (isScrimmedBouncer) {
+        final boolean isScrimmedBouncer =
+                mScrimController.getState() == ScrimState.BOUNCER_SCRIMMED;
+        final boolean isBouncerOverDream = isBouncerShowingOverDream();
+
+        if (mStatusBarKeyguardViewManager.onBackPressed(
+                isScrimmedBouncer || isBouncerOverDream /* hideImmediately */)) {
+            if (isScrimmedBouncer || isBouncerOverDream) {
                 mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
             } else {
                 mNotificationPanelViewController.expandWithoutQs();
@@ -3351,7 +3354,8 @@
         if (mNotificationPanelViewController.closeUserSwitcherIfOpen()) {
             return true;
         }
-        if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) {
+        if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED
+                && !isBouncerOverDream) {
             if (mNotificationPanelViewController.canPanelBeCollapsed()) {
                 mShadeController.animateCollapsePanels();
             }
@@ -3564,6 +3568,17 @@
     }
 
     /**
+     * Sets whether the bouncer over dream is showing. Note that the bouncer over dream is handled
+     * independently of the rest of the notification panel. As a result, setting this state via
+     * {@link #setBouncerShowing(boolean)} leads to unintended side effects from states modified
+     * behind the dream.
+     */
+    @Override
+    public void setBouncerShowingOverDream(boolean bouncerShowingOverDream) {
+        mBouncerShowingOverDream = bouncerShowingOverDream;
+    }
+  
+    /**
      * Propagate the bouncer state to status bar components.
      *
      * Separate from {@link #setBouncerShowing} because we sometimes re-create the status bar and
@@ -4207,7 +4222,7 @@
 
     @Override
     public boolean isBouncerShowingOverDream() {
-        return isBouncerShowing() && mDreamOverlayStateController.isOverlayActive();
+        return mBouncerShowingOverDream;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 414bc84..93b2e41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -28,17 +28,13 @@
 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.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.ColorStateList;
@@ -46,13 +42,8 @@
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.provider.MediaStore;
-import android.service.media.CameraPrewarmService;
 import android.service.quickaccesswallet.GetWalletCardsError;
 import android.service.quickaccesswallet.GetWalletCardsResponse;
 import android.service.quickaccesswallet.QuickAccessWalletClient;
@@ -172,20 +163,6 @@
     private KeyguardAffordanceHelper mAffordanceHelper;
     private FalsingManager mFalsingManager;
     private boolean mUserSetupComplete;
-    private boolean mPrewarmBound;
-    private Messenger mPrewarmMessenger;
-    private final ServiceConnection mPrewarmConnection = new ServiceConnection() {
-
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            mPrewarmMessenger = new Messenger(service);
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            mPrewarmMessenger = null;
-        }
-    };
 
     private boolean mLeftIsVoiceAssist;
     private Drawable mLeftAssistIcon;
@@ -602,46 +579,6 @@
         }
     }
 
-    public void bindCameraPrewarmService() {
-        Intent intent = getCameraIntent();
-        ActivityInfo targetInfo = mActivityIntentHelper.getTargetActivityInfo(intent,
-                KeyguardUpdateMonitor.getCurrentUser(), true /* onlyDirectBootAware */);
-        if (targetInfo != null && targetInfo.metaData != null) {
-            String clazz = targetInfo.metaData.getString(
-                    MediaStore.META_DATA_STILL_IMAGE_CAMERA_PREWARM_SERVICE);
-            if (clazz != null) {
-                Intent serviceIntent = new Intent();
-                serviceIntent.setClassName(targetInfo.packageName, clazz);
-                serviceIntent.setAction(CameraPrewarmService.ACTION_PREWARM);
-                try {
-                    if (getContext().bindServiceAsUser(serviceIntent, mPrewarmConnection,
-                            Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
-                            new UserHandle(UserHandle.USER_CURRENT))) {
-                        mPrewarmBound = true;
-                    }
-                } catch (SecurityException e) {
-                    Log.w(TAG, "Unable to bind to prewarm service package=" + targetInfo.packageName
-                            + " class=" + clazz, e);
-                }
-            }
-        }
-    }
-
-    public void unbindCameraPrewarmService(boolean launched) {
-        if (mPrewarmBound) {
-            if (mPrewarmMessenger != null && launched) {
-                try {
-                    mPrewarmMessenger.send(Message.obtain(null /* handler */,
-                            CameraPrewarmService.MSG_CAMERA_FIRED));
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Error sending camera fired message", e);
-                }
-            }
-            mContext.unbindService(mPrewarmConnection);
-            mPrewarmBound = false;
-        }
-    }
-
     public void launchCamera(String source) {
         final Intent intent = getCameraIntent();
         intent.putExtra(EXTRA_CAMERA_LAUNCH_SOURCE, source);
@@ -651,8 +588,6 @@
             AsyncTask.execute(new Runnable() {
                 @Override
                 public void run() {
-                    int result = ActivityManager.START_CANCELED;
-
                     // Normally an activity will set it's requested rotation
                     // animation on its window. However when launching an activity
                     // causes the orientation to change this is too late. In these cases
@@ -666,7 +601,7 @@
                     o.setRotationAnimationHint(
                             WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
                     try {
-                        result = ActivityTaskManager.getService().startActivityAsUser(
+                        ActivityTaskManager.getService().startActivityAsUser(
                                 null, getContext().getBasePackageName(),
                                 getContext().getAttributionTag(), intent,
                                 intent.resolveTypeIfNeeded(getContext().getContentResolver()),
@@ -675,25 +610,12 @@
                     } catch (RemoteException e) {
                         Log.w(TAG, "Unable to start camera activity", e);
                     }
-                    final boolean launched = isSuccessfulLaunch(result);
-                    post(new Runnable() {
-                        @Override
-                        public void run() {
-                            unbindCameraPrewarmService(launched);
-                        }
-                    });
                 }
             });
         } else {
             // We need to delay starting the activity because ResolverActivity finishes itself if
             // launched behind lockscreen.
-            mActivityStarter.startActivity(intent, false /* dismissShade */,
-                    new ActivityStarter.Callback() {
-                        @Override
-                        public void onActivityStarted(int resultCode) {
-                            unbindCameraPrewarmService(isSuccessfulLaunch(resultCode));
-                        }
-                    });
+            mActivityStarter.startActivity(intent, false /* dismissShade */);
         }
     }
 
@@ -705,12 +627,6 @@
         dozeTimeTick();
     }
 
-    private static boolean isSuccessfulLaunch(int result) {
-        return result == ActivityManager.START_SUCCESS
-                || result == ActivityManager.START_DELIVERED_TO_TOP
-                || result == ActivityManager.START_TASK_TO_FRONT;
-    }
-
     public void launchLeftAffordance() {
         if (mLeftIsVoiceAssist) {
             launchVoiceAssist();
@@ -1195,10 +1111,10 @@
         public void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response) {
             mHasCard = !response.getWalletCards().isEmpty();
             Drawable tileIcon = mQuickAccessWalletController.getWalletClient().getTileIcon();
+            if (tileIcon != null) {
+                mWalletButton.setImageDrawable(tileIcon);
+            }
             post(() -> {
-                if (tileIcon != null) {
-                    mWalletButton.setImageDrawable(tileIcon);
-                }
                 updateWalletVisibility();
                 updateAffordanceColors();
             });
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 629aa03..dde6b16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -309,9 +309,12 @@
      */
     private float getClockAlpha(int y) {
         float alphaKeyguard = Math.max(0, y / Math.max(1f, getClockY(1f, mDarkAmount)));
-        float qsAlphaFactor = MathUtils.saturate(mQsExpansion / 0.3f);
-        qsAlphaFactor = 1f - qsAlphaFactor;
-        alphaKeyguard *= qsAlphaFactor;
+        if (!mIsSplitShade) {
+            // in split shade QS are always expanded so this factor shouldn't apply
+            float qsAlphaFactor = MathUtils.saturate(mQsExpansion / 0.3f);
+            qsAlphaFactor = 1f - qsAlphaFactor;
+            alphaKeyguard *= qsAlphaFactor;
+        }
         alphaKeyguard = Interpolators.ACCELERATE.getInterpolation(alphaKeyguard);
         return MathUtils.lerp(alphaKeyguard, 1f, mDarkAmount);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt
index 178c17d..84c8700 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone
 
 import android.app.StatusBarManager
+import android.content.res.Configuration
 import android.view.View
 import android.widget.TextView
 import androidx.constraintlayout.motion.widget.MotionLayout
@@ -204,6 +205,12 @@
 
     private fun bindConfigurationListener() {
         val listener = object : ConfigurationController.ConfigurationListener {
+            override fun onConfigChanged(newConfig: Configuration?) {
+                val left = header.resources.getDimensionPixelSize(
+                    R.dimen.large_screen_shade_header_left_padding)
+                header.setPadding(
+                    left, header.paddingTop, header.paddingRight, header.paddingBottom)
+            }
             override fun onDensityOrFontScaleChanged() {
                 val qsStatusStyle = R.style.TextAppearance_QS_Status
                 FontSizeUtils.updateFontSizeFromStyle(clock, qsStatusStyle)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 2cac001..fbbb587 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -32,6 +32,7 @@
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
+import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
 import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FOLD_TO_AOD;
 import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_CLOSED;
@@ -646,6 +647,7 @@
     private int mScrimCornerRadius;
     private int mScreenCornerRadius;
     private boolean mQSAnimatingHiddenFromCollapsed;
+    private boolean mUseLargeScreenShadeHeader;
 
     private int mQsClipTop;
     private int mQsClipBottom;
@@ -664,6 +666,9 @@
     private Optional<NotificationPanelUnfoldAnimationController>
             mNotificationPanelUnfoldAnimationController;
 
+    /** The drag distance required to fully expand the split shade. */
+    private int mSplitShadeFullTransitionDistance;
+
     private final NotificationListContainer mNotificationListContainer;
     private final NotificationStackSizeCalculator mNotificationStackSizeCalculator;
 
@@ -1139,18 +1144,20 @@
         final boolean splitShadeChanged = mSplitShadeEnabled != newSplitShadeEnabled;
         mSplitShadeEnabled = newSplitShadeEnabled;
 
-        boolean useLargeScreenShadeHeader =
-                LargeScreenUtils.shouldUseLargeScreenShadeHeader(mView.getResources());
         if (mQs != null) {
             mQs.setInSplitShade(mSplitShadeEnabled);
         }
+
+        mUseLargeScreenShadeHeader =
+                LargeScreenUtils.shouldUseLargeScreenShadeHeader(mView.getResources());
+
         mLargeScreenShadeHeaderHeight =
                 mResources.getDimensionPixelSize(R.dimen.large_screen_shade_header_height);
-        mQuickQsHeaderHeight = useLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight :
+        mQuickQsHeaderHeight = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight :
                 SystemBarUtils.getQuickQsOffsetHeight(mView.getContext());
-        int topMargin = useLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight :
+        int topMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight :
                 mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_top);
-        mLargeScreenShadeHeaderController.setActive(useLargeScreenShadeHeader);
+        mLargeScreenShadeHeaderController.setActive(mUseLargeScreenShadeHeader);
         mAmbientState.setStackTopMargin(topMargin);
         mNotificationsQSContainerController.updateResources();
 
@@ -1159,15 +1166,31 @@
         mKeyguardMediaController.refreshMediaPosition();
 
         if (splitShadeChanged) {
-            // when we switch from split shade to regular shade we want to enforce setting qs to
-            // the default state: expanded for split shade and collapsed otherwise
-            if (!isOnKeyguard() && mPanelExpanded) {
-                setQsExpanded(mSplitShadeEnabled);
-            }
-            updateClockAppearance();
-            updateQsState();
-            mNotificationStackScrollLayoutController.updateFooter();
+            onSplitShadeEnabledChanged();
         }
+
+        mSplitShadeFullTransitionDistance =
+                mResources.getDimensionPixelSize(R.dimen.split_shade_full_transition_distance);
+    }
+
+    private void onSplitShadeEnabledChanged() {
+        // when we switch between split shade and regular shade we want to enforce setting qs to
+        // the default state: expanded for split shade and collapsed otherwise
+        if (!isOnKeyguard() && mPanelExpanded) {
+            setQsExpanded(mSplitShadeEnabled);
+        }
+        if (isOnKeyguard() && mQsExpanded && mSplitShadeEnabled) {
+            // In single column keyguard - when you swipe from the top - QS is fully expanded and
+            // StatusBarState is KEYGUARD. That state doesn't make sense for split shade,
+            // where notifications are always visible and we effectively go to fully expanded
+            // shade, that is SHADE_LOCKED.
+            // Also we might just be switching from regular expanded shade, so we don't want
+            // to force state transition if it's already correct.
+            mStatusBarStateController.setState(StatusBarState.SHADE_LOCKED, /* force= */false);
+        }
+        updateClockAppearance();
+        updateQsState();
+        mNotificationStackScrollLayoutController.updateFooter();
     }
 
     private View reInflateStub(int viewId, int stubId, int layoutId, boolean enabled) {
@@ -1647,7 +1670,6 @@
         setQsExpansionEnabled();
     }
 
-    @Override
     public void resetViews(boolean animate) {
         mIsLaunchTransitionFinished = false;
         mBlockTouches = false;
@@ -1782,14 +1804,14 @@
         mHeadsUpTouchHelper.notifyFling(!expand);
         mKeyguardStateController.notifyPanelFlingStart(!expand /* flingingToDismiss */);
         setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f);
-        mAmbientState.setIsFlinging(true);
+        mNotificationStackScrollLayoutController.setPanelFlinging(true);
         super.flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing);
     }
 
     @Override
     protected void onFlingEnd(boolean cancelled) {
         super.onFlingEnd(cancelled);
-        mAmbientState.setIsFlinging(false);
+        mNotificationStackScrollLayoutController.setPanelFlinging(false);
     }
 
     private boolean onQsIntercept(MotionEvent event) {
@@ -2463,8 +2485,8 @@
     }
 
     /**
-     * Updates scrim bounds, QS clipping, and KSV clipping as well based on the bounds of the shade
-     * and QS state.
+     * Updates scrim bounds, QS clipping, notifications clipping and keyguard status view clipping
+     * as well based on the bounds of the shade and QS state.
      */
     private void setQSClippingBounds() {
         final int qsPanelBottomY = calculateQsBottomPosition(computeQsExpansionFraction());
@@ -2540,6 +2562,13 @@
         }
     }
 
+    /**
+     * Applies clipping to quick settings, notifications layout and
+     * updates bounds of the notifications background (notifications scrim).
+     *
+     * The parameters are bounds of the notifications area rectangle, this function
+     * calculates bounds for the QS clipping based on the notifications bounds.
+     */
     private void applyQSClippingBounds(int left, int top, int right, int bottom,
             boolean qsVisible) {
         if (!mAnimateNextNotificationBounds || mKeyguardStatusAreaClipBounds.isEmpty()) {
@@ -2675,12 +2704,10 @@
         if (mTransitioningToFullShadeProgress > 0.0f) {
             return mTransitionToFullShadeQSPosition;
         } else {
-            int qsBottomY = (int) getHeaderTranslation() + mQs.getQsMinExpansionHeight();
-            if (qsExpansionFraction != 0.0) {
-                qsBottomY = (int) MathUtils.lerp(
-                        qsBottomY, mQs.getDesiredHeight(), qsExpansionFraction);
-            }
-            return qsBottomY;
+            int qsBottomYFrom = (int) getHeaderTranslation() + mQs.getQsMinExpansionHeight();
+            int expandedTopMargin = mUseLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight : 0;
+            int qsBottomYTo = mQs.getDesiredHeight() + expandedTopMargin;
+            return (int) MathUtils.lerp(qsBottomYFrom, qsBottomYTo, qsExpansionFraction);
         }
     }
 
@@ -2699,8 +2726,8 @@
     }
 
     private float calculateNotificationsTopPadding() {
-        if (mSplitShadeEnabled && !mKeyguardShowing) {
-            return 0;
+        if (mSplitShadeEnabled) {
+            return mKeyguardShowing ? getKeyguardNotificationStaticPadding() : 0;
         }
         if (mKeyguardShowing && (mQsExpandImmediate
                 || mIsExpanding && mQsExpandedWhenExpandingStarted)) {
@@ -2774,6 +2801,9 @@
             mIsQsTranslationResetAnimator = mQsTranslationForFullShadeTransition > 0.0f;
         }
 
+        if (mSplitShadeEnabled) {
+            updateQsExpansionForLockscreenToShadeTransition(pxAmount);
+        }
         float endPosition = 0;
         if (pxAmount > 0.0f) {
             if (mNotificationStackScrollLayoutController.getVisibleNotificationCount() == 0
@@ -2813,6 +2843,18 @@
         updateQsExpansion();
     }
 
+    private void updateQsExpansionForLockscreenToShadeTransition(float pxAmount) {
+        float qsExpansion = 0;
+        if (pxAmount > 0.0f) {
+            qsExpansion = MathUtils.lerp(mQsMinExpansionHeight, mQsMaxExpansionHeight,
+                    mLockscreenShadeTransitionController.getQSDragProgress());
+        }
+        // SHADE_LOCKED means transition is over and we don't want further updates
+        if (mBarState != SHADE_LOCKED) {
+            setQsExpansion(qsExpansion);
+        }
+    }
+
     /**
      * Notify the panel that the pulse expansion has finished and that we're going to the full
      * shade
@@ -3016,8 +3058,17 @@
         }
         int maxHeight;
         if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted
-                || mPulsing) {
-            maxHeight = calculatePanelHeightQsExpanded();
+                || mPulsing || mSplitShadeEnabled) {
+            if (mSplitShadeEnabled && mBarState == SHADE) {
+                // Max panel height is used to calculate the fraction of the shade expansion.
+                // Traditionally the value is based on the number of notifications.
+                // On split-shade, we want the required distance to be a specific and constant
+                // value, to make sure the expansion motion has the expected speed.
+                // We also only want this on non-lockscreen for now.
+                maxHeight = mSplitShadeFullTransitionDistance;
+            } else {
+                maxHeight = calculatePanelHeightQsExpanded();
+            }
         } else {
             maxHeight = calculatePanelHeightShade();
         }
@@ -4540,13 +4591,6 @@
         @Override
         public void onSwipingStarted(boolean rightIcon) {
             mFalsingCollector.onAffordanceSwipingStarted(rightIcon);
-            boolean
-                    camera =
-                    mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? !rightIcon
-                            : rightIcon;
-            if (camera) {
-                mKeyguardBottomArea.bindCameraPrewarmService();
-            }
             mView.requestDisallowInterceptTouchEvent(true);
             mOnlyAffordanceInThisMotion = true;
             mQsTracking = false;
@@ -4555,7 +4599,6 @@
         @Override
         public void onSwipingAborted() {
             mFalsingCollector.onAffordanceSwipingAborted();
-            mKeyguardBottomArea.unbindCameraPrewarmService(false /* launched */);
         }
 
         @Override
@@ -4772,11 +4815,6 @@
                     duration = StackStateAnimator.ANIMATION_DURATION_STANDARD;
                 }
                 mKeyguardStatusBarViewController.animateKeyguardStatusBarOut(startDelay, duration);
-                if (mSplitShadeEnabled) {
-                    // temporary workaround for QS height not being updated during lockscreen to
-                    // shade transition
-                    setQsExpanded(true);
-                }
                 updateQSMinHeight();
             } else if (oldState == StatusBarState.SHADE_LOCKED
                     && statusBarState == KEYGUARD) {
@@ -5047,7 +5085,8 @@
             mDebugPaint.setColor(color);
             canvas.drawLine(/* startX= */ 0, /* startY= */ y, /* stopX= */ mView.getWidth(),
                     /* stopY= */ y, mDebugPaint);
-            canvas.drawText(label, /* x= */ 0, /* y= */ computeDebugYTextPosition(y), mDebugPaint);
+            canvas.drawText(label + " = " + y + "px", /* x= */ 0,
+                    /* y= */ computeDebugYTextPosition(y), mDebugPaint);
         }
 
         private int computeDebugYTextPosition(int lineY) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index faae4bb..a8da554 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -502,7 +502,8 @@
             cb.onStateChanged(mCurrentState.mKeyguardShowing,
                     mCurrentState.mKeyguardOccluded,
                     mCurrentState.mBouncerShowing,
-                    mCurrentState.mDozing);
+                    mCurrentState.mDozing,
+                    mCurrentState.mPanelExpanded);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS
new file mode 100644
index 0000000..f5828f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS
@@ -0,0 +1,16 @@
+per-file *Notification* = set noparent
+per-file *Notification* = file:../notification/OWNERS
+
+per-file NotificationIcon* = ccassidy@google.com, evanlaird@google.com, pixel@google.com
+
+per-file NotificationsQuickSettingsContainer.java = kozynski@google.com, asc@google.com
+per-file NotificationsQSContainerController.kt = kozynski@google.com, asc@google.com
+
+per-file NotificationShadeWindowControllerImpl.java = dupin@google.com, cinek@google.com, beverlyt@google.com, pixel@google.com, juliacr@google.com
+per-file NotificationShadeWindowViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com
+per-file NotificationShadeWindowView.java = pixel@google.com, cinek@google.com, juliacr@google.com
+
+per-file NotificationPanelUnfoldAnimationController.kt = alexflo@google.com, jeffdq@google.com, juliacr@google.com
+
+per-file NotificationPanelView.java = pixel@google.com, cinek@google.com, juliacr@google.com
+per-file NotificationPanelViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 82ca842..ed12b00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -430,6 +430,8 @@
                     // situations, such keeping your finger down while swiping to unlock to an app
                     // that is locked in landscape (the rotation will cancel the touch event).
                     expand = false;
+                } else if (mCentralSurfaces.isBouncerShowingOverDream()) {
+                    expand = false;
                 } else {
                     // If we get a cancel, put the shade back to the state it was in when the
                     // gesture started
@@ -806,6 +808,7 @@
             mExpansionDragDownAmountPx = h;
             mExpandedFraction = Math.min(1f,
                     maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
+            mAmbientState.setExpansionFraction(mExpandedFraction);
             onHeightUpdated(mExpandedHeight);
             updatePanelExpansionAndVisibility();
         });
@@ -1160,8 +1163,6 @@
                 mTouchDisabled ? "T" : "f"));
     }
 
-    public abstract void resetViews(boolean animate);
-
     public void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
         mHeadsUpManager = headsUpManager;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 5e7dc11..0cf9a53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -55,7 +55,6 @@
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.scrim.ScrimView;
 import com.android.systemui.statusbar.notification.stack.ViewState;
-import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.AlarmTimeout;
@@ -265,7 +264,6 @@
             KeyguardUpdateMonitor keyguardUpdateMonitor, DockManager dockManager,
             ConfigurationController configurationController, @Main Executor mainExecutor,
             ScreenOffAnimationController screenOffAnimationController,
-            PanelExpansionStateManager panelExpansionStateManager,
             KeyguardUnlockAnimationController keyguardUnlockAnimationController,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
         mScrimStateListener = lightBarController::setScrimState;
@@ -305,10 +303,6 @@
                 ScrimController.this.onThemeChanged();
             }
         });
-        panelExpansionStateManager.addExpansionListener(
-                event -> setRawPanelExpansionFraction(event.getFraction())
-        );
-
         mColors = new GradientColors();
     }
 
@@ -553,13 +547,12 @@
      *
      * The expansion fraction is tied to the scrim opacity.
      *
-     * See {@link PanelExpansionListener#onPanelExpansionChanged}.
+     * See {@link ScrimShadeTransitionController#onPanelExpansionChanged}.
      *
      * @param rawPanelExpansionFraction From 0 to 1 where 0 means collapsed and 1 expanded.
      */
-     @VisibleForTesting
-     void setRawPanelExpansionFraction(
-            @FloatRange(from = 0.0, to = 1.0) float rawPanelExpansionFraction) {
+    public void setRawPanelExpansionFraction(
+             @FloatRange(from = 0.0, to = 1.0) float rawPanelExpansionFraction) {
         if (isNaN(rawPanelExpansionFraction)) {
             throw new IllegalArgumentException("rawPanelExpansionFraction should not be NaN");
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 97439b8..b6c960a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -163,6 +163,10 @@
 
         @Override
         public void onVisibilityChanged(boolean isVisible) {
+            mCentralSurfaces
+                    .setBouncerShowingOverDream(
+                            isVisible && mDreamOverlayStateController.isOverlayActive());
+
             if (!isVisible) {
                 mCentralSurfaces.setBouncerHiddenFraction(KeyguardBouncer.EXPANSION_HIDDEN);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
index ac43b67..ae48c2d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
@@ -17,5 +17,5 @@
 
 public interface StatusBarWindowCallback {
     void onStateChanged(boolean keyguardShowing, boolean keyguardOccluded, boolean bouncerShowing,
-            boolean isDozing);
+            boolean isDozing, boolean panelExpanded);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 36a0456..26bc3e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -93,6 +93,17 @@
     }
 
     public SystemUIDialog(Context context, int theme, boolean dismissOnDeviceLock) {
+        // TODO(b/219008720): Remove those calls to Dependency.get by introducing a
+        // SystemUIDialogFactory and make all other dialogs create a SystemUIDialog to which we set
+        // the content and attach listeners.
+        this(context, theme, dismissOnDeviceLock, Dependency.get(SystemUIDialogManager.class),
+                Dependency.get(SysUiState.class), Dependency.get(BroadcastDispatcher.class),
+                Dependency.get(DialogLaunchAnimator.class));
+    }
+
+    public SystemUIDialog(Context context, int theme, boolean dismissOnDeviceLock,
+            SystemUIDialogManager dialogManager, SysUiState sysUiState,
+            BroadcastDispatcher broadcastDispatcher, DialogLaunchAnimator dialogLaunchAnimator) {
         super(context, theme);
         mContext = context;
 
@@ -101,13 +112,10 @@
         attrs.setTitle(getClass().getSimpleName());
         getWindow().setAttributes(attrs);
 
-        mDismissReceiver = dismissOnDeviceLock ? new DismissReceiver(this) : null;
-
-        // TODO(b/219008720): Remove those calls to Dependency.get by introducing a
-        // SystemUIDialogFactory and make all other dialogs create a SystemUIDialog to which we set
-        // the content and attach listeners.
-        mDialogManager = Dependency.get(SystemUIDialogManager.class);
-        mSysUiState = Dependency.get(SysUiState.class);
+        mDismissReceiver = dismissOnDeviceLock ? new DismissReceiver(this, broadcastDispatcher,
+                dialogLaunchAnimator) : null;
+        mDialogManager = dialogManager;
+        mSysUiState = sysUiState;
     }
 
     @Override
@@ -326,7 +334,10 @@
      * @param dismissAction An action to run when the dialog is dismissed.
      */
     public static void registerDismissListener(Dialog dialog, @Nullable Runnable dismissAction) {
-        DismissReceiver dismissReceiver = new DismissReceiver(dialog);
+        // TODO(b/219008720): Remove those calls to Dependency.get.
+        DismissReceiver dismissReceiver = new DismissReceiver(dialog,
+                Dependency.get(BroadcastDispatcher.class),
+                Dependency.get(DialogLaunchAnimator.class));
         dialog.setOnDismissListener(d -> {
             dismissReceiver.unregister();
             if (dismissAction != null) dismissAction.run();
@@ -408,11 +419,11 @@
         private final BroadcastDispatcher mBroadcastDispatcher;
         private final DialogLaunchAnimator mDialogLaunchAnimator;
 
-        DismissReceiver(Dialog dialog) {
+        DismissReceiver(Dialog dialog, BroadcastDispatcher broadcastDispatcher,
+                DialogLaunchAnimator dialogLaunchAnimator) {
             mDialog = dialog;
-            // TODO(b/219008720): Remove those calls to Dependency.get.
-            mBroadcastDispatcher = Dependency.get(BroadcastDispatcher.class);
-            mDialogLaunchAnimator = Dependency.get(DialogLaunchAnimator.class);
+            mBroadcastDispatcher = broadcastDispatcher;
+            mDialogLaunchAnimator = dialogLaunchAnimator;
         }
 
         void register() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionChangeEvent.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionChangeEvent.kt
index c0384b4..7c61b29 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionChangeEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionChangeEvent.kt
@@ -1,3 +1,18 @@
+/*
+ * 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.systemui.statusbar.phone.panelstate
 
 import android.annotation.FloatRange
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt
new file mode 100644
index 0000000..16f28e7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionController.kt
@@ -0,0 +1,86 @@
+package com.android.systemui.statusbar.phone.shade.transition
+
+import android.content.res.Configuration
+import android.content.res.Resources
+import android.util.MathUtils.constrain
+import com.android.systemui.R
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.phone.ScrimController
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.LargeScreenUtils
+import java.io.PrintWriter
+import javax.inject.Inject
+
+/** Controls the scrim properties during the shade expansion transition on non-lockscreen. */
+@SysUISingleton
+class ScrimShadeTransitionController
+@Inject
+constructor(
+    configurationController: ConfigurationController,
+    dumpManager: DumpManager,
+    private val scrimController: ScrimController,
+    @Main private val resources: Resources,
+    private val statusBarStateController: SysuiStatusBarStateController,
+) {
+
+    private var inSplitShade = false
+    private var splitShadeScrimTransitionDistance = 0
+    private var lastExpansionFraction: Float = 0f
+    private var lastExpansionEvent: PanelExpansionChangeEvent? = null
+
+    init {
+        updateResources()
+        configurationController.addCallback(
+            object : ConfigurationController.ConfigurationListener {
+                override fun onConfigChanged(newConfig: Configuration?) {
+                    updateResources()
+                }
+            })
+        dumpManager
+            .registerDumpable(ScrimShadeTransitionController::class.java.simpleName, this::dump)
+    }
+
+    private fun updateResources() {
+        inSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(resources)
+        splitShadeScrimTransitionDistance =
+            resources.getDimensionPixelSize(R.dimen.split_shade_scrim_transition_distance)
+    }
+
+    fun onPanelExpansionChanged(panelExpansionChangeEvent: PanelExpansionChangeEvent) {
+        val expansionFraction = calculateScrimExpansionFraction(panelExpansionChangeEvent)
+        scrimController.setRawPanelExpansionFraction(expansionFraction)
+        lastExpansionFraction = expansionFraction
+        lastExpansionEvent = panelExpansionChangeEvent
+    }
+
+    private fun calculateScrimExpansionFraction(expansionEvent: PanelExpansionChangeEvent): Float {
+        return if (inSplitShade && isScreenUnlocked()) {
+            constrain(expansionEvent.dragDownPxAmount / splitShadeScrimTransitionDistance, 0f, 1f)
+        } else {
+            expansionEvent.fraction
+        }
+    }
+
+    private fun isScreenUnlocked() =
+        statusBarStateController.currentOrUpcomingState == StatusBarState.SHADE
+
+    private fun dump(printWriter: PrintWriter, args: Array<String>) {
+        printWriter.println(
+            """
+                ScrimShadeTransitionController:
+                  Resources:
+                    inSplitShade: $inSplitShade
+                    isScreenUnlocked: ${isScreenUnlocked()}
+                    splitShadeScrimTransitionDistance: $splitShadeScrimTransitionDistance
+                  State:
+                    lastExpansionFraction: $lastExpansionFraction
+                    lastExpansionEvent: $lastExpansionEvent
+            """.trimIndent()
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt
index 2762b9a..e967d4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionController.kt
@@ -4,6 +4,7 @@
 import android.content.res.Configuration
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.qs.QS
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.phone.NotificationPanelViewController
@@ -11,6 +12,7 @@
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
 import com.android.systemui.statusbar.phone.panelstate.PanelState
 import com.android.systemui.statusbar.policy.ConfigurationController
+import java.io.PrintWriter
 import javax.inject.Inject
 
 /** Controls the shade expansion transition on non-lockscreen. */
@@ -20,9 +22,11 @@
 constructor(
     configurationController: ConfigurationController,
     panelExpansionStateManager: PanelExpansionStateManager,
+    dumpManager: DumpManager,
     private val context: Context,
     private val splitShadeOverScrollerFactory: SplitShadeOverScroller.Factory,
-    private val noOpOverScroller: NoOpOverScroller
+    private val noOpOverScroller: NoOpOverScroller,
+    private val scrimShadeTransitionController: ScrimShadeTransitionController
 ) {
 
     lateinit var notificationPanelViewController: NotificationPanelViewController
@@ -32,7 +36,7 @@
     private var inSplitShade = false
 
     private val splitShadeOverScroller by lazy {
-        splitShadeOverScrollerFactory.create(qs, notificationStackScrollLayoutController)
+        splitShadeOverScrollerFactory.create({ qs }, { notificationStackScrollLayoutController })
     }
     private val shadeOverScroller: ShadeOverScroller
         get() =
@@ -52,6 +56,9 @@
             })
         panelExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged)
         panelExpansionStateManager.addStateListener(this::onPanelStateChanged)
+        dumpManager.registerDumpable("ShadeTransitionController") { printWriter, _ ->
+            dump(printWriter)
+        }
     }
 
     private fun updateResources() {
@@ -64,10 +71,22 @@
 
     private fun onPanelExpansionChanged(event: PanelExpansionChangeEvent) {
         shadeOverScroller.onDragDownAmountChanged(event.dragDownPxAmount)
+        scrimShadeTransitionController.onPanelExpansionChanged(event)
     }
 
     private fun propertiesInitialized() =
         this::qs.isInitialized &&
             this::notificationPanelViewController.isInitialized &&
             this::notificationStackScrollLayoutController.isInitialized
+
+    private fun dump(pw: PrintWriter) {
+        pw.println(
+            """
+            ShadeTransitionController:
+                inSplitShade: $inSplitShade
+                qs.isInitialized: ${this::qs.isInitialized}
+                npvc.isInitialized: ${this::notificationPanelViewController.isInitialized}
+                nssl.isInitialized: ${this::notificationStackScrollLayoutController.isInitialized}
+            """.trimIndent())
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScroller.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScroller.kt
index 71050f2..c25aab8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScroller.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScroller.kt
@@ -28,8 +28,8 @@
     dumpManager: DumpManager,
     private val context: Context,
     private val scrimController: ScrimController,
-    @Assisted private val qS: QS,
-    @Assisted private val nsslController: NotificationStackScrollLayoutController
+    @Assisted private val qSProvider: () -> QS,
+    @Assisted private val nsslControllerProvider: () -> NotificationStackScrollLayoutController
 ) : ShadeOverScroller {
 
     private var releaseOverScrollDuration = 0L
@@ -39,6 +39,12 @@
     @PanelState private var panelState: Int = STATE_CLOSED
     private var releaseOverScrollAnimator: Animator? = null
 
+    private val qS: QS
+        get() = qSProvider()
+
+    private val nsslController: NotificationStackScrollLayoutController
+        get() = nsslControllerProvider()
+
     init {
         updateResources()
         configurationController.addCallback(
@@ -47,7 +53,9 @@
                     updateResources()
                 }
             })
-        dumpManager.registerDumpable(this::dump)
+        dumpManager.registerDumpable("SplitShadeOverScroller") { printWriter, _ ->
+            dump(printWriter)
+        }
     }
 
     private fun updateResources() {
@@ -118,7 +126,7 @@
         releaseOverScrollAnimator = null
     }
 
-    private fun dump(pw: PrintWriter, strings: Array<String>) {
+    private fun dump(pw: PrintWriter) {
         pw.println(
             """
             SplitShadeOverScroller:
@@ -135,8 +143,8 @@
     @AssistedFactory
     fun interface Factory {
         fun create(
-            qS: QS,
-            nsslController: NotificationStackScrollLayoutController
+            qSProvider: () -> QS,
+            nsslControllerProvider: () -> NotificationStackScrollLayoutController
         ): SplitShadeOverScroller
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index a89c128..753e940 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -119,6 +119,17 @@
     }
 
     /**
+     * Returns {@code true} if the charging source is
+     * {@link android.os.BatteryManager#BATTERY_PLUGGED_DOCK}.
+     *
+     * <P>Note that charging from dock is not considered as wireless charging. In other words,
+     * {@link BatteryController#isWirelessCharging()} and this are mutually exclusive.
+     */
+    default boolean isChargingSourceDock() {
+        return false;
+    }
+
+    /**
      * A listener that will be notified whenever a change in battery level or power save mode has
      * occurred.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 917a5e0..33ddf7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -76,7 +76,7 @@
 
     protected int mLevel;
     protected boolean mPluggedIn;
-    private boolean mPluggedInWireless;
+    private int mPluggedChargingSource;
     protected boolean mCharging;
     private boolean mStateUnknown = false;
     private boolean mCharged;
@@ -195,10 +195,8 @@
             mLevel = (int)(100f
                     * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
                     / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
-            mPluggedIn = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
-            mPluggedInWireless = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0)
-                    == BatteryManager.BATTERY_PLUGGED_WIRELESS;
-
+            mPluggedChargingSource = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+            mPluggedIn = mPluggedChargingSource != 0;
             final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
                     BatteryManager.BATTERY_STATUS_UNKNOWN);
             mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
@@ -284,7 +282,7 @@
 
     @Override
     public boolean isPluggedInWireless() {
-        return mPluggedInWireless;
+        return mPluggedChargingSource == BatteryManager.BATTERY_PLUGGED_WIRELESS;
     }
 
     @Override
@@ -441,4 +439,9 @@
         registerReceiver();
         updatePowerSave();
     }
+
+    @Override
+    public boolean isChargingSourceDock() {
+        return mPluggedChargingSource == BatteryManager.BATTERY_PLUGGED_DOCK;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
index 4cf1d2b..9946b4b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
@@ -17,15 +17,11 @@
 package com.android.systemui.statusbar.policy;
 
 import android.annotation.WorkerThread;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.hardware.camera2.CameraAccessException;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraManager;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Process;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
 import android.text.TextUtils;
@@ -33,12 +29,19 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.internal.annotations.GuardedBy;
+import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.util.settings.SecureSettings;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.inject.Inject;
 
@@ -59,65 +62,88 @@
         "com.android.settings.flashlight.action.FLASHLIGHT_CHANGED";
 
     private final CameraManager mCameraManager;
-    private final Context mContext;
-    /** Call {@link #ensureHandler()} before using */
-    private Handler mHandler;
+    private final Executor mExecutor;
+    private final SecureSettings mSecureSettings;
+    private final DumpManager mDumpManager;
+    private final BroadcastSender mBroadcastSender;
 
-    /** Lock on mListeners when accessing */
+    private final boolean mHasFlashlight;
+
+    @GuardedBy("mListeners")
     private final ArrayList<WeakReference<FlashlightListener>> mListeners = new ArrayList<>(1);
 
-    /** Lock on {@code this} when accessing */
+    @GuardedBy("this")
     private boolean mFlashlightEnabled;
-
-    private String mCameraId;
+    @GuardedBy("this")
     private boolean mTorchAvailable;
 
-    @Inject
-    public FlashlightControllerImpl(Context context, DumpManager dumpManager) {
-        mContext = context;
-        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
+    private final AtomicReference<String> mCameraId;
+    private final AtomicBoolean mInitted = new AtomicBoolean(false);
 
-        dumpManager.registerDumpable(getClass().getSimpleName(), this);
-        tryInitCamera();
+    @Inject
+    public FlashlightControllerImpl(
+            DumpManager dumpManager,
+            CameraManager cameraManager,
+            @Background Executor bgExecutor,
+            SecureSettings secureSettings,
+            BroadcastSender broadcastSender,
+            PackageManager packageManager
+    ) {
+        mCameraManager = cameraManager;
+        mExecutor = bgExecutor;
+        mCameraId = new AtomicReference<>(null);
+        mSecureSettings = secureSettings;
+        mDumpManager = dumpManager;
+        mBroadcastSender = broadcastSender;
+
+        mHasFlashlight = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
+        init();
     }
 
+    private void init() {
+        if (!mInitted.getAndSet(true)) {
+            mDumpManager.registerDumpable(getClass().getSimpleName(), this);
+            mExecutor.execute(this::tryInitCamera);
+        }
+    }
+
+    @WorkerThread
     private void tryInitCamera() {
+        if (!mHasFlashlight || mCameraId.get() != null) return;
         try {
-            mCameraId = getCameraId();
+            mCameraId.set(getCameraId());
         } catch (Throwable e) {
             Log.e(TAG, "Couldn't initialize.", e);
             return;
         }
 
-        if (mCameraId != null) {
-            ensureHandler();
-            mCameraManager.registerTorchCallback(mTorchCallback, mHandler);
+        if (mCameraId.get() != null) {
+            mCameraManager.registerTorchCallback(mExecutor, mTorchCallback);
         }
     }
 
     public void setFlashlight(boolean enabled) {
-        boolean pendingError = false;
-        synchronized (this) {
-            if (mCameraId == null) return;
-            if (mFlashlightEnabled != enabled) {
-                mFlashlightEnabled = enabled;
-                try {
-                    mCameraManager.setTorchMode(mCameraId, enabled);
-                } catch (CameraAccessException e) {
-                    Log.e(TAG, "Couldn't set torch mode", e);
-                    mFlashlightEnabled = false;
-                    pendingError = true;
+        if (!mHasFlashlight) return;
+        if (mCameraId.get() == null) {
+            mExecutor.execute(this::tryInitCamera);
+        }
+        mExecutor.execute(() -> {
+            if (mCameraId.get() == null) return;
+            synchronized (this) {
+                if (mFlashlightEnabled != enabled) {
+                    try {
+                        mCameraManager.setTorchMode(mCameraId.get(), enabled);
+                    } catch (CameraAccessException e) {
+                        Log.e(TAG, "Couldn't set torch mode", e);
+                        dispatchError();
+                    }
                 }
             }
-        }
-        dispatchModeChanged(mFlashlightEnabled);
-        if (pendingError) {
-            dispatchError();
-        }
+        });
     }
 
     public boolean hasFlashlight() {
-        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
+        return mHasFlashlight;
     }
 
     public synchronized boolean isEnabled() {
@@ -131,13 +157,13 @@
     @Override
     public void addCallback(@NonNull FlashlightListener l) {
         synchronized (mListeners) {
-            if (mCameraId == null) {
-                tryInitCamera();
+            if (mCameraId.get() == null) {
+                mExecutor.execute(this::tryInitCamera);
             }
             cleanUpListenersLocked(l);
             mListeners.add(new WeakReference<>(l));
-            l.onFlashlightAvailabilityChanged(mTorchAvailable);
-            l.onFlashlightChanged(mFlashlightEnabled);
+            l.onFlashlightAvailabilityChanged(isAvailable());
+            l.onFlashlightChanged(isEnabled());
         }
     }
 
@@ -148,14 +174,7 @@
         }
     }
 
-    private synchronized void ensureHandler() {
-        if (mHandler == null) {
-            HandlerThread thread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
-            thread.start();
-            mHandler = new Handler(thread.getLooper());
-        }
-    }
-
+    @WorkerThread
     private String getCameraId() throws CameraAccessException {
         String[] ids = mCameraManager.getCameraIdList();
         for (String id : ids) {
@@ -221,10 +240,9 @@
         @Override
         @WorkerThread
         public void onTorchModeUnavailable(String cameraId) {
-            if (TextUtils.equals(cameraId, mCameraId)) {
+            if (TextUtils.equals(cameraId, mCameraId.get())) {
                 setCameraAvailable(false);
-                Settings.Secure.putInt(
-                    mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 0);
+                mSecureSettings.putInt(Settings.Secure.FLASHLIGHT_AVAILABLE, 0);
 
             }
         }
@@ -232,14 +250,12 @@
         @Override
         @WorkerThread
         public void onTorchModeChanged(String cameraId, boolean enabled) {
-            if (TextUtils.equals(cameraId, mCameraId)) {
+            if (TextUtils.equals(cameraId, mCameraId.get())) {
                 setCameraAvailable(true);
                 setTorchMode(enabled);
-                Settings.Secure.putInt(
-                    mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
-                Settings.Secure.putInt(
-                    mContext.getContentResolver(), Secure.FLASHLIGHT_ENABLED, enabled ? 1 : 0);
-                mContext.sendBroadcast(new Intent(ACTION_FLASHLIGHT_CHANGED));
+                mSecureSettings.putInt(Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
+                mSecureSettings.putInt(Secure.FLASHLIGHT_ENABLED, enabled ? 1 : 0);
+                mBroadcastSender.sendBroadcast(new Intent(ACTION_FLASHLIGHT_CHANGED));
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index bce5a15..d3837d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -142,7 +142,7 @@
 
     protected void setEntryPinned(
             @NonNull HeadsUpManager.HeadsUpEntry headsUpEntry, boolean isPinned) {
-        mLogger.logSetEntryPinned(headsUpEntry.mEntry.getKey(), isPinned);
+        mLogger.logSetEntryPinned(headsUpEntry.mEntry, isPinned);
         NotificationEntry entry = headsUpEntry.mEntry;
         if (entry.isRowPinned() != isPinned) {
             entry.setRowPinned(isPinned);
@@ -183,7 +183,7 @@
         entry.setHeadsUp(false);
         setEntryPinned((HeadsUpEntry) alertEntry, false /* isPinned */);
         EventLogTags.writeSysuiHeadsUpStatus(entry.getKey(), 0 /* visible */);
-        mLogger.logNotificationActuallyRemoved(entry.getKey());
+        mLogger.logNotificationActuallyRemoved(entry);
         for (OnHeadsUpChangedListener listener : mListeners) {
             listener.onHeadsUpStateChanged(entry, false);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
index 6a74ba9..d7c81af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
@@ -20,6 +20,8 @@
 import com.android.systemui.log.LogLevel.INFO
 import com.android.systemui.log.LogLevel.VERBOSE
 import com.android.systemui.log.dagger.NotificationHeadsUpLog
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.logKey
 import javax.inject.Inject
 
 /** Logger for [HeadsUpManager]. */
@@ -56,9 +58,9 @@
         })
     }
 
-    fun logShowNotification(key: String) {
+    fun logShowNotification(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "show notification $str1"
         })
@@ -66,16 +68,16 @@
 
     fun logRemoveNotification(key: String, releaseImmediately: Boolean) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = logKey(key)
             bool1 = releaseImmediately
         }, {
             "remove notification $str1 releaseImmediately: $bool1"
         })
     }
 
-    fun logNotificationActuallyRemoved(key: String) {
+    fun logNotificationActuallyRemoved(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
         }, {
             "notification removed $str1 "
         })
@@ -83,7 +85,7 @@
 
     fun logUpdateNotification(key: String, alert: Boolean, hasEntry: Boolean) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = logKey(key)
             bool1 = alert
             bool2 = hasEntry
         }, {
@@ -91,12 +93,12 @@
         })
     }
 
-    fun logUpdateEntry(key: String, updatePostTime: Boolean) {
+    fun logUpdateEntry(entry: NotificationEntry, updatePostTime: Boolean) {
         buffer.log(TAG, INFO, {
-            str1 = key
+            str1 = entry.logKey
             bool1 = updatePostTime
         }, {
-            "update entry $key updatePostTime: $bool1"
+            "update entry $str1 updatePostTime: $bool1"
         })
     }
 
@@ -108,9 +110,9 @@
         })
     }
 
-    fun logSetEntryPinned(key: String, isPinned: Boolean) {
+    fun logSetEntryPinned(entry: NotificationEntry, isPinned: Boolean) {
         buffer.log(TAG, VERBOSE, {
-            str1 = key
+            str1 = entry.logKey
             bool1 = isPinned
         }, {
             "set entry pinned $str1 pinned: $bool1"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 1b685d0..f151d29 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -45,6 +45,7 @@
 import android.provider.Settings;
 import android.telephony.TelephonyCallback;
 import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -63,6 +64,7 @@
 import com.android.settingslib.users.UserCreatingDialog;
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.Dumpable;
+import com.android.systemui.GuestResetOrExitSessionReceiver;
 import com.android.systemui.GuestResumeSessionReceiver;
 import com.android.systemui.R;
 import com.android.systemui.SystemUISecondaryUserService;
@@ -121,6 +123,8 @@
     private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>();
     @VisibleForTesting
     final GuestResumeSessionReceiver mGuestResumeSessionReceiver;
+    @VisibleForTesting
+    final GuestResetOrExitSessionReceiver mGuestResetOrExitSessionReceiver;
     private final KeyguardStateController mKeyguardStateController;
     private final DeviceProvisionedController mDeviceProvisionedController;
     private final DevicePolicyManager mDevicePolicyManager;
@@ -188,7 +192,9 @@
             InteractionJankMonitor interactionJankMonitor,
             LatencyTracker latencyTracker,
             DumpManager dumpManager,
-            DialogLaunchAnimator dialogLaunchAnimator) {
+            DialogLaunchAnimator dialogLaunchAnimator,
+            GuestResumeSessionReceiver guestResumeSessionReceiver,
+            GuestResetOrExitSessionReceiver guestResetOrExitSessionReceiver) {
         mContext = context;
         mActivityManager = activityManager;
         mUserTracker = userTracker;
@@ -200,14 +206,13 @@
         mInteractionJankMonitor = interactionJankMonitor;
         mLatencyTracker = latencyTracker;
         mGlobalSettings = globalSettings;
-        mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(
-                this, mUserTracker, mUiEventLogger, secureSettings);
+        mGuestResumeSessionReceiver = guestResumeSessionReceiver;
+        mGuestResetOrExitSessionReceiver = guestResetOrExitSessionReceiver;
         mBgExecutor = bgExecutor;
         mLongRunningExecutor = longRunningExecutor;
         mUiExecutor = uiExecutor;
-        if (!UserManager.isGuestUserEphemeral()) {
-            mGuestResumeSessionReceiver.register(mBroadcastDispatcher);
-        }
+        mGuestResumeSessionReceiver.register();
+        mGuestResetOrExitSessionReceiver.register();
         mGuestUserAutoCreated = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_guestUserAutoCreated);
         mGuestIsResetting = new AtomicBoolean();
@@ -278,6 +283,10 @@
         refreshUsers(UserHandle.USER_NULL);
     }
 
+    private static boolean isEnableGuestModeUxChanges(Context context) {
+        return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_GUEST_MODE_UX_CHANGES);
+    }
+
     /**
      * Refreshes users from UserManager.
      *
@@ -524,20 +533,31 @@
 
     private void onUserListItemClicked(int id, UserRecord record, DialogShower dialogShower) {
         int currUserId = mUserTracker.getUserId();
+        // If switching from guest and guest is ephemeral, then follow the flow
+        // of showExitGuestDialog to remove current guest,
+        // and switch to selected user
+        UserInfo currUserInfo = mUserTracker.getUserInfo();
         if (currUserId == id) {
             if (record.isGuest) {
-                showExitGuestDialog(id, dialogShower);
+                showExitGuestDialog(id, currUserInfo.isEphemeral(), dialogShower);
             }
             return;
         }
-        if (UserManager.isGuestUserEphemeral()) {
-            // If switching from guest, we want to bring up the guest exit dialog instead of switching
-            UserInfo currUserInfo = mUserManager.getUserInfo(currUserId);
-            if (currUserInfo != null && currUserInfo.isGuest()) {
-                showExitGuestDialog(currUserId, record.resolveId(), dialogShower);
+
+        if (currUserInfo != null && currUserInfo.isGuest()) {
+            if (isEnableGuestModeUxChanges(mContext)) {
+                showExitGuestDialog(currUserId, currUserInfo.isEphemeral(),
+                        record.resolveId(), dialogShower);
                 return;
+            } else {
+                if (currUserInfo.isEphemeral()) {
+                    showExitGuestDialog(currUserId, currUserInfo.isEphemeral(),
+                            record.resolveId(), dialogShower);
+                    return;
+                }
             }
         }
+
         if (dialogShower != null) {
             // If we haven't morphed into another dialog, it means we have just switched users.
             // Then, dismiss the dialog.
@@ -559,7 +579,7 @@
         }
     }
 
-    private void showExitGuestDialog(int id, DialogShower dialogShower) {
+    private void showExitGuestDialog(int id, boolean isGuestEphemeral, DialogShower dialogShower) {
         int newId = UserHandle.USER_SYSTEM;
         if (mResumeUserOnGuestLogout && mLastNonGuestUser != UserHandle.USER_SYSTEM) {
             UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser);
@@ -567,14 +587,15 @@
                 newId = info.id;
             }
         }
-        showExitGuestDialog(id, newId, dialogShower);
+        showExitGuestDialog(id, isGuestEphemeral, newId, dialogShower);
     }
 
-    private void showExitGuestDialog(int id, int targetId, DialogShower dialogShower) {
+    private void showExitGuestDialog(int id, boolean isGuestEphemeral,
+                        int targetId, DialogShower dialogShower) {
         if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) {
             mExitGuestDialog.cancel();
         }
-        mExitGuestDialog = new ExitGuestDialog(mContext, id, targetId);
+        mExitGuestDialog = new ExitGuestDialog(mContext, id, isGuestEphemeral, targetId);
         if (dialogShower != null) {
             dialogShower.showDialog(mExitGuestDialog);
         } else {
@@ -808,6 +829,52 @@
         }
     }
 
+    /**
+     * Exits guest user and switches to previous non-guest user. The guest must be the current
+     * user.
+     *
+     * @param guestUserId user id of the guest user to exit
+     * @param targetUserId user id of the guest user to exit, set to UserHandle.USER_NULL when
+     *                       target user id is not known
+     * @param forceRemoveGuestOnExit true: remove guest before switching user,
+     *                               false: remove guest only if its ephemeral, else keep guest
+     */
+    public void exitGuestUser(@UserIdInt int guestUserId, @UserIdInt int targetUserId,
+                    boolean forceRemoveGuestOnExit) {
+        UserInfo currentUser = mUserTracker.getUserInfo();
+        if (currentUser.id != guestUserId) {
+            Log.w(TAG, "User requesting to start a new session (" + guestUserId + ")"
+                    + " is not current user (" + currentUser.id + ")");
+            return;
+        }
+        if (!currentUser.isGuest()) {
+            Log.w(TAG, "User requesting to start a new session (" + guestUserId + ")"
+                    + " is not a guest");
+            return;
+        }
+
+        int newUserId = UserHandle.USER_SYSTEM;
+        if (targetUserId == UserHandle.USER_NULL) {
+            // when target user is not specified switch to last non guest user
+            if (mResumeUserOnGuestLogout && mLastNonGuestUser != UserHandle.USER_SYSTEM) {
+                UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser);
+                if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) {
+                    newUserId = info.id;
+                }
+            }
+        } else {
+            newUserId = targetUserId;
+        }
+
+        if (currentUser.isEphemeral() || forceRemoveGuestOnExit) {
+            mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE);
+            removeGuestUser(currentUser.id, newUserId);
+        } else {
+            mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_SWITCH);
+            switchToUserId(newUserId);
+        }
+    }
+
     private void scheduleGuestCreation() {
         if (!mGuestCreationScheduled.compareAndSet(false, true)) {
             return;
@@ -975,9 +1042,14 @@
         public String getName(Context context, UserRecord item) {
             if (item.isGuest) {
                 if (item.isCurrent) {
-                    return context.getString(mController.mGuestUserAutoCreated
+                    if (isEnableGuestModeUxChanges(context)) {
+                        return context.getString(
+                                com.android.settingslib.R.string.guest_exit_quick_settings_button);
+                    } else {
+                        return context.getString(mController.mGuestUserAutoCreated
                             ? com.android.settingslib.R.string.guest_reset_guest
                             : com.android.settingslib.R.string.guest_exit_guest);
+                    }
                 } else {
                     if (item.info != null) {
                         return context.getString(com.android.internal.R.string.guest_name);
@@ -994,8 +1066,13 @@
                                             ? com.android.settingslib.R.string.guest_resetting
                                             : com.android.internal.R.string.guest_name);
                         } else {
-                            return context.getString(
-                                    com.android.settingslib.R.string.guest_new_guest);
+                            if (isEnableGuestModeUxChanges(context)) {
+                                // we always show "guest" as string, instead of "add guest"
+                                return context.getString(com.android.internal.R.string.guest_name);
+                            } else {
+                                return context.getString(
+                                        com.android.settingslib.R.string.guest_new_guest);
+                            }
                         }
                     }
                 }
@@ -1017,7 +1094,11 @@
         protected static Drawable getIconDrawable(Context context, UserRecord item) {
             int iconRes;
             if (item.isAddUser) {
-                iconRes = R.drawable.ic_account_circle_filled;
+                if (isEnableGuestModeUxChanges(context)) {
+                    iconRes = R.drawable.ic_add;
+                } else {
+                    iconRes = R.drawable.ic_account_circle_filled;
+                }
             } else if (item.isGuest) {
                 iconRes = R.drawable.ic_account_circle;
             } else if (item.isAddSupervisedUser) {
@@ -1189,24 +1270,58 @@
 
         private final int mGuestId;
         private final int mTargetId;
+        private final boolean mIsGuestEphemeral;
 
-        public ExitGuestDialog(Context context, int guestId, int targetId) {
+        ExitGuestDialog(Context context, int guestId, boolean isGuestEphemeral,
+                    int targetId) {
             super(context);
-            setTitle(mGuestUserAutoCreated
-                    ? com.android.settingslib.R.string.guest_reset_guest_dialog_title
-                    : com.android.settingslib.R.string.guest_remove_guest_dialog_title);
-            setMessage(context.getString(R.string.guest_exit_guest_dialog_message));
-            setButton(DialogInterface.BUTTON_NEUTRAL,
-                    context.getString(android.R.string.cancel), this);
-            setButton(DialogInterface.BUTTON_POSITIVE,
-                    context.getString(mGuestUserAutoCreated
+            if (isEnableGuestModeUxChanges(context)) {
+                if (isGuestEphemeral) {
+                    setTitle(context.getString(
+                                com.android.settingslib.R.string.guest_exit_dialog_title));
+                    setMessage(context.getString(
+                                com.android.settingslib.R.string.guest_exit_dialog_message));
+                    setButton(DialogInterface.BUTTON_NEUTRAL,
+                            context.getString(android.R.string.cancel), this);
+                    setButton(DialogInterface.BUTTON_POSITIVE,
+                            context.getString(
+                                com.android.settingslib.R.string.guest_exit_dialog_button), this);
+                } else {
+                    setTitle(context.getString(
+                                com.android.settingslib
+                                    .R.string.guest_exit_dialog_title_non_ephemeral));
+                    setMessage(context.getString(
+                                com.android.settingslib
+                                    .R.string.guest_exit_dialog_message_non_ephemeral));
+                    setButton(DialogInterface.BUTTON_NEUTRAL,
+                            context.getString(android.R.string.cancel), this);
+                    setButton(DialogInterface.BUTTON_NEGATIVE,
+                            context.getString(
+                                com.android.settingslib.R.string.guest_exit_clear_data_button),
+                            this);
+                    setButton(DialogInterface.BUTTON_POSITIVE,
+                            context.getString(
+                                com.android.settingslib.R.string.guest_exit_save_data_button),
+                            this);
+                }
+            } else {
+                setTitle(mGuestUserAutoCreated
+                        ? com.android.settingslib.R.string.guest_reset_guest_dialog_title
+                        : com.android.settingslib.R.string.guest_remove_guest_dialog_title);
+                setMessage(context.getString(R.string.guest_exit_guest_dialog_message));
+                setButton(DialogInterface.BUTTON_NEUTRAL,
+                        context.getString(android.R.string.cancel), this);
+                setButton(DialogInterface.BUTTON_POSITIVE,
+                        context.getString(mGuestUserAutoCreated
                             ? com.android.settingslib.R.string.guest_reset_guest_confirm_button
                             : com.android.settingslib.R.string.guest_remove_guest_confirm_button),
-                    this);
+                        this);
+            }
             SystemUIDialog.setWindowOnTop(this, mKeyguardStateController.isShowing());
             setCanceledOnTouchOutside(false);
             mGuestId = guestId;
             mTargetId = targetId;
+            mIsGuestEphemeral = isGuestEphemeral;
         }
 
         @Override
@@ -1216,12 +1331,40 @@
             if (mFalsingManager.isFalseTap(penalty)) {
                 return;
             }
-            if (which == BUTTON_NEUTRAL) {
-                cancel();
+            if (isEnableGuestModeUxChanges(getContext())) {
+                if (mIsGuestEphemeral) {
+                    if (which == DialogInterface.BUTTON_POSITIVE) {
+                        mDialogLaunchAnimator.dismissStack(this);
+                        // Ephemeral guest: exit guest, guest is removed by the system
+                        // on exit, since its marked ephemeral
+                        exitGuestUser(mGuestId, mTargetId, false);
+                    } else if (which == DialogInterface.BUTTON_NEGATIVE) {
+                        // Cancel clicked, do nothing
+                        cancel();
+                    }
+                } else {
+                    if (which == DialogInterface.BUTTON_POSITIVE) {
+                        mDialogLaunchAnimator.dismissStack(this);
+                        // Non-ephemeral guest: exit guest, guest is not removed by the system
+                        // on exit, since its marked non-ephemeral
+                        exitGuestUser(mGuestId, mTargetId, false);
+                    } else if (which == DialogInterface.BUTTON_NEGATIVE) {
+                        mDialogLaunchAnimator.dismissStack(this);
+                        // Non-ephemeral guest: remove guest and then exit
+                        exitGuestUser(mGuestId, mTargetId, true);
+                    } else if (which == DialogInterface.BUTTON_NEUTRAL) {
+                        // Cancel clicked, do nothing
+                        cancel();
+                    }
+                }
             } else {
-                mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE);
-                mDialogLaunchAnimator.dismissStack(this);
-                removeGuestUser(mGuestId, mTargetId);
+                if (which == BUTTON_NEUTRAL) {
+                    cancel();
+                } else {
+                    mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE);
+                    mDialogLaunchAnimator.dismissStack(this);
+                    removeGuestUser(mGuestId, mTargetId);
+                }
             }
         }
     }
@@ -1230,10 +1373,17 @@
     final class AddUserDialog extends SystemUIDialog implements
             DialogInterface.OnClickListener {
 
-        public AddUserDialog(Context context) {
+        AddUserDialog(Context context) {
             super(context);
+
             setTitle(com.android.settingslib.R.string.user_add_user_title);
-            setMessage(com.android.settingslib.R.string.user_add_user_message_short);
+            String message = context.getString(
+                                com.android.settingslib.R.string.user_add_user_message_short);
+            UserInfo currentUser = mUserTracker.getUserInfo();
+            if (currentUser != null && currentUser.isGuest() && currentUser.isEphemeral()) {
+                message += context.getString(R.string.user_add_user_message_guest_remove);
+            }
+            setMessage(message);
             setButton(DialogInterface.BUTTON_NEUTRAL,
                     context.getString(android.R.string.cancel), this);
             setButton(DialogInterface.BUTTON_POSITIVE,
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
index d2d2361..eea6ac0e 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
@@ -20,6 +20,7 @@
 import android.view.IWindowManager
 import com.android.systemui.keyguard.LifecycleScreenStatusProvider
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.system.SystemUnfoldSharedModule
 import com.android.systemui.unfold.updates.FoldStateProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
 import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
@@ -34,7 +35,7 @@
 import javax.inject.Named
 import javax.inject.Singleton
 
-@Module(includes = [UnfoldSharedModule::class])
+@Module(includes = [UnfoldSharedModule::class, SystemUnfoldSharedModule::class])
 class UnfoldTransitionModule {
 
     @Provides @UnfoldTransitionATracePrefix fun tracingTagPrefix() = "systemui"
@@ -62,11 +63,6 @@
 
     @Provides
     @Singleton
-    fun provideUnfoldTransitionConfig(context: Context): UnfoldTransitionConfig =
-        createConfig(context)
-
-    @Provides
-    @Singleton
     fun provideNaturalRotationProgressProvider(
         context: Context,
         windowManager: IWindowManager,
diff --git a/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt b/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt
new file mode 100644
index 0000000..8b90547
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util
+
+import android.content.Context
+import android.util.AttributeSet
+import com.android.systemui.R
+
+class DelayableMarqueeTextView @JvmOverloads constructor(
+    context: Context,
+    attrs: AttributeSet? = null,
+    defStyleAttr: Int = 0,
+    defStyleRes: Int = 0
+) : SafeMarqueeTextView(context, attrs, defStyleAttr, defStyleRes) {
+
+    var marqueeDelay: Long = DEFAULT_MARQUEE_DELAY
+    private var wantsMarquee = false
+    private var marqueeBlocked = true
+
+    private val enableMarquee = Runnable {
+        if (wantsMarquee) {
+            marqueeBlocked = false
+            startMarquee()
+        }
+    }
+
+    init {
+        val typedArray = context.theme.obtainStyledAttributes(
+                attrs,
+                R.styleable.DelayableMarqueeTextView,
+                defStyleAttr,
+                defStyleRes
+        )
+        marqueeDelay = typedArray.getInteger(
+                R.styleable.DelayableMarqueeTextView_marqueeDelay,
+                DEFAULT_MARQUEE_DELAY.toInt()
+        ).toLong()
+        typedArray.recycle()
+    }
+
+    override fun startMarquee() {
+        if (!isSelected) {
+            return
+        }
+        wantsMarquee = true
+        if (marqueeBlocked) {
+            if (handler?.hasCallbacks(enableMarquee) == false) {
+                postDelayed(enableMarquee, marqueeDelay)
+            }
+            return
+        }
+        super.startMarquee()
+    }
+
+    override fun stopMarquee() {
+        handler?.removeCallbacks(enableMarquee)
+        wantsMarquee = false
+        marqueeBlocked = true
+        super.stopMarquee()
+    }
+
+    companion object {
+        const val DEFAULT_MARQUEE_DELAY = 2000L
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/DumpUtils.kt b/packages/SystemUI/src/com/android/systemui/util/DumpUtils.kt
index f952476..018ef96 100644
--- a/packages/SystemUI/src/com/android/systemui/util/DumpUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/DumpUtils.kt
@@ -55,6 +55,10 @@
     }
 }
 
+/** Print a line which is '$label=$value' */
+fun IndentingPrintWriter.println(label: String, value: Any) =
+    append(label).append('=').println(value)
+
 /** Return a readable string for the visibility */
 fun visibilityString(@View.Visibility visibility: Int): String = when (visibility) {
     View.GONE -> "gone"
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index 76dfcb1..53da213 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -35,11 +35,15 @@
 public class NotificationChannels extends CoreStartable {
     public static String ALERTS      = "ALR";
     public static String SCREENSHOTS_HEADSUP = "SCN_HEADSUP";
-    public static String GENERAL     = "GEN";
+    // Deprecated. Please use or create a more specific channel that users will better understand
+    @Deprecated
+    static String GENERAL     = "GEN";
     public static String STORAGE     = "DSK";
     public static String BATTERY     = "BAT";
     public static String TVPIP       = TvPipNotificationController.NOTIFICATION_CHANNEL; // "TVPIP"
     public static String HINTS       = "HNT";
+    public static String INSTANT     = "INS";
+    public static String SETUP       = "STP";
 
     @Inject
     public NotificationChannels(Context context) {
@@ -64,11 +68,17 @@
                 context.getString(R.string.notification_channel_alerts),
                 NotificationManager.IMPORTANCE_HIGH);
 
-        final NotificationChannel general = new NotificationChannel(
-                GENERAL,
-                context.getString(R.string.notification_channel_general),
+        final NotificationChannel instant = new NotificationChannel(
+                INSTANT,
+                context.getString(R.string.notification_channel_instant),
                 NotificationManager.IMPORTANCE_MIN);
 
+        final NotificationChannel setup = new NotificationChannel(
+                SETUP,
+                context.getString(R.string.notification_channel_setup),
+                NotificationManager.IMPORTANCE_DEFAULT);
+        setup.setSound(null, null);
+
         final NotificationChannel storage = new NotificationChannel(
                 STORAGE,
                 context.getString(R.string.notification_channel_storage),
@@ -84,7 +94,8 @@
 
         nm.createNotificationChannels(Arrays.asList(
                 alerts,
-                general,
+                instant,
+                setup,
                 storage,
                 createScreenshotChannel(
                         context.getString(R.string.notification_channel_screenshot)),
@@ -123,6 +134,11 @@
     @Override
     public void start() {
         createAll(mContext);
+        cleanUp();
+    }
+
+    private void cleanUp() {
+        mContext.getSystemService(NotificationManager.class).deleteNotificationChannel(GENERAL);
     }
 
     private static boolean isTv(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/PluralMessageFormater.kt b/packages/SystemUI/src/com/android/systemui/util/PluralMessageFormater.kt
new file mode 100644
index 0000000..83b471d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/PluralMessageFormater.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util
+
+import android.annotation.StringRes
+import android.content.res.Resources
+import android.util.PluralsMessageFormatter
+
+/**
+ * Utility method that provides the localized plural string for the given [messageId]
+ * using the [count] parameter.
+ */
+fun icuMessageFormat(res: Resources, @StringRes messageId: Int, count: Int): String {
+    return PluralsMessageFormatter.format(res, mapOf<String, Any>("count" to count), messageId)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java b/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java
index d3c6e9a..4e9030f 100644
--- a/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java
@@ -16,16 +16,17 @@
 
 package com.android.systemui.util.condition;
 
+import android.util.ArraySet;
 import android.util.Log;
 
-import com.android.systemui.statusbar.policy.CallbackController;
+import com.android.systemui.dagger.qualifiers.Main;
 
 import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Set;
 import java.util.concurrent.Executor;
 import java.util.stream.Collectors;
@@ -36,157 +37,120 @@
  * {@link Monitor} takes in a set of conditions, monitors whether all of them have
  * been fulfilled, and informs any registered listeners.
  */
-public class Monitor implements CallbackController<Monitor.Callback> {
+public class Monitor {
     private final String mTag = getClass().getSimpleName();
-
-    private final ArrayList<Callback> mCallbacks = new ArrayList<>();
-
-    // Set of all conditions that need to be monitored.
-    private final Set<Condition> mConditions;
     private final Executor mExecutor;
 
-    // Whether all conditions have been met.
-    private boolean mAllConditionsMet = false;
+    private final HashMap<Condition, ArraySet<Subscription.Token>> mConditions = new HashMap<>();
+    private final HashMap<Subscription.Token, SubscriptionState> mSubscriptions = new HashMap<>();
 
-    // Whether the monitor has started listening for all the conditions.
-    private boolean mHaveConditionsStarted = false;
+    private static class SubscriptionState {
+        private final Subscription mSubscription;
+        private Boolean mAllConditionsMet;
+
+        SubscriptionState(Subscription subscription) {
+            mSubscription = subscription;
+        }
+
+        public Set<Condition> getConditions() {
+            return mSubscription.mConditions;
+        }
+
+        public void update() {
+            // Overriding conditions do not override each other
+            final Collection<Condition> overridingConditions = mSubscription.mConditions.stream()
+                    .filter(Condition::isOverridingCondition).collect(Collectors.toSet());
+
+            final Collection<Condition> targetCollection = overridingConditions.isEmpty()
+                    ? mSubscription.mConditions : overridingConditions;
+
+            final boolean newAllConditionsMet = targetCollection.isEmpty() ? true : targetCollection
+                    .stream()
+                    .map(Condition::isConditionMet)
+                    .allMatch(conditionMet -> conditionMet);
+
+            if (mAllConditionsMet != null && newAllConditionsMet == mAllConditionsMet) {
+                return;
+            }
+
+            mAllConditionsMet = newAllConditionsMet;
+            mSubscription.mCallback.onConditionsChanged(mAllConditionsMet);
+        }
+    }
 
     // Callback for when each condition has been updated.
     private final Condition.Callback mConditionCallback = new Condition.Callback() {
         @Override
         public void onConditionChanged(Condition condition) {
-            mExecutor.execute(() -> updateConditionMetState());
+            mExecutor.execute(() -> updateConditionMetState(condition));
         }
     };
 
     @Inject
-    public Monitor(Executor executor, Set<Condition> conditions, Set<Callback> callbacks) {
-        mConditions = new HashSet<>();
+    public Monitor(@Main Executor executor) {
         mExecutor = executor;
-
-        if (conditions != null) {
-            mConditions.addAll(conditions);
-        }
-
-        if (callbacks == null) {
-            return;
-        }
-
-        for (Callback callback : callbacks) {
-            addCallbackLocked(callback);
-        }
     }
 
-    private void updateConditionMetState() {
-        // Overriding conditions do not override each other
-        final Collection<Condition> overridingConditions = mConditions.stream()
-                .filter(Condition::isOverridingCondition).collect(Collectors.toSet());
-
-        final Collection<Condition> targetCollection = overridingConditions.isEmpty()
-                ? mConditions : overridingConditions;
-
-        final boolean newAllConditionsMet = targetCollection.isEmpty() ? true : targetCollection
-                .stream()
-                .map(Condition::isConditionMet)
-                .allMatch(conditionMet -> conditionMet);
-
-        if (newAllConditionsMet == mAllConditionsMet) {
-            return;
-        }
-
-        if (shouldLog()) Log.d(mTag, "all conditions met: " + newAllConditionsMet);
-        mAllConditionsMet = newAllConditionsMet;
-
-        // Updates all callbacks.
-        final Iterator<Callback> iterator = mCallbacks.iterator();
-        while (iterator.hasNext()) {
-            final Callback callback = iterator.next();
-            if (callback == null) {
-                iterator.remove();
-            } else {
-                callback.onConditionsChanged(mAllConditionsMet);
-            }
-        }
-    }
-
-    private void addConditionLocked(@NotNull Condition condition) {
-        mConditions.add(condition);
-
-        if (!mHaveConditionsStarted) {
-            return;
-        }
-
-        condition.addCallback(mConditionCallback);
-        updateConditionMetState();
+    private void updateConditionMetState(Condition condition) {
+        mConditions.get(condition).stream().forEach(token -> mSubscriptions.get(token).update());
     }
 
     /**
-     * Adds a condition for the monitor to listen to and consider when determining whether the
-     * overall condition state is met.
+     * Registers a callback and the set of conditions to trigger it.
+     * @param subscription A {@link Subscription} detailing the desired conditions and callback.
+     * @return A {@link Subscription.Token} that can be used to remove the subscription.
      */
-    public void addCondition(@NotNull Condition condition) {
-        mExecutor.execute(() -> addConditionLocked(condition));
-    }
+    public Subscription.Token addSubscription(@NotNull Subscription subscription) {
+        final Subscription.Token token = new Subscription.Token();
+        final SubscriptionState state = new SubscriptionState(subscription);
 
-    /**
-     * Removes a condition from further consideration.
-     */
-    public void removeCondition(@NotNull Condition condition) {
         mExecutor.execute(() -> {
-            mConditions.remove(condition);
+            mSubscriptions.put(token, state);
 
-            if (!mHaveConditionsStarted) {
+            // Add and associate conditions.
+            subscription.getConditions().stream().forEach(condition -> {
+                if (!mConditions.containsKey(condition)) {
+                    mConditions.put(condition, new ArraySet<>());
+                    condition.addCallback(mConditionCallback);
+                }
+
+                mConditions.get(condition).add(token);
+            });
+
+            // Update subscription state.
+            state.update();
+
+        });
+        return token;
+    }
+
+    /**
+     * Removes a subscription from participating in future callbacks.
+     * @param token The {@link Subscription.Token} returned when the {@link Subscription} was
+     *              originally added.
+     */
+    public void removeSubscription(@NotNull Subscription.Token token) {
+        mExecutor.execute(() -> {
+            if (shouldLog()) Log.d(mTag, "removing callback");
+            if (!mSubscriptions.containsKey(token)) {
+                Log.e(mTag, "subscription not present:" + token);
                 return;
             }
 
-            condition.removeCallback(mConditionCallback);
-            updateConditionMetState();
-        });
-    }
+            mSubscriptions.remove(token).getConditions().forEach(condition -> {
+                if (!mConditions.containsKey(condition)) {
+                    Log.e(mTag, "condition not present:" + condition);
+                    return;
 
-    private void addCallbackLocked(@NotNull Callback callback) {
-        if (mCallbacks.contains(callback)) {
-            return;
-        }
-
-        if (shouldLog()) Log.d(mTag, "adding callback");
-        mCallbacks.add(callback);
-
-        // Updates the callback immediately.
-        callback.onConditionsChanged(mAllConditionsMet);
-
-        if (!mHaveConditionsStarted) {
-            if (shouldLog()) Log.d(mTag, "starting all conditions");
-            mConditions.forEach(condition -> condition.addCallback(mConditionCallback));
-            updateConditionMetState();
-            mHaveConditionsStarted = true;
-        }
-    }
-
-    @Override
-    public void addCallback(@NotNull Callback callback) {
-        mExecutor.execute(() -> addCallbackLocked(callback));
-    }
-
-    @Override
-    public void removeCallback(@NotNull Callback callback) {
-        mExecutor.execute(() -> {
-            if (shouldLog()) Log.d(mTag, "removing callback");
-            final Iterator<Callback> iterator = mCallbacks.iterator();
-            while (iterator.hasNext()) {
-                final Callback cb = iterator.next();
-                if (cb == null || cb == callback) {
-                    iterator.remove();
                 }
-            }
+                final Set<Subscription.Token> conditionSubscriptions = mConditions.get(condition);
 
-            if (mCallbacks.isEmpty() && mHaveConditionsStarted) {
-                if (shouldLog()) Log.d(mTag, "stopping all conditions");
-                mConditions.forEach(condition -> condition.removeCallback(mConditionCallback));
-
-                mAllConditionsMet = false;
-                mHaveConditionsStarted = false;
-            }
+                conditionSubscriptions.remove(token);
+                if (conditionSubscriptions.isEmpty()) {
+                    condition.removeCallback(mConditionCallback);
+                    mConditions.remove(condition);
+                }
+            });
         });
     }
 
@@ -195,10 +159,92 @@
     }
 
     /**
+     * A {@link Subscription} represents a set of conditions and a callback that is informed when
+     * these conditions change.
+     */
+    public static class Subscription {
+        private final Set<Condition> mConditions;
+        private final Callback mCallback;
+
+        /** */
+        public Subscription(Set<Condition> conditions, Callback callback) {
+            this.mConditions = Collections.unmodifiableSet(conditions);
+            this.mCallback = callback;
+        }
+
+        public Set<Condition> getConditions() {
+            return mConditions;
+        }
+
+        public Callback getCallback() {
+            return mCallback;
+        }
+
+        /**
+         * A {@link Token} is an identifier that is associated with a {@link Subscription} which is
+         * registered with a {@link Monitor}.
+         */
+        public static class Token {
+        }
+
+        /**
+         * {@link Builder} is a helper class for constructing a {@link Subscription}.
+         */
+        public static class Builder {
+            private final Callback mCallback;
+            private final ArraySet<Condition> mConditions;
+
+            /**
+             * Default constructor specifying the {@link Callback} for the {@link Subscription}.
+             * @param callback
+             */
+            public Builder(Callback callback) {
+                mCallback = callback;
+                mConditions = new ArraySet<>();
+            }
+
+            /**
+             * Adds a {@link Condition} to be associated with the {@link Subscription}.
+             * @param condition
+             * @return The updated {@link Builder}.
+             */
+            public Builder addCondition(Condition condition) {
+                mConditions.add(condition);
+                return this;
+            }
+
+            /**
+             * Adds a set of {@link Condition} to be associated with the {@link Subscription}.
+             * @param condition
+             * @return The updated {@link Builder}.
+             */
+            public Builder addConditions(Set<Condition> condition) {
+                mConditions.addAll(condition);
+                return this;
+            }
+
+            /**
+             * Builds the {@link Subscription}.
+             * @return The resulting {@link Subscription}.
+             */
+            public Subscription build() {
+                return new Subscription(mConditions, mCallback);
+            }
+        }
+    }
+
+    /**
      * Callback that receives updates of whether all conditions have been fulfilled.
      */
     public interface Callback {
         /**
+         * Returns the conditions associated with this callback.
+         */
+        default ArrayList<Condition> getConditions() {
+            return new ArrayList<>();
+        }
+
+        /**
          * Triggered when the fulfillment of all conditions have been met.
          *
          * @param allConditionsMet True if all conditions have been fulfilled. False if none or
diff --git a/packages/SystemUI/src/com/android/systemui/util/condition/dagger/MonitorComponent.java b/packages/SystemUI/src/com/android/systemui/util/condition/dagger/MonitorComponent.java
deleted file mode 100644
index fc67973..0000000
--- a/packages/SystemUI/src/com/android/systemui/util/condition/dagger/MonitorComponent.java
+++ /dev/null
@@ -1,46 +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.util.condition.dagger;
-
-import com.android.systemui.util.condition.Condition;
-import com.android.systemui.util.condition.Monitor;
-
-import java.util.Set;
-
-import dagger.BindsInstance;
-import dagger.Subcomponent;
-
-/**
- * Component for {@link Monitor}.
- */
-@Subcomponent
-public interface MonitorComponent {
-    /**
-     * Factory for {@link MonitorComponent}.
-     */
-    @Subcomponent.Factory
-    interface Factory {
-        MonitorComponent create(@BindsInstance Set<Condition> conditions,
-                @BindsInstance Set<Monitor.Callback> callbacks);
-    }
-
-    /**
-     * Provides {@link Monitor}.
-     * @return
-     */
-    Monitor getMonitor();
-}
diff --git a/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java b/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java
index 7892d6e..981bf01 100644
--- a/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java
@@ -18,7 +18,6 @@
 
 import com.android.systemui.util.RingerModeTracker;
 import com.android.systemui.util.RingerModeTrackerImpl;
-import com.android.systemui.util.condition.dagger.MonitorComponent;
 import com.android.systemui.util.wrapper.UtilWrapperModule;
 
 import dagger.Binds;
@@ -27,9 +26,6 @@
 /** Dagger Module for code in the util package. */
 @Module(includes = {
                 UtilWrapperModule.class
-        },
-        subcomponents = {
-                MonitorComponent.class,
         })
 public interface UtilModule {
     /** */
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index 83fc281..e90775d 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -78,6 +78,7 @@
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
 import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -121,6 +122,7 @@
     private final Bubbles.SysuiProxy mSysuiProxy;
     // TODO (b/145659174): allow for multiple callbacks to support the "shadow" new notif pipeline
     private final List<NotifCallback> mCallbacks = new ArrayList<>();
+    private final StatusBarWindowCallback mStatusBarWindowCallback;
 
     /**
      * Creates {@link BubblesManager}, returns {@code null} if Optional {@link Bubbles} not present
@@ -278,9 +280,15 @@
 
                 });
 
+        // Store callback in a field so it won't get GC'd
+        mStatusBarWindowCallback =
+                (keyguardShowing, keyguardOccluded, bouncerShowing, isDozing, panelExpanded) ->
+                        mBubbles.onNotificationPanelExpandedChanged(panelExpanded);
+        notificationShadeWindowController.registerCallback(mStatusBarWindowCallback);
+
         mSysuiProxy = new Bubbles.SysuiProxy() {
             @Override
-            public void isNotificationShadeExpand(Consumer<Boolean> callback) {
+            public void isNotificationPanelExpand(Consumer<Boolean> callback) {
                 sysuiMainExecutor.execute(() -> {
                     callback.accept(mNotificationShadeWindowController.getPanelExpanded());
                 });
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
index 1518ea1..8293cc2 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
@@ -17,11 +17,13 @@
 package com.android.keyguard;
 
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -90,4 +92,19 @@
         mMessageAreaController.setBouncerShowing(true);
         verify(mKeyguardMessageArea).setBouncerShowing(true);
     }
+
+    @Test
+    public void testSetMessageIfEmpty_empty() {
+        mMessageAreaController.setMessage("");
+        mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_pin);
+        verify(mKeyguardMessageArea).setMessage(R.string.keyguard_enter_your_pin);
+    }
+
+    @Test
+    public void testSetMessageIfEmpty_notEmpty() {
+        mMessageAreaController.setMessage("abc");
+        mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_pin);
+        verify(mKeyguardMessageArea, never()).setMessage(getContext()
+                .getResources().getText(R.string.keyguard_enter_your_pin));
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
index a1e23a20..ec85603 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
@@ -73,25 +73,25 @@
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
-        Mockito.`when`(keyguardPasswordView
-                .findViewById<KeyguardMessageArea>(R.id.keyguard_message_area))
-                .thenReturn(mKeyguardMessageArea)
+        Mockito.`when`(
+            keyguardPasswordView.findViewById<KeyguardMessageArea>(R.id.keyguard_message_area)
+        ).thenReturn(mKeyguardMessageArea)
         Mockito.`when`(messageAreaControllerFactory.create(mKeyguardMessageArea))
-                .thenReturn(mKeyguardMessageAreaController)
+            .thenReturn(mKeyguardMessageAreaController)
         keyguardPasswordViewController = KeyguardPasswordViewController(
-                keyguardPasswordView,
-                keyguardUpdateMonitor,
-                securityMode,
-                lockPatternUtils,
-                keyguardSecurityCallback,
-                messageAreaControllerFactory,
-                latencyTracker,
-                inputMethodManager,
-                emergencyButtonController,
-                mainExecutor,
-                mContext.resources,
-                falsingCollector,
-                keyguardViewController
+            keyguardPasswordView,
+            keyguardUpdateMonitor,
+            securityMode,
+            lockPatternUtils,
+            keyguardSecurityCallback,
+            messageAreaControllerFactory,
+            latencyTracker,
+            inputMethodManager,
+            emergencyButtonController,
+            mainExecutor,
+            mContext.resources,
+            falsingCollector,
+            keyguardViewController
         )
     }
 
@@ -110,4 +110,11 @@
         keyguardPasswordViewController.onResume(KeyguardSecurityView.VIEW_REVEALED)
         verify(keyguardPasswordView, never()).requestFocus()
     }
-}
\ No newline at end of file
+
+    @Test
+    fun onResume_testSetInitialText() {
+        keyguardPasswordViewController.onResume(KeyguardSecurityView.SCREEN_ON)
+        verify(mKeyguardMessageAreaController)
+            .setMessageIfEmpty(R.string.keyguard_enter_your_password)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index 8e1e42a..616a105 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -31,8 +31,8 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @SmallTest
@@ -41,28 +41,39 @@
 class KeyguardPatternViewControllerTest : SysuiTestCase() {
     @Mock
     private lateinit var mKeyguardPatternView: KeyguardPatternView
+
     @Mock
     private lateinit var mKeyguardUpdateMonitor: KeyguardUpdateMonitor
+
     @Mock
     private lateinit var mSecurityMode: KeyguardSecurityModel.SecurityMode
+
     @Mock
     private lateinit var mLockPatternUtils: LockPatternUtils
+
     @Mock
     private lateinit var mKeyguardSecurityCallback: KeyguardSecurityCallback
+
     @Mock
     private lateinit var mLatencyTracker: LatencyTracker
     private var mFalsingCollector: FalsingCollector = FalsingCollectorFake()
+
     @Mock
     private lateinit var mEmergencyButtonController: EmergencyButtonController
+
     @Mock
     private lateinit
     var mKeyguardMessageAreaControllerFactory: KeyguardMessageAreaController.Factory
+
     @Mock
     private lateinit var mKeyguardMessageArea: KeyguardMessageArea
+
     @Mock
     private lateinit var mKeyguardMessageAreaController: KeyguardMessageAreaController
+
     @Mock
     private lateinit var mLockPatternView: LockPatternView
+
     @Mock
     private lateinit var mPostureController: DevicePostureController
 
@@ -73,15 +84,17 @@
         MockitoAnnotations.initMocks(this)
         `when`(mKeyguardPatternView.isAttachedToWindow).thenReturn(true)
         `when`(mKeyguardPatternView.findViewById<KeyguardMessageArea>(R.id.keyguard_message_area))
-                .thenReturn(mKeyguardMessageArea)
+            .thenReturn(mKeyguardMessageArea)
         `when`(mKeyguardPatternView.findViewById<LockPatternView>(R.id.lockPatternView))
-                .thenReturn(mLockPatternView)
+            .thenReturn(mLockPatternView)
         `when`(mKeyguardMessageAreaControllerFactory.create(mKeyguardMessageArea))
-                .thenReturn(mKeyguardMessageAreaController)
-        mKeyguardPatternViewController = KeyguardPatternViewController(mKeyguardPatternView,
-        mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
-                mLatencyTracker, mFalsingCollector, mEmergencyButtonController,
-                mKeyguardMessageAreaControllerFactory, mPostureController)
+            .thenReturn(mKeyguardMessageAreaController)
+        mKeyguardPatternViewController = KeyguardPatternViewController(
+            mKeyguardPatternView,
+            mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
+            mLatencyTracker, mFalsingCollector, mEmergencyButtonController,
+            mKeyguardMessageAreaControllerFactory, mPostureController
+        )
     }
 
     @Test
@@ -90,4 +103,11 @@
         mKeyguardPatternViewController.onPause()
         verify(mKeyguardMessageAreaController).setMessage("")
     }
+
+    @Test
+    fun onResume_setInitialText() {
+        mKeyguardPatternViewController.onResume(KeyguardSecurityView.SCREEN_ON)
+        verify(mKeyguardMessageAreaController)
+            .setMessageIfEmpty(R.string.keyguard_enter_your_pattern)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
index 9597cab..7bc8e8a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
@@ -113,5 +113,11 @@
         mKeyguardPinViewController.onResume(KeyguardSecurityView.SCREEN_ON);
         verify(mPasswordEntry).requestFocus();
     }
+
+    @Test
+    public void onResume_setInitialText() {
+        mKeyguardPinViewController.onResume(KeyguardSecurityView.SCREEN_ON);
+        verify(mKeyguardMessageAreaController).setMessageIfEmpty(R.string.keyguard_enter_your_pin);
+    }
 }
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index 4d33430..bc35142 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -27,7 +27,6 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -68,8 +67,6 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper()
 public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
-    private static final int VIEW_WIDTH = 1600;
-
     @Rule
     public MockitoRule mRule = MockitoJUnit.rule();
 
@@ -104,6 +101,8 @@
     @Mock
     private KeyguardMessageAreaController.Factory mKeyguardMessageAreaControllerFactory;
     @Mock
+    private KeyguardMessageAreaController mKeyguardMessageAreaController;
+    @Mock
     private KeyguardMessageArea mKeyguardMessageArea;
     @Mock
     private ConfigurationController mConfigurationController;
@@ -139,7 +138,6 @@
         when(mResources.getConfiguration()).thenReturn(mConfiguration);
         when(mView.getContext()).thenReturn(mContext);
         when(mView.getResources()).thenReturn(mResources);
-        when(mView.getWidth()).thenReturn(VIEW_WIDTH);
         when(mAdminSecondaryLockScreenControllerFactory.create(any(KeyguardSecurityCallback.class)))
                 .thenReturn(mAdminSecondaryLockScreenController);
         when(mSecurityViewFlipper.getWindowInsetsController()).thenReturn(mWindowInsetsController);
@@ -147,6 +145,8 @@
         when(mKeyguardPasswordView.getRootView()).thenReturn(mSecurityViewFlipper);
         when(mKeyguardPasswordView.findViewById(R.id.keyguard_message_area))
                 .thenReturn(mKeyguardMessageArea);
+        when(mKeyguardMessageAreaControllerFactory.create(any(KeyguardMessageArea.class)))
+                .thenReturn(mKeyguardMessageAreaController);
         when(mKeyguardPasswordView.getWindowInsetsController()).thenReturn(mWindowInsetsController);
         mKeyguardPasswordViewController = new KeyguardPasswordViewController(
                 (KeyguardPasswordView) mKeyguardPasswordView, mKeyguardUpdateMonitor,
@@ -208,49 +208,26 @@
                 mUserSwitcherController);
     }
 
-    private void touchDownLeftSide() {
+    private void touchDown() {
         mKeyguardSecurityContainerController.mGlobalTouchListener.onTouchEvent(
                 MotionEvent.obtain(
                         /* downTime= */0,
                         /* eventTime= */0,
                         MotionEvent.ACTION_DOWN,
-                        /* x= */VIEW_WIDTH / 3f,
-                        /* y= */0,
-                        /* metaState= */0));
-    }
-
-    private void touchDownRightSide() {
-        mKeyguardSecurityContainerController.mGlobalTouchListener.onTouchEvent(
-                MotionEvent.obtain(
-                        /* downTime= */0,
-                        /* eventTime= */0,
-                        MotionEvent.ACTION_DOWN,
-                        /* x= */(VIEW_WIDTH / 3f) * 2,
+                        /* x= */0,
                         /* y= */0,
                         /* metaState= */0));
     }
 
     @Test
-    public void onInterceptTap_inhibitsFalsingInOneHandedMode() {
-        when(mView.getMode()).thenReturn(MODE_ONE_HANDED);
-        when(mView.isOneHandedModeLeftAligned()).thenReturn(true);
+    public void onInterceptTap_inhibitsFalsingInSidedSecurityMode() {
 
-        touchDownLeftSide();
+        when(mView.isTouchOnTheOtherSideOfSecurity(any())).thenReturn(false);
+        touchDown();
         verify(mFalsingCollector, never()).avoidGesture();
 
-        // Now on the right.
-        touchDownRightSide();
-        verify(mFalsingCollector).avoidGesture();
-
-        // Move and re-test
-        reset(mFalsingCollector);
-        when(mView.isOneHandedModeLeftAligned()).thenReturn(false);
-
-        // On the right...
-        touchDownRightSide();
-        verify(mFalsingCollector, never()).avoidGesture();
-
-        touchDownLeftSide();
+        when(mView.isTouchOnTheOtherSideOfSecurity(any())).thenReturn(true);
+        touchDown();
         verify(mFalsingCollector).avoidGesture();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index d49f4d8..f2ac0c7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -16,6 +16,11 @@
 
 package com.android.keyguard;
 
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.provider.Settings.Global.ONE_HANDED_KEYGUARD_SIDE;
+import static android.provider.Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT;
+import static android.provider.Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.systemBars;
@@ -25,7 +30,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
@@ -34,14 +41,13 @@
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.graphics.Insets;
-import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.Gravity;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowInsets;
-import android.view.WindowInsetsController;
 import android.widget.FrameLayout;
 
 import androidx.test.filters.SmallTest;
@@ -70,6 +76,9 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper()
 public class KeyguardSecurityContainerTest extends SysuiTestCase {
+
+    private static final int VIEW_WIDTH = 1600;
+
     private int mScreenWidth;
     private int mFakeMeasureSpec;
 
@@ -77,8 +86,6 @@
     public MockitoRule mRule = MockitoJUnit.rule();
 
     @Mock
-    private WindowInsetsController mWindowInsetsController;
-    @Mock
     private KeyguardSecurityViewFlipper mSecurityViewFlipper;
     @Mock
     private GlobalSettings mGlobalSettings;
@@ -102,7 +109,6 @@
         mSecurityViewFlipperLayoutParams = new FrameLayout.LayoutParams(
                 MATCH_PARENT, MATCH_PARENT);
 
-        when(mSecurityViewFlipper.getWindowInsetsController()).thenReturn(mWindowInsetsController);
         when(mSecurityViewFlipper.getLayoutParams()).thenReturn(mSecurityViewFlipperLayoutParams);
         mKeyguardSecurityContainer = new KeyguardSecurityContainer(getContext());
         mKeyguardSecurityContainer.mSecurityViewFlipper = mSecurityViewFlipper;
@@ -212,14 +218,12 @@
         mKeyguardSecurityContainer.updatePositionByTouchX(
                 mKeyguardSecurityContainer.getWidth() - 1f);
 
-        verify(mGlobalSettings).putInt(Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
-                Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT);
-        verify(mSecurityViewFlipper).setTranslationX(
+        verify(mGlobalSettings).putInt(ONE_HANDED_KEYGUARD_SIDE, ONE_HANDED_KEYGUARD_SIDE_RIGHT);
+        assertSecurityTranslationX(
                 mKeyguardSecurityContainer.getWidth() - mSecurityViewFlipper.getWidth());
 
         mKeyguardSecurityContainer.updatePositionByTouchX(1f);
-        verify(mGlobalSettings).putInt(Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
-                Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT);
+        verify(mGlobalSettings).putInt(ONE_HANDED_KEYGUARD_SIDE, ONE_HANDED_KEYGUARD_SIDE_LEFT);
 
         verify(mSecurityViewFlipper).setTranslationX(0.0f);
     }
@@ -237,49 +241,43 @@
     }
 
     @Test
-    public void testUserSwitcherModeViewGravityLandscape() {
+    public void testUserSwitcherModeViewPositionLandscape() {
         // GIVEN one user has been setup and in landscape
         when(mUserSwitcherController.getUsers()).thenReturn(buildUserRecords(1));
-        Configuration config = new Configuration();
-        config.orientation = Configuration.ORIENTATION_LANDSCAPE;
-        when(getContext().getResources().getConfiguration()).thenReturn(config);
+        Configuration landscapeConfig = configuration(ORIENTATION_LANDSCAPE);
+        when(getContext().getResources().getConfiguration()).thenReturn(landscapeConfig);
 
         // WHEN UserSwitcherViewMode is initialized and config has changed
         setupUserSwitcher();
-        reset(mSecurityViewFlipper);
-        when(mSecurityViewFlipper.getLayoutParams()).thenReturn(mSecurityViewFlipperLayoutParams);
-        mKeyguardSecurityContainer.onConfigurationChanged(config);
+        mKeyguardSecurityContainer.onConfigurationChanged(landscapeConfig);
 
         // THEN views are oriented side by side
-        verify(mSecurityViewFlipper).setLayoutParams(mLayoutCaptor.capture());
-        assertThat(mLayoutCaptor.getValue().gravity).isEqualTo(Gravity.RIGHT | Gravity.BOTTOM);
-        ViewGroup userSwitcher = mKeyguardSecurityContainer.findViewById(
-                R.id.keyguard_bouncer_user_switcher);
-        assertThat(((FrameLayout.LayoutParams) userSwitcher.getLayoutParams()).gravity)
-                .isEqualTo(Gravity.LEFT | Gravity.CENTER_VERTICAL);
+        assertSecurityGravity(Gravity.LEFT | Gravity.BOTTOM);
+        assertUserSwitcherGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
+        assertSecurityTranslationX(
+                mKeyguardSecurityContainer.getWidth() - mSecurityViewFlipper.getWidth());
+        assertUserSwitcherTranslationX(0f);
+
     }
 
     @Test
     public void testUserSwitcherModeViewGravityPortrait() {
         // GIVEN one user has been setup and in landscape
         when(mUserSwitcherController.getUsers()).thenReturn(buildUserRecords(1));
-        Configuration config = new Configuration();
-        config.orientation = Configuration.ORIENTATION_PORTRAIT;
-        when(getContext().getResources().getConfiguration()).thenReturn(config);
+        Configuration portraitConfig = configuration(ORIENTATION_PORTRAIT);
+        when(getContext().getResources().getConfiguration()).thenReturn(portraitConfig);
 
         // WHEN UserSwitcherViewMode is initialized and config has changed
         setupUserSwitcher();
         reset(mSecurityViewFlipper);
         when(mSecurityViewFlipper.getLayoutParams()).thenReturn(mSecurityViewFlipperLayoutParams);
-        mKeyguardSecurityContainer.onConfigurationChanged(config);
+        mKeyguardSecurityContainer.onConfigurationChanged(portraitConfig);
 
         // THEN views are both centered horizontally
-        verify(mSecurityViewFlipper).setLayoutParams(mLayoutCaptor.capture());
-        assertThat(mLayoutCaptor.getValue().gravity).isEqualTo(Gravity.CENTER_HORIZONTAL);
-        ViewGroup userSwitcher = mKeyguardSecurityContainer.findViewById(
-                R.id.keyguard_bouncer_user_switcher);
-        assertThat(((FrameLayout.LayoutParams) userSwitcher.getLayoutParams()).gravity)
-                .isEqualTo(Gravity.CENTER_HORIZONTAL);
+        assertSecurityGravity(Gravity.CENTER_HORIZONTAL);
+        assertUserSwitcherGravity(Gravity.CENTER_HORIZONTAL);
+        assertSecurityTranslationX(0);
+        assertUserSwitcherTranslationX(0);
     }
 
     @Test
@@ -310,9 +308,102 @@
         assertThat(anchor.isClickable()).isTrue();
     }
 
+    @Test
+    public void testTouchesAreRecognizedAsBeingOnTheOtherSideOfSecurity() {
+        setupUserSwitcher();
+        setViewWidth(VIEW_WIDTH);
+
+        // security is on the right side by default
+        assertThat(mKeyguardSecurityContainer.isTouchOnTheOtherSideOfSecurity(
+                touchEventLeftSide())).isTrue();
+        assertThat(mKeyguardSecurityContainer.isTouchOnTheOtherSideOfSecurity(
+                touchEventRightSide())).isFalse();
+
+        // move security to the left side
+        when(mGlobalSettings.getInt(any(), anyInt())).thenReturn(ONE_HANDED_KEYGUARD_SIDE_LEFT);
+        mKeyguardSecurityContainer.onConfigurationChanged(new Configuration());
+
+        assertThat(mKeyguardSecurityContainer.isTouchOnTheOtherSideOfSecurity(
+                touchEventLeftSide())).isFalse();
+        assertThat(mKeyguardSecurityContainer.isTouchOnTheOtherSideOfSecurity(
+                touchEventRightSide())).isTrue();
+    }
+
+    @Test
+    public void testSecuritySwitchesSidesInLandscapeUserSwitcherMode() {
+        when(getContext().getResources().getConfiguration())
+                .thenReturn(configuration(ORIENTATION_LANDSCAPE));
+        setupUserSwitcher();
+
+        // switch sides
+        when(mGlobalSettings.getInt(any(), anyInt())).thenReturn(ONE_HANDED_KEYGUARD_SIDE_LEFT);
+        mKeyguardSecurityContainer.onConfigurationChanged(new Configuration());
+
+        assertSecurityTranslationX(0);
+        assertUserSwitcherTranslationX(
+                mKeyguardSecurityContainer.getWidth() - mSecurityViewFlipper.getWidth());
+    }
+
+    private Configuration configuration(@Configuration.Orientation int orientation) {
+        Configuration config = new Configuration();
+        config.orientation = orientation;
+        return config;
+    }
+
+    private void assertSecurityTranslationX(float translation) {
+        verify(mSecurityViewFlipper).setTranslationX(translation);
+    }
+
+    private void assertUserSwitcherTranslationX(float translation) {
+        ViewGroup userSwitcher = mKeyguardSecurityContainer.findViewById(
+                R.id.keyguard_bouncer_user_switcher);
+        assertThat(userSwitcher.getTranslationX()).isEqualTo(translation);
+    }
+
+    private void assertUserSwitcherGravity(@Gravity.GravityFlags int gravity) {
+        ViewGroup userSwitcher = mKeyguardSecurityContainer.findViewById(
+                R.id.keyguard_bouncer_user_switcher);
+        assertThat(((FrameLayout.LayoutParams) userSwitcher.getLayoutParams()).gravity)
+                .isEqualTo(gravity);
+    }
+
+    private void assertSecurityGravity(@Gravity.GravityFlags int gravity) {
+        verify(mSecurityViewFlipper, atLeastOnce()).setLayoutParams(mLayoutCaptor.capture());
+        assertThat(mLayoutCaptor.getValue().gravity).isEqualTo(gravity);
+    }
+
+    private void setViewWidth(int width) {
+        mKeyguardSecurityContainer.setRight(width);
+        mKeyguardSecurityContainer.setLeft(0);
+    }
+
+    private MotionEvent touchEventLeftSide() {
+        return MotionEvent.obtain(
+                /* downTime= */0,
+                /* eventTime= */0,
+                MotionEvent.ACTION_DOWN,
+                /* x= */VIEW_WIDTH / 3f,
+                /* y= */0,
+                /* metaState= */0);
+    }
+
+    private MotionEvent touchEventRightSide() {
+        return MotionEvent.obtain(
+                /* downTime= */0,
+                /* eventTime= */0,
+                MotionEvent.ACTION_DOWN,
+                /* x= */(VIEW_WIDTH / 3f) * 2,
+                /* y= */0,
+                /* metaState= */0);
+    }
+
     private void setupUserSwitcher() {
+        when(mGlobalSettings.getInt(any(), anyInt())).thenReturn(ONE_HANDED_KEYGUARD_SIDE_RIGHT);
         mKeyguardSecurityContainer.initMode(KeyguardSecurityContainer.MODE_USER_SWITCHER,
                 mGlobalSettings, mFalsingManager, mUserSwitcherController);
+        // reset mSecurityViewFlipper so setup doesn't influence test verifications
+        reset(mSecurityViewFlipper);
+        when(mSecurityViewFlipper.getLayoutParams()).thenReturn(mSecurityViewFlipperLayoutParams);
     }
 
     private ArrayList<UserRecord> buildUserRecords(int count) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
index fe2efa5..1e2074b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
@@ -15,6 +15,7 @@
 import android.view.WindowManager
 import android.widget.LinearLayout
 import androidx.test.filters.SmallTest
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.policy.DecorView
 import com.android.systemui.SysuiTestCase
 import junit.framework.Assert.assertEquals
@@ -29,6 +30,8 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 
 @SmallTest
@@ -40,12 +43,14 @@
     private val attachedViews = mutableSetOf<View>()
 
     @Mock lateinit var dreamManager: IDreamManager
+    @Mock lateinit var interactionJankMonitor: InteractionJankMonitor
     @get:Rule val rule = MockitoJUnit.rule()
 
     @Before
     fun setUp() {
         dialogLaunchAnimator = DialogLaunchAnimator(
-            dreamManager, launchAnimator, isForTesting = true)
+            dreamManager, interactionJankMonitor, launchAnimator, isForTesting = true
+        )
     }
 
     @After
@@ -90,7 +95,8 @@
 
         // The dialog content is inside this fake window view.
         assertNotNull(
-            dialogContentWithBackground.findViewByPredicate { it === dialog.contentView })
+            dialogContentWithBackground.findViewByPredicate { it === dialog.contentView }
+        )
 
         // Clicking the transparent background should dismiss the dialog.
         runOnMainThreadAndWaitForIdleSync {
@@ -161,6 +167,24 @@
         assertNotEquals(0, dialog.window.attributes.windowAnimations)
     }
 
+    @Test
+    fun testCujSpecificationLogsInteraction() {
+        val touchSurface = createTouchSurface()
+        return runOnMainThreadAndWaitForIdleSync {
+            val dialog = TestDialog(context)
+            dialogLaunchAnimator.showFromView(
+                dialog, touchSurface,
+                cuj = DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN)
+            )
+        }
+
+        verify(interactionJankMonitor).begin(
+            any()
+        )
+        verify(interactionJankMonitor)
+            .end(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN)
+    }
+
     private fun createAndShowDialog(): TestDialog {
         val touchSurface = createTouchSurface()
         return runOnMainThreadAndWaitForIdleSync {
@@ -224,4 +248,4 @@
             window.setBackgroundDrawable(windowBackground)
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
index 0fdd905..b61bda8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -468,6 +469,40 @@
         verify(mView).setUnpausedAlpha(255);
     }
 
+    @Test
+    public void testUpdatePanelExpansion_pauseAuth() {
+        // GIVEN view is attached + on the keyguard
+        mController.onViewAttached();
+        captureStatusBarStateListeners();
+        captureStatusBarExpansionListeners();
+        sendStatusBarStateChanged(StatusBarState.KEYGUARD);
+        reset(mView);
+
+        // WHEN panelViewExpansion changes to hide
+        when(mView.getUnpausedAlpha()).thenReturn(0);
+        updateStatusBarExpansion(0f, false);
+
+        // THEN pause auth is updated to PAUSE
+        verify(mView, atLeastOnce()).setPauseAuth(true);
+    }
+
+    @Test
+    public void testUpdatePanelExpansion_unpauseAuth() {
+        // GIVEN view is attached + on the keyguard + panel expansion is 0f
+        mController.onViewAttached();
+        captureStatusBarStateListeners();
+        captureStatusBarExpansionListeners();
+        sendStatusBarStateChanged(StatusBarState.KEYGUARD);
+        reset(mView);
+
+        // WHEN panelViewExpansion changes to expanded
+        when(mView.getUnpausedAlpha()).thenReturn(255);
+        updateStatusBarExpansion(1f, true);
+
+        // THEN pause auth is updated to NOT pause
+        verify(mView, atLeastOnce()).setPauseAuth(false);
+    }
+
     private void sendStatusBarStateChanged(int statusBarState) {
         mStatusBarStateListener.onStateChanged(statusBarState);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
new file mode 100644
index 0000000..a61cecb
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogTest.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+
+import androidx.test.filters.SmallTest;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.media.dialog.MediaOutputDialogFactory;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class BroadcastDialogTest extends SysuiTestCase {
+
+    private static final String SWITCH_APP = "Music";
+    private static final String TEST_PACKAGE = "com.google.android.apps.nbu.files";
+    private BroadcastDialog mBroadcastDialog;
+    private View mDialogView;
+    private TextView mSubTitle;
+    private Button mChangeOutputButton;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mBroadcastDialog = new BroadcastDialog(mContext, mock(MediaOutputDialogFactory.class),
+                SWITCH_APP, TEST_PACKAGE, mock(UiEventLogger.class));
+        mBroadcastDialog.show();
+        mDialogView = mBroadcastDialog.mDialogView;
+    }
+
+    @After
+    public void tearDown() {
+        mBroadcastDialog.dismiss();
+    }
+
+    @Test
+    public void onCreate_withCurrentApp_checkSwitchAppContent() {
+        mSubTitle = mDialogView.requireViewById(R.id.dialog_subtitle);
+
+        assertThat(mSubTitle.getText()).isEqualTo(
+                mContext.getString(R.string.bt_le_audio_broadcast_dialog_sub_title, SWITCH_APP));
+    }
+
+    @Test
+    public void onClick_withChangeOutput_dismissBroadcastDialog() {
+        mChangeOutputButton = mDialogView.requireViewById(R.id.change_output);
+        mChangeOutputButton.performClick();
+
+        assertThat(mBroadcastDialog.isShowing()).isFalse();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 3340f2f..abe7ae1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -21,7 +21,9 @@
 import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_DOCKED;
 import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE;
 import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING_BRIGHT;
 import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_SUSPEND_TRIGGERS;
 import static com.android.systemui.doze.DozeMachine.State.FINISH;
 import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
 import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
@@ -39,6 +41,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.UiModeManager;
+import android.content.res.Configuration;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.testing.AndroidTestingRunner;
 import android.testing.UiThreadTest;
@@ -50,7 +54,6 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.util.wakelock.WakeLockFake;
 
 import org.junit.Before;
@@ -70,9 +73,12 @@
     private WakefulnessLifecycle mWakefulnessLifecycle;
     @Mock
     private DozeLog mDozeLog;
-    @Mock private DockManager mDockManager;
+    @Mock
+    private DockManager mDockManager;
     @Mock
     private DozeHost mHost;
+    @Mock
+    private UiModeManager mUiModeManager;
     private DozeServiceFake mServiceFake;
     private WakeLockFake mWakeLockFake;
     private AmbientDisplayConfiguration mConfigMock;
@@ -89,7 +95,7 @@
         when(mDockManager.isHidden()).thenReturn(false);
 
         mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake,
-                mWakefulnessLifecycle, mock(BatteryController.class), mDozeLog, mDockManager,
+                mWakefulnessLifecycle, mUiModeManager, mDozeLog, mDockManager,
                 mHost, new DozeMachine.Part[]{mPartMock});
     }
 
@@ -462,4 +468,64 @@
 
         assertEquals(Display.STATE_ON, DOZE_REQUEST_PULSE.screenState(dozeParameters));
     }
+
+    @Test
+    public void testTransitionToInitialized_carModeIsEnabled() {
+        when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
+        mMachine.requestState(INITIALIZED);
+
+        verify(mPartMock).transitionTo(UNINITIALIZED, INITIALIZED);
+        verify(mPartMock).transitionTo(INITIALIZED, DOZE_SUSPEND_TRIGGERS);
+        assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
+    }
+
+    @Test
+    public void testTransitionToFinish_carModeIsEnabled() {
+        when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
+        mMachine.requestState(INITIALIZED);
+        mMachine.requestState(FINISH);
+
+        assertEquals(FINISH, mMachine.getState());
+    }
+
+    @Test
+    public void testDozeToDozeSuspendTriggers_carModeIsEnabled() {
+        when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
+        mMachine.requestState(INITIALIZED);
+        mMachine.requestState(DOZE);
+
+        assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
+    }
+
+    @Test
+    public void testDozeAoDToDozeSuspendTriggers_carModeIsEnabled() {
+        when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
+        mMachine.requestState(INITIALIZED);
+        mMachine.requestState(DOZE_AOD);
+
+        assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
+    }
+
+    @Test
+    public void testDozePulsingBrightDozeSuspendTriggers_carModeIsEnabled() {
+        when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
+        mMachine.requestState(INITIALIZED);
+        mMachine.requestState(DOZE_PULSING_BRIGHT);
+
+        assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
+    }
+
+    @Test
+    public void testDozeAodDockedDozeSuspendTriggers_carModeIsEnabled() {
+        when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
+        mMachine.requestState(INITIALIZED);
+        mMachine.requestState(DOZE_AOD_DOCKED);
+
+        assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
+    }
+
+    @Test
+    public void testDozeSuppressTriggers_screenState() {
+        assertEquals(Display.STATE_OFF, DOZE_SUSPEND_TRIGGERS.screenState(null));
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index 2e7b88d..03827da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -24,6 +24,7 @@
 import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE;
 import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING;
 import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_SUSPEND_TRIGGERS;
 import static com.android.systemui.doze.DozeMachine.State.FINISH;
 import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
 import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
@@ -182,6 +183,21 @@
     }
 
     @Test
+    public void dozeSuspendTriggers_doesNotUseLightSensor() {
+        // GIVEN the device is DOZE and the display state changes to ON
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_SUSPEND_TRIGGERS);
+        waitForSensorManager();
+
+        // WHEN new sensor event sent
+        mSensor.sendSensorEvent(3);
+
+        // THEN brightness is NOT changed, it's set to the default brightness
+        assertNotSame(3, mServiceFake.screenBrightness);
+        assertEquals(DEFAULT_BRIGHTNESS, mServiceFake.screenBrightness);
+    }
+
+    @Test
     public void aod_usesLightSensor() {
         // GIVEN the device is DOZE_AOD and the display state changes to ON
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index 0a1e45c..9ffc5a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -461,7 +461,8 @@
                     /* reportsTouchCoordinate*/ false,
                     /* requiresTouchscreen */ false,
                     /* ignoresSetting */ false,
-                    requiresTouchScreen);
+                    requiresTouchScreen,
+                    /* immediatelyReRegister */ true);
         }
 
         public TriggerSensor createDozeSensor(
@@ -477,7 +478,8 @@
                     /* reportsTouchCoordinate*/ false,
                     /* requiresTouchscreen */ false,
                     /* ignoresSetting */ false,
-                    /* requiresTouchScreen */false);
+                    /* requiresTouchScreen */ false,
+                    /* immediatelyReRegister*/ true);
         }
 
         /**
@@ -492,7 +494,8 @@
                     /* reportsTouchCoordinate*/ false,
                     /* requiresTouchscreen */ false,
                     /* ignoresSetting */ true,
-                    /* requiresProx */false,
+                    /* requiresProx */ false,
+                    /* immediatelyReRegister */ true,
                     posture);
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
index aa0a909..0f29dcd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
@@ -16,19 +16,26 @@
 
 package com.android.systemui.doze;
 
+import static android.app.UiModeManager.ACTION_ENTER_CAR_MODE;
+import static android.app.UiModeManager.ACTION_EXIT_CAR_MODE;
+
 import static com.android.systemui.doze.DozeMachine.State.DOZE;
 import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_SUSPEND_TRIGGERS;
 import static com.android.systemui.doze.DozeMachine.State.FINISH;
 import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
 import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
 
-import static org.mockito.Matchers.anyObject;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.UiModeManager;
 import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.res.Configuration;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.testing.AndroidTestingRunner;
@@ -77,7 +84,10 @@
 
     @Captor
     private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
+    @Captor
+    private ArgumentCaptor<IntentFilter> mIntentFilterCaptor;
     private BroadcastReceiver mBroadcastReceiver;
+    private IntentFilter mIntentFilter;
 
     @Captor
     private ArgumentCaptor<DozeHost.Callback> mDozeHostCaptor;
@@ -122,15 +132,59 @@
     }
 
     @Test
-    public void testEndDoze_carMode() {
+    public void testSuspendTriggersDoze_carMode() {
         // GIVEN car mode
         when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
 
         // WHEN dozing begins
         mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
 
-        // THEN doze immediately ends
-        verify(mDozeMachine).requestState(FINISH);
+        // THEN doze continues with all doze triggers disabled.
+        verify(mDozeMachine).requestState(DOZE_SUSPEND_TRIGGERS);
+    }
+
+    @Test
+    public void testSuspendTriggersDoze_enterCarMode() {
+        // GIVEN currently dozing
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+        captureBroadcastReceiver();
+        mDozeSuppressor.transitionTo(INITIALIZED, DOZE);
+
+        // WHEN car mode entered
+        mBroadcastReceiver.onReceive(null, new Intent(ACTION_ENTER_CAR_MODE));
+
+        // THEN doze continues with all doze triggers disabled.
+        verify(mDozeMachine).requestState(DOZE_SUSPEND_TRIGGERS);
+    }
+
+    @Test
+    public void testDozeResume_exitCarMode() {
+        // GIVEN currently suspended, with AOD not enabled
+        when(mConfig.alwaysOnEnabled(anyInt())).thenReturn(false);
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+        captureBroadcastReceiver();
+        mDozeSuppressor.transitionTo(INITIALIZED, DOZE_SUSPEND_TRIGGERS);
+
+        // WHEN exiting car mode
+        mBroadcastReceiver.onReceive(null, new Intent(ACTION_EXIT_CAR_MODE));
+
+        // THEN doze is resumed
+        verify(mDozeMachine).requestState(DOZE);
+    }
+
+    @Test
+    public void testDozeAoDResume_exitCarMode() {
+        // GIVEN currently suspended, with AOD not enabled
+        when(mConfig.alwaysOnEnabled(anyInt())).thenReturn(true);
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+        captureBroadcastReceiver();
+        mDozeSuppressor.transitionTo(INITIALIZED, DOZE_SUSPEND_TRIGGERS);
+
+        // WHEN exiting car mode
+        mBroadcastReceiver.onReceive(null, new Intent(ACTION_EXIT_CAR_MODE));
+
+        // THEN doze AOD is resumed
+        verify(mDozeMachine).requestState(DOZE_AOD);
     }
 
     @Test
@@ -225,7 +279,11 @@
 
     private void captureBroadcastReceiver() {
         verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(),
-                anyObject());
+                mIntentFilterCaptor.capture());
         mBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
+        mIntentFilter = mIntentFilterCaptor.getValue();
+        assertEquals(2, mIntentFilter.countActions());
+        org.hamcrest.MatcherAssert.assertThat(() -> mIntentFilter.actionsIterator(),
+                containsInAnyOrder(ACTION_ENTER_CAR_MODE, ACTION_EXIT_CAR_MODE));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 4eeb4ac..01a1a37 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -17,6 +17,8 @@
 package com.android.systemui.doze;
 
 import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
+import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
+import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyFloat;
@@ -133,7 +135,7 @@
         ArgumentCaptor<DozeHost.Callback> captor = ArgumentCaptor.forClass(DozeHost.Callback.class);
         doAnswer(invocation -> null).when(mHost).addCallback(captor.capture());
 
-        mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
+        mTriggers.transitionTo(UNINITIALIZED, DozeMachine.State.INITIALIZED);
         mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
         clearInvocations(mMachine);
 
@@ -192,8 +194,21 @@
     }
 
     @Test
+    public void transitionToDozeSuspendTriggers_disablesAllCallbacks() {
+        mTriggers.transitionTo(UNINITIALIZED, INITIALIZED);
+        when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_SUSPEND_TRIGGERS);
+
+        mTriggers.transitionTo(DozeMachine.State.INITIALIZED,
+                DozeMachine.State.DOZE_SUSPEND_TRIGGERS);
+
+        verify(mDockManager).removeListener(any());
+        verify(mBroadcastDispatcher).unregisterReceiver(any());
+        verify(mHost).removeCallback(any());
+    }
+
+    @Test
     public void testDockEventListener_registerAndUnregister() {
-        mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
+        mTriggers.transitionTo(UNINITIALIZED, DozeMachine.State.INITIALIZED);
         verify(mDockManager).addListener(any());
 
         mTriggers.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.FINISH);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
index b7de6c1..25d4c47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.dreams;
 
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -48,6 +49,8 @@
     @Mock
     StatusBarNotification mNotification2;
     @Mock
+    StatusBarNotification mNotification3;
+    @Mock
     NotificationListenerService.RankingMap mRankingMap;
 
     private DreamOverlayNotificationCountProvider mProvider;
@@ -58,6 +61,8 @@
 
         when(mNotification1.getKey()).thenReturn("key1");
         when(mNotification2.getKey()).thenReturn("key2");
+        when(mNotification3.getKey()).thenReturn("key3");
+        when(mNotification3.isOngoing()).thenReturn(true);
 
         final StatusBarNotification[] notifications = {mNotification1};
         when(mNotificationListener.getActiveNotifications()).thenReturn(notifications);
@@ -83,4 +88,13 @@
         handlerArgumentCaptor.getValue().onNotificationRemoved(mNotification1, mRankingMap);
         verify(mCallback).onNotificationCountChanged(0);
     }
+
+    @Test
+    public void testPostingOngoingNotificationDoesNotCallCallbackWithNotificationCount() {
+        final ArgumentCaptor<NotificationHandler> handlerArgumentCaptor =
+                ArgumentCaptor.forClass(NotificationHandler.class);
+        verify(mNotificationListener).addNotificationHandler(handlerArgumentCaptor.capture());
+        handlerArgumentCaptor.getValue().onNotificationPosted(mNotification3, mRankingMap);
+        verify(mCallback, never()).onNotificationCountChanged(2);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index fb64c7b..2adf285 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
@@ -207,4 +207,15 @@
             assertThat(complications.contains(weatherComplication)).isFalse();
         }
     }
+
+    @Test
+    public void testComplicationWithNoTypeNotFiltered() {
+        final Complication complication = Mockito.mock(Complication.class);
+        final DreamOverlayStateController stateController =
+                new DreamOverlayStateController(mExecutor);
+        stateController.addComplication(complication);
+        mExecutor.runAllReady();
+        assertThat(stateController.getComplications(true).contains(complication))
+                .isTrue();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
index 3c28d48..d334694 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
@@ -57,6 +57,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.Optional;
 import java.util.concurrent.Executor;
 
 @SmallTest
@@ -115,7 +116,7 @@
                 mNextAlarmController,
                 mDateFormatUtil,
                 mSensorPrivacyController,
-                mDreamOverlayNotificationCountProvider,
+                Optional.of(mDreamOverlayNotificationCountProvider),
                 mZenModeController,
                 mStatusBarWindowStateController);
     }
@@ -231,6 +232,26 @@
     }
 
     @Test
+    public void testNotificationsIconNotShownWhenCountProviderAbsent() {
+        DreamOverlayStatusBarViewController controller = new DreamOverlayStatusBarViewController(
+                mView,
+                mResources,
+                mMainExecutor,
+                mConnectivityManager,
+                mTouchSession,
+                mAlarmManager,
+                mNextAlarmController,
+                mDateFormatUtil,
+                mSensorPrivacyController,
+                Optional.empty(),
+                mZenModeController,
+                mStatusBarWindowStateController);
+        controller.onViewAttached();
+        verify(mView, never()).showIcon(
+                eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(true), any());
+    }
+
+    @Test
     public void testOnViewAttachedShowsPriorityModeIconWhenEnabled() {
         when(mZenModeController.getZen()).thenReturn(
                 Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
index ed1cf69..964e6d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.systemui.dreams;
 
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -23,11 +25,14 @@
 import android.app.smartspace.SmartspaceTarget;
 import android.content.Context;
 import android.testing.AndroidTestingRunner;
+import android.view.View;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dreams.smartspace.DreamsSmartspaceController;
+import com.android.systemui.dreams.complication.Complication;
+import com.android.systemui.dreams.complication.ComplicationViewModel;
+import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 
 import org.junit.Before;
@@ -47,7 +52,7 @@
     private Context mContext;
 
     @Mock
-    private DreamsSmartspaceController mSmartspaceController;
+    private DreamSmartspaceController mSmartspaceController;
 
     @Mock
     private DreamOverlayStateController mDreamOverlayStateController;
@@ -55,25 +60,79 @@
     @Mock
     private SmartSpaceComplication mComplication;
 
+    @Mock
+    private ComplicationViewModel mComplicationViewModel;
+
+    @Mock
+    private View mBcSmartspaceView;
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
     }
 
     /**
-     * Ensures {@link SmartSpaceComplication} is only registered when it is available.
+     * Ensures {@link SmartSpaceComplication} isn't registered right away on start.
      */
     @Test
-    public void testAvailability() {
+    public void testRegistrantStart_doesNotAddComplication() {
+        final SmartSpaceComplication.Registrant registrant = getRegistrant();
+        registrant.start();
+        verify(mDreamOverlayStateController, never()).addComplication(eq(mComplication));
+    }
 
-        final SmartSpaceComplication.Registrant registrant = new SmartSpaceComplication.Registrant(
+    private SmartSpaceComplication.Registrant getRegistrant() {
+        return new SmartSpaceComplication.Registrant(
                 mContext,
                 mDreamOverlayStateController,
                 mComplication,
                 mSmartspaceController);
-        registrant.start();
-        verify(mDreamOverlayStateController, never()).addComplication(eq(mComplication));
+    }
 
+    @Test
+    public void testOverlayActive_addsTargetListener() {
+        final SmartSpaceComplication.Registrant registrant = getRegistrant();
+        registrant.start();
+
+        final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor =
+                ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
+        verify(mDreamOverlayStateController).addCallback(dreamCallbackCaptor.capture());
+
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+        dreamCallbackCaptor.getValue().onStateChanged();
+
+        // Test
+        final ArgumentCaptor<BcSmartspaceDataPlugin.SmartspaceTargetListener> listenerCaptor =
+                ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
+        verify(mSmartspaceController).addListener(listenerCaptor.capture());
+    }
+
+    @Test
+    public void testOverlayActive_targetsNonEmpty_addsComplication() {
+        final SmartSpaceComplication.Registrant registrant = getRegistrant();
+        registrant.start();
+
+        final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor =
+                ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
+        verify(mDreamOverlayStateController).addCallback(dreamCallbackCaptor.capture());
+
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+        dreamCallbackCaptor.getValue().onStateChanged();
+
+        final ArgumentCaptor<BcSmartspaceDataPlugin.SmartspaceTargetListener> listenerCaptor =
+                ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
+        verify(mSmartspaceController).addListener(listenerCaptor.capture());
+
+        // Test
+        final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
+        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
+        verify(mDreamOverlayStateController).addComplication(eq(mComplication));
+    }
+
+    @Test
+    public void testOverlayActive_targetsEmpty_removesComplication() {
+        final SmartSpaceComplication.Registrant registrant = getRegistrant();
+        registrant.start();
 
         final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor =
                 ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
@@ -89,5 +148,45 @@
         final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
         listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
         verify(mDreamOverlayStateController).addComplication(eq(mComplication));
+
+        // Test
+        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList());
+        verify(mDreamOverlayStateController).removeComplication(eq(mComplication));
+    }
+
+    @Test
+    public void testOverlayInActive_removesTargetListener_removesComplication() {
+        final SmartSpaceComplication.Registrant registrant = getRegistrant();
+        registrant.start();
+
+        final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor =
+                ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
+        verify(mDreamOverlayStateController).addCallback(dreamCallbackCaptor.capture());
+
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+        dreamCallbackCaptor.getValue().onStateChanged();
+
+        final ArgumentCaptor<BcSmartspaceDataPlugin.SmartspaceTargetListener> listenerCaptor =
+                ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
+        verify(mSmartspaceController).addListener(listenerCaptor.capture());
+
+        final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
+        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
+        verify(mDreamOverlayStateController).addComplication(eq(mComplication));
+
+        // Test
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(false);
+        dreamCallbackCaptor.getValue().onStateChanged();
+        verify(mSmartspaceController).removeListener(listenerCaptor.getValue());
+        verify(mDreamOverlayStateController).removeComplication(eq(mComplication));
+    }
+
+    @Test
+    public void testGetView_reusesSameView() {
+        final SmartSpaceComplication complication = new SmartSpaceComplication(getContext(),
+                mSmartspaceController);
+        final Complication.ViewHolder viewHolder = complication.createView(mComplicationViewModel);
+        when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mBcSmartspaceView);
+        assertEquals(viewHolder.getView(), viewHolder.getView());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/AirQualityColorPickerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/AirQualityColorPickerTest.java
new file mode 100644
index 0000000..33be5dc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/AirQualityColorPickerTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams.complication;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class AirQualityColorPickerTest extends SysuiTestCase {
+    private static final int DEFAULT_COLOR = 0;
+    private static final int MOCK_COLOR_1 = 1;
+    private static final int MOCK_COLOR_2 = 2;
+    private static final int MOCK_COLOR_3 = 3;
+    private static final int MOCK_COLOR_4 = 4;
+    private static final int MOCK_COLOR_5 = 5;
+
+    private static final int[] MOCK_THRESHOLDS = {-1, 100, 200, 201, 500};
+    private static final int[] MOCK_COLORS =
+            {MOCK_COLOR_1, MOCK_COLOR_2, MOCK_COLOR_3, MOCK_COLOR_4, MOCK_COLOR_5};
+    private static final int[] EMPTY_ARRAY = {};
+
+    @Test
+    public void testEmptyThresholds() {
+        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
+                EMPTY_ARRAY,
+                MOCK_COLORS,
+                DEFAULT_COLOR);
+        assertThat(colorPicker.getColorForValue("110 AQI")).isEqualTo(DEFAULT_COLOR);
+    }
+
+    @Test
+    public void testEmptyColors() {
+        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
+                MOCK_THRESHOLDS,
+                EMPTY_ARRAY,
+                DEFAULT_COLOR);
+        assertThat(colorPicker.getColorForValue("110 AQI")).isEqualTo(DEFAULT_COLOR);
+    }
+
+    @Test
+    public void testEmptyAqiString() {
+        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
+                MOCK_THRESHOLDS,
+                MOCK_COLORS,
+                DEFAULT_COLOR);
+        assertThat(colorPicker.getColorForValue("")).isEqualTo(DEFAULT_COLOR);
+    }
+
+    @Test
+    public void testInvalidAqiString() {
+        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
+                MOCK_THRESHOLDS,
+                MOCK_COLORS,
+                DEFAULT_COLOR);
+        assertThat(colorPicker.getColorForValue("invalid")).isEqualTo(DEFAULT_COLOR);
+    }
+
+    @Test
+    public void testZeroAirQuality() {
+        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
+                MOCK_THRESHOLDS,
+                MOCK_COLORS,
+                DEFAULT_COLOR);
+        assertThat(colorPicker.getColorForValue("0 AQI")).isEqualTo(MOCK_COLOR_1);
+    }
+
+    @Test
+    public void testVeryLargeAirQuality() {
+        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
+                MOCK_THRESHOLDS,
+                MOCK_COLORS,
+                DEFAULT_COLOR);
+        assertThat(colorPicker.getColorForValue("100000 AQI")).isEqualTo(MOCK_COLOR_5);
+    }
+
+    @Test
+    public void testAirQuality200() {
+        final AirQualityColorPicker colorPicker = new AirQualityColorPicker(
+                MOCK_THRESHOLDS,
+                MOCK_COLORS,
+                DEFAULT_COLOR);
+        assertThat(colorPicker.getColorForValue("200 AQI")).isEqualTo(MOCK_COLOR_2);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamAirQualityComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamAirQualityComplicationTest.java
new file mode 100644
index 0000000..b8a7059
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamAirQualityComplicationTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams.complication;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.testing.AndroidTestingRunner;
+import android.widget.TextView;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.dreams.complication.DreamAirQualityComplication.DreamAirQualityViewController;
+import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
+import com.android.systemui.plugins.ActivityStarter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class DreamAirQualityComplicationTest extends SysuiTestCase {
+    private static final String TRAMPOLINE_COMPONENT = "TestComponent";
+
+    @Mock
+    private DreamSmartspaceController mDreamSmartspaceController;
+
+    @Mock
+    private DreamOverlayStateController mDreamOverlayStateController;
+
+    @Mock
+    private DreamAirQualityComplication mComplication;
+
+    @Mock
+    private AirQualityColorPicker mColorPicker;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    /**
+     * Ensures {@link DreamAirQualityComplication} is registered.
+     */
+    @Test
+    public void testComplicationRegistered() {
+        final DreamAirQualityComplication.Registrant registrant =
+                new DreamAirQualityComplication.Registrant(
+                        mContext,
+                        mDreamOverlayStateController,
+                        mComplication);
+        registrant.start();
+        verify(mDreamOverlayStateController).addComplication(eq(mComplication));
+    }
+
+    @Test
+    public void testGetUnfilteredTargets() {
+        final DreamAirQualityViewController controller =
+                new DreamAirQualityViewController(
+                        mock(TextView.class),
+                        mDreamSmartspaceController,
+                        TRAMPOLINE_COMPONENT,
+                        mock(ActivityStarter.class),
+                        mColorPicker);
+        controller.onViewAttached();
+        verify(mDreamSmartspaceController).addUnfilteredListener(any());
+        controller.onViewDetached();
+        verify(mDreamSmartspaceController).removeUnfilteredListener(any());
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java
index 151742a..883bec46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java
@@ -17,18 +17,19 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.testing.AndroidTestingRunner;
+import android.widget.TextView;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dreams.DreamOverlayStateController;
-import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
+import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
+import com.android.systemui.plugins.ActivityStarter;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -39,12 +40,14 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 public class DreamWeatherComplicationTest extends SysuiTestCase {
+    private static final String TRAMPOLINE_COMPONENT = "TestComponent";
+
     @SuppressWarnings("HidingField")
     @Mock
     private Context mContext;
 
     @Mock
-    private LockscreenSmartspaceController mSmartspaceController;
+    private DreamSmartspaceController mDreamSmartspaceController;
 
     @Mock
     private DreamOverlayStateController mDreamOverlayStateController;
@@ -58,22 +61,28 @@
     }
 
     /**
-     * Ensures {@link DreamWeatherComplication} is only registered when it is available.
+     * Ensures {@link DreamWeatherComplication} is registered.
      */
     @Test
-    public void testComplicationAvailability() {
-        when(mSmartspaceController.isEnabled()).thenReturn(false);
+    public void testComplicationRegistered() {
         final DreamWeatherComplication.Registrant registrant =
                 new DreamWeatherComplication.Registrant(
                         mContext,
-                        mSmartspaceController,
                         mDreamOverlayStateController,
                         mComplication);
         registrant.start();
-        verify(mDreamOverlayStateController, never()).addComplication(any());
-
-        when(mSmartspaceController.isEnabled()).thenReturn(true);
-        registrant.start();
         verify(mDreamOverlayStateController).addComplication(eq(mComplication));
     }
+
+    @Test
+    public void testGetUnfilteredTargets() {
+        final DreamWeatherComplication.DreamWeatherViewController controller =
+                new DreamWeatherComplication.DreamWeatherViewController(mock(
+                        TextView.class), TRAMPOLINE_COMPONENT, mock(ActivityStarter.class),
+                        mDreamSmartspaceController);
+        controller.onViewAttached();
+        verify(mDreamSmartspaceController).addUnfilteredListener(any());
+        controller.onViewDetached();
+        verify(mDreamSmartspaceController).removeUnfilteredListener(any());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index 89c82fb..c3fca29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -422,7 +422,29 @@
         verify(mUiEventLogger).log(BouncerSwipeTouchHandler.DreamEvent.DREAM_BOUNCER_FULLY_VISIBLE);
     }
 
+    /**
+     * Ensures {@link CentralSurfaces}
+     */
+    @Test
+    public void testInformBouncerShowingOnExpand() {
+        swipeToPosition(1f, Direction.UP, 0);
+    }
+
+    /**
+     * Ensures {@link CentralSurfaces}
+     */
+    @Test
+    public void testInformBouncerHidingOnCollapse() {
+        // Must swipe up to set initial state.
+        swipeToPosition(1f, Direction.UP, 0);
+        Mockito.clearInvocations(mCentralSurfaces);
+
+        swipeToPosition(0f, Direction.DOWN, 0);
+    }
+
+
     private void swipeToPosition(float percent, Direction direction, float velocityY) {
+        Mockito.clearInvocations(mTouchSession);
         mTouchHandler.onSessionStart(mTouchSession);
         ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
                 ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/HideComplicationTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/HideComplicationTouchHandlerTest.java
index 0a02133..14a5702 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/HideComplicationTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/HideComplicationTouchHandlerTest.java
@@ -35,6 +35,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dreams.complication.Complication;
 import com.android.systemui.shared.system.InputChannelCompat;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.touch.TouchInsetManager;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
@@ -59,6 +60,9 @@
     TouchInsetManager mTouchInsetManager;
 
     @Mock
+    StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+
+    @Mock
     Handler mHandler;
 
     @Mock
@@ -83,12 +87,45 @@
                 mVisibilityController,
                 RESTORE_TIMEOUT,
                 mTouchInsetManager,
+                mStatusBarKeyguardViewManager,
                 mFakeExecutor,
                 mHandler);
 
         // Report multiple active sessions.
         when(mSession.getActiveSessionCount()).thenReturn(2);
 
+        // Bouncer hidden.
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+
+        // Start session.
+        touchHandler.onSessionStart(mSession);
+
+        // Verify session end.
+        verify(mSession).pop();
+
+        // Verify no interaction with visibility controller.
+        verify(mVisibilityController, never()).setVisibility(anyInt(), anyBoolean());
+    }
+
+    /**
+     * Ensures no actions are taken when the bouncer is showing.
+     */
+    @Test
+    public void testSessionEndWhenBouncerShowing() {
+        final HideComplicationTouchHandler touchHandler = new HideComplicationTouchHandler(
+                mVisibilityController,
+                RESTORE_TIMEOUT,
+                mTouchInsetManager,
+                mStatusBarKeyguardViewManager,
+                mFakeExecutor,
+                mHandler);
+
+        // Report one session.
+        when(mSession.getActiveSessionCount()).thenReturn(1);
+
+        // Bouncer is showing.
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+
         // Start session.
         touchHandler.onSessionStart(mSession);
 
@@ -108,12 +145,16 @@
                 mVisibilityController,
                 RESTORE_TIMEOUT,
                 mTouchInsetManager,
+                mStatusBarKeyguardViewManager,
                 mFakeExecutor,
                 mHandler);
 
         // Report one session
         when(mSession.getActiveSessionCount()).thenReturn(1);
 
+        // Bouncer hidden.
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+
         // Start session
         touchHandler.onSessionStart(mSession);
 
@@ -149,12 +190,16 @@
                 mVisibilityController,
                 RESTORE_TIMEOUT,
                 mTouchInsetManager,
+                mStatusBarKeyguardViewManager,
                 mFakeExecutor,
                 mHandler);
 
         // Report one session
         when(mSession.getActiveSessionCount()).thenReturn(1);
 
+        // Bouncer hidden.
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+
         // Start session
         touchHandler.onSessionStart(mSession);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
index b43856a..51f3404 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.statusbar.commandline.Command
 import com.android.systemui.statusbar.commandline.CommandRegistry
+import com.android.systemui.util.DeviceConfigProxyFake
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.capture
@@ -75,6 +76,7 @@
     private lateinit var broadcastReceiver: BroadcastReceiver
     private lateinit var clearCacheAction: Consumer<Int>
 
+    private val deviceConfig = DeviceConfigProxyFake()
     private val teamfoodableFlagA = BooleanFlag(500, false, true)
     private val teamfoodableFlagB = BooleanFlag(501, true, true)
 
@@ -90,6 +92,7 @@
             systemProperties,
             resources,
             dumpManager,
+            deviceConfig,
             flagMap,
             commandRegistry,
             barService
@@ -195,6 +198,21 @@
     }
 
     @Test
+    fun testReadDeviceConfigBooleanFlag() {
+        val namespace = "test_namespace"
+        deviceConfig.setProperty(namespace, "a", "true", false)
+        deviceConfig.setProperty(namespace, "b", "false", false)
+        deviceConfig.setProperty(namespace, "c", null, false)
+
+        assertThat(mFeatureFlagsDebug.isEnabled(DeviceConfigBooleanFlag(1, "a", namespace)))
+            .isTrue()
+        assertThat(mFeatureFlagsDebug.isEnabled(DeviceConfigBooleanFlag(2, "b", namespace)))
+            .isFalse()
+        assertThat(mFeatureFlagsDebug.isEnabled(DeviceConfigBooleanFlag(3, "c", namespace)))
+            .isFalse()
+    }
+
+    @Test
     fun testReadStringFlag() {
         whenever(flagManager.readFlagValue<String>(eq(3), any())).thenReturn("foo")
         whenever(flagManager.readFlagValue<String>(eq(4), any())).thenReturn("bar")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
index b5deb0b..6b683f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
@@ -20,6 +20,7 @@
 import android.test.suitebuilder.annotation.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.util.DeviceConfigProxyFake
 import com.android.systemui.util.mockito.any
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
@@ -44,10 +45,13 @@
     @Mock private lateinit var mSystemProperties: SystemPropertiesHelper
     @Mock private lateinit var mDumpManager: DumpManager
 
+    private val deviceConfig = DeviceConfigProxyFake()
+
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
-        mFeatureFlagsRelease = FeatureFlagsRelease(mResources, mSystemProperties, mDumpManager)
+        mFeatureFlagsRelease = FeatureFlagsRelease(mResources, mSystemProperties, deviceConfig,
+            mDumpManager)
     }
 
     @After
@@ -85,6 +89,21 @@
     }
 
     @Test
+    fun testReadDeviceConfigBooleanFlag() {
+        val namespace = "test_namespace"
+        deviceConfig.setProperty(namespace, "a", "true", false)
+        deviceConfig.setProperty(namespace, "b", "false", false)
+        deviceConfig.setProperty(namespace, "c", null, false)
+
+        assertThat(mFeatureFlagsRelease.isEnabled(DeviceConfigBooleanFlag(1, "a", namespace)))
+            .isTrue()
+        assertThat(mFeatureFlagsRelease.isEnabled(DeviceConfigBooleanFlag(2, "b", namespace)))
+            .isFalse()
+        assertThat(mFeatureFlagsRelease.isEnabled(DeviceConfigBooleanFlag(3, "c", namespace)))
+            .isFalse()
+    }
+
+    @Test
     fun testSysPropBooleanFlag() {
         val flagId = 213
         val flagName = "sys_prop_flag"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
index f00fbe6..141a213 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 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.spy;
@@ -480,4 +481,13 @@
         // hide dialog again
         mGlobalActionsDialogLite.showOrHideDialog(true, true, null /* view */);
     }
+
+    @Test
+    public void testBugreportAction_whenDebugMode_shouldOfferBugreportButtonBeforeProvisioning() {
+        doReturn(1).when(mGlobalSettings).getInt(anyString(), anyInt());
+
+        GlobalActionsDialogLite.BugReportAction bugReportAction =
+                mGlobalActionsDialogLite.makeBugReportActionForTesting();
+        assertThat(bugReportAction.showBeforeProvisioning()).isTrue();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index 241ed24..540f2a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -58,6 +58,7 @@
 import com.android.systemui.ActivityIntentHelper
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.bluetooth.BroadcastDialogController
 import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.media.MediaControlPanel.KEY_SMARTSPACE_APP_NAME
 import com.android.systemui.media.dialog.MediaOutputDialogFactory
@@ -104,6 +105,7 @@
 private const val SESSION_TITLE = "SESSION_TITLE"
 private const val DISABLED_DEVICE_NAME = "DISABLED_DEVICE_NAME"
 private const val REC_APP_NAME = "REC APP NAME"
+private const val APP_NAME = "APP_NAME"
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -130,6 +132,7 @@
     @Mock private lateinit var mediaCarouselController: MediaCarouselController
     @Mock private lateinit var falsingManager: FalsingManager
     @Mock private lateinit var transitionParent: ViewGroup
+    @Mock private lateinit var broadcastDialogController: BroadcastDialogController
     private lateinit var appIcon: ImageView
     @Mock private lateinit var albumView: ImageView
     private lateinit var titleText: TextView
@@ -160,8 +163,9 @@
     private lateinit var dismissText: TextView
 
     private lateinit var session: MediaSession
-    private val device = MediaDeviceData(true, null, DEVICE_NAME)
-    private val disabledDevice = MediaDeviceData(false, null, DISABLED_DEVICE_NAME)
+    private lateinit var device: MediaDeviceData
+    private val disabledDevice = MediaDeviceData(false, null, DISABLED_DEVICE_NAME, null,
+            showBroadcastButton = false)
     private lateinit var mediaData: MediaData
     private val clock = FakeSystemClock()
     @Mock private lateinit var logger: MediaUiEventLogger
@@ -187,6 +191,7 @@
     private lateinit var recSubtitle1: TextView
     private lateinit var recSubtitle2: TextView
     private lateinit var recSubtitle3: TextView
+    private var shouldShowBroadcastButton: Boolean = false
 
     @JvmField @Rule val mockito = MockitoJUnit.rule()
 
@@ -223,7 +228,8 @@
             logger,
             keyguardStateController,
             activityIntentHelper,
-            lockscreenUserManager) {
+            lockscreenUserManager,
+            broadcastDialogController) {
                 override fun loadAnimator(
                     animId: Int,
                     otionInterpolator: Interpolator,
@@ -236,28 +242,7 @@
         initGutsViewHolderMocks()
         initMediaViewHolderMocks()
 
-        // Create media session
-        val metadataBuilder = MediaMetadata.Builder().apply {
-            putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST)
-            putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE)
-        }
-        val playbackBuilder = PlaybackState.Builder().apply {
-            setState(PlaybackState.STATE_PAUSED, 6000L, 1f)
-            setActions(PlaybackState.ACTION_PLAY)
-        }
-        session = MediaSession(context, SESSION_KEY).apply {
-            setMetadata(metadataBuilder.build())
-            setPlaybackState(playbackBuilder.build())
-        }
-        session.setActive(true)
-
-        mediaData = MediaTestUtils.emptyMediaData.copy(
-                artist = ARTIST,
-                song = TITLE,
-                packageName = PACKAGE,
-                token = session.sessionToken,
-                device = device,
-                instanceId = instanceId)
+        initDeviceMediaData(false, DEVICE_NAME)
 
         // Set up recommendation view
         initRecommendationViewHolderMocks()
@@ -293,6 +278,34 @@
         whenever(gutsViewHolder.dismissText).thenReturn(dismissText)
     }
 
+    private fun initDeviceMediaData(shouldShowBroadcastButton: Boolean, name: String) {
+        device = MediaDeviceData(true, null, name, null,
+                showBroadcastButton = shouldShowBroadcastButton)
+
+        // Create media session
+        val metadataBuilder = MediaMetadata.Builder().apply {
+            putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST)
+            putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE)
+        }
+        val playbackBuilder = PlaybackState.Builder().apply {
+            setState(PlaybackState.STATE_PAUSED, 6000L, 1f)
+            setActions(PlaybackState.ACTION_PLAY)
+        }
+        session = MediaSession(context, SESSION_KEY).apply {
+            setMetadata(metadataBuilder.build())
+            setPlaybackState(playbackBuilder.build())
+        }
+        session.setActive(true)
+
+        mediaData = MediaTestUtils.emptyMediaData.copy(
+                artist = ARTIST,
+                song = TITLE,
+                packageName = PACKAGE,
+                token = session.sessionToken,
+                device = device,
+                instanceId = instanceId)
+    }
+
     /**
      * Initialize elements in media view holder
      */
@@ -1032,6 +1045,28 @@
         assertThat(seamless.isEnabled()).isFalse()
     }
 
+    @Test
+    fun bindBroadcastButton() {
+        initMediaViewHolderMocks()
+        initDeviceMediaData(true, APP_NAME)
+
+        val mockAvd0 = mock(AnimatedVectorDrawable::class.java)
+        whenever(mockAvd0.mutate()).thenReturn(mockAvd0)
+        val semanticActions0 = MediaButton(
+                playOrPause = MediaAction(mockAvd0, Runnable {}, "play", null)
+        )
+        val state = mediaData.copy(resumption = true, semanticActions = semanticActions0,
+                isPlaying = false)
+        player.attachPlayer(viewHolder)
+        player.bindPlayer(state, PACKAGE)
+        assertThat(seamlessText.getText()).isEqualTo(APP_NAME)
+        assertThat(seamless.isEnabled()).isTrue()
+
+        seamless.callOnClick()
+
+        verify(logger).logOpenBroadcastDialog(anyInt(), eq(PACKAGE), eq(instanceId))
+    }
+
     /* ***** Guts tests for the player ***** */
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
index 3e335c5..04b93d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
@@ -79,7 +79,7 @@
                 new ArrayList<>(), new ArrayList<>(), null, PACKAGE, null, null, null, true, null,
                 MediaData.PLAYBACK_LOCAL, false, KEY, false, false, false, 0L,
                 InstanceId.fakeInstanceId(-1), -1);
-        mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME);
+        mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME, null, false);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
index 187210a..ee10426 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
@@ -16,6 +16,10 @@
 
 package com.android.systemui.media
 
+import android.bluetooth.BluetoothLeBroadcast
+import android.bluetooth.BluetoothLeBroadcastMetadata
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
 import android.graphics.drawable.Drawable
 import android.media.MediaRouter2Manager
 import android.media.RoutingSessionInfo
@@ -25,8 +29,12 @@
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast
+import com.android.settingslib.bluetooth.LocalBluetoothManager
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager
 import com.android.settingslib.media.LocalMediaManager
 import com.android.settingslib.media.MediaDevice
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManager
@@ -42,6 +50,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
 import org.mockito.Mockito.any
 import org.mockito.Mockito.mock
@@ -60,6 +69,8 @@
 private const val DEVICE_ID = "DEVICE_ID"
 private const val DEVICE_NAME = "DEVICE_NAME"
 private const val REMOTE_DEVICE_NAME = "REMOTE_DEVICE_NAME"
+private const val BROADCAST_APP_NAME = "BROADCAST_APP_NAME"
+private const val NORMAL_APP_NAME = "NORMAL_APP_NAME"
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -83,6 +94,12 @@
     @Mock private lateinit var controller: MediaController
     @Mock private lateinit var playbackInfo: PlaybackInfo
     @Mock private lateinit var configurationController: ConfigurationController
+    @Mock private lateinit var bluetoothLeBroadcast: BluetoothLeBroadcast
+    @Mock private lateinit var localBluetoothProfileManager: LocalBluetoothProfileManager
+    @Mock private lateinit var localBluetoothLeBroadcast: LocalBluetoothLeBroadcast
+    @Mock private lateinit var packageManager: PackageManager
+    @Mock private lateinit var applicationInfo: ApplicationInfo
+    private lateinit var localBluetoothManager: LocalBluetoothManager
     private lateinit var session: MediaSession
     private lateinit var mediaData: MediaData
     @JvmField @Rule val mockito = MockitoJUnit.rule()
@@ -91,12 +108,15 @@
     fun setUp() {
         fakeFgExecutor = FakeExecutor(FakeSystemClock())
         fakeBgExecutor = FakeExecutor(FakeSystemClock())
+        localBluetoothManager = mDependency.injectMockDependency(LocalBluetoothManager::class.java)
         manager = MediaDeviceManager(
+                context,
                 controllerFactory,
                 lmmFactory,
                 mr2,
                 muteAwaitFactory,
                 configurationController,
+                localBluetoothManager,
                 fakeFgExecutor,
                 fakeBgExecutor,
                 dumpster
@@ -119,6 +139,7 @@
                 token = session.sessionToken)
         whenever(controllerFactory.create(session.sessionToken))
                 .thenReturn(controller)
+        setupLeAudioConfiguration(false)
     }
 
     @After
@@ -545,7 +566,8 @@
     @Test
     fun testRemotePlaybackDeviceOverride() {
         whenever(route.name).thenReturn(DEVICE_NAME)
-        val deviceData = MediaDeviceData(false, null, REMOTE_DEVICE_NAME, null)
+        val deviceData = MediaDeviceData(false, null, REMOTE_DEVICE_NAME, null,
+                showBroadcastButton = false)
         val mediaDataWithDevice = mediaData.copy(device = deviceData)
 
         // GIVEN media data that already has a device set
@@ -560,12 +582,95 @@
         verify(lmm, never()).registerCallback(any())
     }
 
+    @Test
+    fun onBroadcastStarted_currentMediaDeviceDataIsBroadcasting() {
+        val broadcastCallback = setupBroadcastCallback()
+        setupLeAudioConfiguration(true)
+        setupBroadcastPackage(BROADCAST_APP_NAME)
+        broadcastCallback.onBroadcastStarted(1, 1)
+
+        manager.onMediaDataLoaded(KEY, null, mediaData)
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+
+        val data = captureDeviceData(KEY)
+        assertThat(data.showBroadcastButton).isTrue()
+        assertThat(data.enabled).isTrue()
+        assertThat(data.name).isEqualTo(context.getString(
+                R.string.broadcasting_description_is_broadcasting))
+    }
+
+    @Test
+    fun onBroadcastStarted_currentMediaDeviceDataIsNotBroadcasting() {
+        val broadcastCallback = setupBroadcastCallback()
+        setupLeAudioConfiguration(true)
+        setupBroadcastPackage(NORMAL_APP_NAME)
+        broadcastCallback.onBroadcastStarted(1, 1)
+
+        manager.onMediaDataLoaded(KEY, null, mediaData)
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+
+        val data = captureDeviceData(KEY)
+        assertThat(data.showBroadcastButton).isTrue()
+        assertThat(data.enabled).isTrue()
+        assertThat(data.name).isEqualTo(BROADCAST_APP_NAME)
+    }
+
+    @Test
+    fun onBroadcastStopped_bluetoothLeBroadcastIsDisabledAndBroadcastingButtonIsGone() {
+        val broadcastCallback = setupBroadcastCallback()
+        setupLeAudioConfiguration(false)
+        broadcastCallback.onBroadcastStopped(1, 1)
+
+        manager.onMediaDataLoaded(KEY, null, mediaData)
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+
+        val data = captureDeviceData(KEY)
+        assertThat(data.showBroadcastButton).isFalse()
+    }
+
     fun captureCallback(): LocalMediaManager.DeviceCallback {
         val captor = ArgumentCaptor.forClass(LocalMediaManager.DeviceCallback::class.java)
         verify(lmm).registerCallback(captor.capture())
         return captor.getValue()
     }
 
+    fun setupBroadcastCallback(): BluetoothLeBroadcast.Callback {
+        val callback: BluetoothLeBroadcast.Callback = object : BluetoothLeBroadcast.Callback {
+            override fun onBroadcastStarted(reason: Int, broadcastId: Int) {}
+            override fun onBroadcastStartFailed(reason: Int) {}
+            override fun onBroadcastStopped(reason: Int, broadcastId: Int) {}
+            override fun onBroadcastStopFailed(reason: Int) {}
+            override fun onPlaybackStarted(reason: Int, broadcastId: Int) {}
+            override fun onPlaybackStopped(reason: Int, broadcastId: Int) {}
+            override fun onBroadcastUpdated(reason: Int, broadcastId: Int) {}
+            override fun onBroadcastUpdateFailed(reason: Int, broadcastId: Int) {}
+            override fun onBroadcastMetadataChanged(broadcastId: Int,
+                                                    metadata: BluetoothLeBroadcastMetadata) {}
+        }
+
+        bluetoothLeBroadcast.registerCallback(fakeFgExecutor, callback)
+        return callback;
+    }
+
+    fun setupLeAudioConfiguration(isLeAudio: Boolean) {
+        whenever(localBluetoothManager.profileManager).thenReturn(localBluetoothProfileManager)
+        whenever(localBluetoothProfileManager.leAudioBroadcastProfile)
+                .thenReturn(localBluetoothLeBroadcast)
+        whenever(localBluetoothLeBroadcast.isEnabled(any())).thenReturn(isLeAudio)
+        whenever(localBluetoothLeBroadcast.appSourceName).thenReturn(BROADCAST_APP_NAME)
+    }
+
+    fun setupBroadcastPackage(currentName: String) {
+        whenever(lmm.packageName).thenReturn(PACKAGE)
+        whenever(packageManager.getApplicationInfo(eq(PACKAGE), anyInt()))
+                .thenReturn(applicationInfo)
+        whenever(packageManager.getApplicationLabel(applicationInfo)).thenReturn(currentName)
+        context.setMockPackageManager(packageManager)
+    }
+
     fun captureDeviceData(key: String, oldKey: String? = null): MediaDeviceData {
         val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java)
         verify(listener).onMediaDeviceChanged(eq(key), eq(oldKey), captor.capture())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt
index ae58fe6..3d9ed5f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt
@@ -20,7 +20,8 @@
             device = null,
             active = true,
             resumeAction = null,
+            isPlaying = false,
             instanceId = InstanceId.fakeInstanceId(-1),
             appUid = -1)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index ef0fc95..c45db05 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -140,16 +140,31 @@
         mFeatures.add(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK);
 
         assertThat(mMediaOutputDialog.getStopButtonVisibility()).isEqualTo(View.VISIBLE);
+    }
 
-        mFeatures.clear();
+    @Test
+    public void getStopButtonVisibility_remoteBLEDevice_returnVisible() {
         when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
                 mLocalBluetoothLeBroadcast);
         when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
         when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+        when(mMediaDevice.isBLEDevice()).thenReturn(true);
+
         assertThat(mMediaOutputDialog.getStopButtonVisibility()).isEqualTo(View.VISIBLE);
     }
 
     @Test
+    public void getStopButtonVisibility_remoteNonBLEDevice_returnGone() {
+        when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+                mLocalBluetoothLeBroadcast);
+        when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
+        when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+        when(mMediaDevice.isBLEDevice()).thenReturn(false);
+
+        assertThat(mMediaOutputDialog.getStopButtonVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
     public void getStopButtonVisibility_localDevice_returnGone() {
         mFeatures.add(MediaRoute2Info.FEATURE_LOCAL_PLAYBACK);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
index b9a69bb..1527f0d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
@@ -25,6 +25,7 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManager
+import android.view.accessibility.AccessibilityManager
 import android.widget.ImageView
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
@@ -65,6 +66,8 @@
     @Mock
     private lateinit var logger: MediaTttLogger
     @Mock
+    private lateinit var accessibilityManager: AccessibilityManager
+    @Mock
     private lateinit var windowManager: WindowManager
     @Mock
     private lateinit var viewUtil: ViewUtil
@@ -88,11 +91,21 @@
         )).thenReturn(applicationInfo)
         context.setMockPackageManager(packageManager)
 
+        whenever(accessibilityManager.getRecommendedTimeoutMillis(any(), any()))
+            .thenReturn(TIMEOUT_MS.toInt())
+
         fakeClock = FakeSystemClock()
         fakeExecutor = FakeExecutor(fakeClock)
 
         controllerCommon = TestControllerCommon(
-            context, logger, windowManager, viewUtil, fakeExecutor, tapGestureDetector, powerManager
+            context,
+            logger,
+            windowManager,
+            viewUtil,
+            fakeExecutor,
+            accessibilityManager,
+            tapGestureDetector,
+            powerManager
         )
     }
 
@@ -344,6 +357,7 @@
         windowManager: WindowManager,
         viewUtil: ViewUtil,
         @Main mainExecutor: DelayableExecutor,
+        accessibilityManager: AccessibilityManager,
         tapGestureDetector: TapGestureDetector,
         powerManager: PowerManager
     ) : MediaTttChipControllerCommon<ChipInfo>(
@@ -352,6 +366,7 @@
         windowManager,
         viewUtil,
         mainExecutor,
+        accessibilityManager,
         tapGestureDetector,
         powerManager,
         R.layout.media_ttt_chip
@@ -364,7 +379,7 @@
     }
 
     inner class ChipInfo : ChipInfoCommon {
-        override fun getTimeoutMs() = TIMEOUT_MS
+        override fun getTimeoutMs() = 1L
     }
 }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
index 9edc4f4..bbc5641 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
@@ -28,6 +28,7 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManager
+import android.view.accessibility.AccessibilityManager
 import android.widget.ImageView
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
@@ -65,6 +66,8 @@
     @Mock
     private lateinit var logger: MediaTttLogger
     @Mock
+    private lateinit var accessibilityManager: AccessibilityManager
+    @Mock
     private lateinit var powerManager: PowerManager
     @Mock
     private lateinit var windowManager: WindowManager
@@ -99,6 +102,7 @@
             windowManager,
             viewUtil,
             FakeExecutor(FakeSystemClock()),
+            accessibilityManager,
             TapGestureDetector(context),
             powerManager,
             Handler.getMain(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
index a8c72dd..7ca0cd3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
@@ -27,6 +27,7 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManager
+import android.view.accessibility.AccessibilityManager
 import android.widget.ImageView
 import android.widget.TextView
 import androidx.test.filters.SmallTest
@@ -67,6 +68,8 @@
     @Mock
     private lateinit var logger: MediaTttLogger
     @Mock
+    private lateinit var accessibilityManager: AccessibilityManager
+    @Mock
     private lateinit var powerManager: PowerManager
     @Mock
     private lateinit var windowManager: WindowManager
@@ -95,9 +98,12 @@
 
         fakeClock = FakeSystemClock()
         fakeExecutor = FakeExecutor(fakeClock)
+
         uiEventLoggerFake = UiEventLoggerFake()
         senderUiEventLogger = MediaTttSenderUiEventLogger(uiEventLoggerFake)
 
+        whenever(accessibilityManager.getRecommendedTimeoutMillis(any(), any())).thenReturn(TIMEOUT)
+
         controllerSender = MediaTttChipControllerSender(
             commandQueue,
             context,
@@ -105,6 +111,7 @@
             windowManager,
             viewUtil,
             fakeExecutor,
+            accessibilityManager,
             TapGestureDetector(context),
             powerManager,
             senderUiEventLogger
@@ -592,7 +599,7 @@
         fakeClock.advanceTime(1000L)
         controllerSender.removeChip("fakeRemovalReason")
 
-        fakeClock.advanceTime(state.state.timeout + 1)
+        fakeClock.advanceTime(TIMEOUT + 1L)
 
         verify(windowManager).removeView(any())
     }
@@ -615,7 +622,7 @@
         fakeClock.advanceTime(1000L)
         controllerSender.removeChip("fakeRemovalReason")
 
-        fakeClock.advanceTime(state.state.timeout + 1)
+        fakeClock.advanceTime(TIMEOUT + 1L)
 
         verify(windowManager).removeView(any())
     }
@@ -674,6 +681,7 @@
 private const val APP_NAME = "Fake app name"
 private const val OTHER_DEVICE_NAME = "My Tablet"
 private const val PACKAGE_NAME = "com.android.systemui"
+private const val TIMEOUT = 10000
 
 private val routeInfo = MediaRoute2Info.Builder("id", OTHER_DEVICE_NAME)
     .addFeature("feature")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
index 26e4d9d..a56990f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
@@ -222,7 +222,7 @@
 
         mReceiver.onReceive(mContext, intent);
 
-        verify(mDialogLaunchAnimator).showFromView(any(), eq(mView));
+        verify(mDialogLaunchAnimator).showFromView(any(), eq(mView), any());
 
         mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index a3c353b..c1c0f78 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -731,7 +731,7 @@
 
         mTestableLooper.processAllMessages();
 
-        verify(mDialogLaunchAnimator).showFromView(any(), eq(mRootView));
+        verify(mDialogLaunchAnimator).showFromView(any(), eq(mRootView), any());
     }
 
     @Test
@@ -768,7 +768,7 @@
         ArgumentCaptor<AlertDialog> dialogCaptor = ArgumentCaptor.forClass(AlertDialog.class);
 
         mTestableLooper.processAllMessages();
-        verify(mDialogLaunchAnimator).showFromView(dialogCaptor.capture(), any());
+        verify(mDialogLaunchAnimator).showFromView(dialogCaptor.capture(), any(), any());
 
         AlertDialog dialog = dialogCaptor.getValue();
         dialog.create();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
index 0f2c2647..ca3182a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.qs.tiles.DataSaverTile
 import com.android.systemui.qs.tiles.DeviceControlsTile
 import com.android.systemui.qs.tiles.DndTile
+import com.android.systemui.qs.tiles.DreamTile
 import com.android.systemui.qs.tiles.FlashlightTile
 import com.android.systemui.qs.tiles.HotspotTile
 import com.android.systemui.qs.tiles.InternetTile
@@ -89,7 +90,8 @@
         "wallet" to QuickAccessWalletTile::class.java,
         "qr_code_scanner" to QRCodeScannerTile::class.java,
         "onehanded" to OneHandedModeTile::class.java,
-        "color_correction" to ColorCorrectionTile::class.java
+        "color_correction" to ColorCorrectionTile::class.java,
+        "dream" to DreamTile::class.java
 )
 
 @RunWith(AndroidTestingRunner::class)
@@ -129,6 +131,7 @@
     @Mock private lateinit var qrCodeScannerTile: QRCodeScannerTile
     @Mock private lateinit var oneHandedModeTile: OneHandedModeTile
     @Mock private lateinit var colorCorrectionTile: ColorCorrectionTile
+    @Mock private lateinit var dreamTile: DreamTile
 
     private lateinit var factory: QSFactoryImpl
 
@@ -171,7 +174,8 @@
                 { quickAccessWalletTile },
                 { qrCodeScannerTile },
                 { oneHandedModeTile },
-                { colorCorrectionTile }
+                { colorCorrectionTile },
+                { dreamTile }
         )
         // When adding/removing tiles, fix also [specMap]
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
index cc47248..d65901777 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
@@ -10,6 +10,7 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.plugins.ActivityStarter
@@ -18,6 +19,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.QSTileHost
 import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.statusbar.policy.BluetoothController
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
@@ -25,6 +27,7 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
@@ -84,6 +87,53 @@
         assertThat(tile.restrictionChecked).isEqualTo(UserManager.DISALLOW_BLUETOOTH)
     }
 
+    @Test
+    fun testIcon_whenDisabled_isOffState() {
+        val state = QSTile.BooleanState()
+        disableBluetooth()
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_off))
+    }
+
+    @Test
+    fun testIcon_whenDisconnected_isOffState() {
+        val state = QSTile.BooleanState()
+        enableBluetooth()
+        setBluetoothDisconnected()
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_off))
+    }
+
+    @Test
+    fun testIcon_whenConnected_isOnState() {
+        val state = QSTile.BooleanState()
+        enableBluetooth()
+        setBluetoothConnected()
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_on))
+    }
+
+    @Test
+    fun testIcon_whenConnecting_isSearchState() {
+        val state = QSTile.BooleanState()
+        enableBluetooth()
+        setBluetoothConnecting()
+
+        tile.handleUpdateState(state, /* arg= */ null)
+
+        assertThat(state.icon)
+                .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_bluetooth_icon_search))
+    }
+
     private class FakeBluetoothTile(
         qsTileHost: QSTileHost,
         backgroundLooper: Looper,
@@ -114,4 +164,27 @@
             restrictionChecked = userRestriction
         }
     }
+
+    fun enableBluetooth() {
+        `when`(bluetoothController.isBluetoothEnabled).thenReturn(true)
+    }
+
+    fun disableBluetooth() {
+        `when`(bluetoothController.isBluetoothEnabled).thenReturn(false)
+    }
+
+    fun setBluetoothDisconnected() {
+        `when`(bluetoothController.isBluetoothConnecting).thenReturn(false)
+        `when`(bluetoothController.isBluetoothConnected).thenReturn(false)
+    }
+
+    fun setBluetoothConnected() {
+        `when`(bluetoothController.isBluetoothConnecting).thenReturn(false)
+        `when`(bluetoothController.isBluetoothConnected).thenReturn(true)
+    }
+
+    fun setBluetoothConnecting() {
+        `when`(bluetoothController.isBluetoothConnected).thenReturn(false)
+        `when`(bluetoothController.isBluetoothConnecting).thenReturn(true)
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
index 9936d49..ae70d32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
@@ -38,9 +38,11 @@
 import com.android.systemui.statusbar.policy.ZenModeController
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.settings.FakeSettings
 import com.android.systemui.util.settings.SecureSettings
 import com.google.common.truth.Truth.assertThat
+import java.io.File
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
@@ -49,9 +51,8 @@
 import org.mockito.Mockito.anyBoolean
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
-import java.io.File
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -173,7 +174,7 @@
         tile.handleClick(view)
         testableLooper.processAllMessages()
 
-        verify(dialogLaunchAnimator).showFromView(any(), eq(view), anyBoolean())
+        verify(dialogLaunchAnimator).showFromView(any(), eq(view), nullable(), anyBoolean())
     }
 
     @Test
@@ -187,6 +188,6 @@
         tile.handleClick(view)
         testableLooper.processAllMessages()
 
-        verify(dialogLaunchAnimator, never()).showFromView(any(), any(), anyBoolean())
+        verify(dialogLaunchAnimator, never()).showFromView(any(), any(), nullable(), anyBoolean())
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
new file mode 100644
index 0000000..a13bece
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertTrue;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.dreams.IDreamManager;
+import android.service.quicksettings.Tile;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.util.settings.FakeSettings;
+import com.android.systemui.util.settings.SecureSettings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+public class DreamTileTest extends SysuiTestCase {
+
+    @Mock
+    private ActivityStarter mActivityStarter;
+    @Mock
+    private QSTileHost mHost;
+    @Mock
+    private MetricsLogger mMetricsLogger;
+    @Mock
+    private QSLogger mQSLogger;
+    @Mock
+    private StatusBarStateController mStatusBarStateController;
+    @Mock
+    private IDreamManager mDreamManager;
+    @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
+    @Mock
+    private UserTracker mUserTracker;
+
+    private TestableLooper mTestableLooper;
+
+    private DreamTile mTile;
+
+    private SecureSettings mSecureSettings;
+
+    private static final ComponentName COLORS_DREAM_COMPONENT_NAME = new ComponentName(
+            "com.android.dreams", ".Colors");
+
+    private static final int DEFAULT_USER = 0;
+
+    private final String mExpectedTileLabel = mContext.getResources().getString(
+            R.string.quick_settings_screensaver_label);
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mSecureSettings = new FakeSettings();
+        mTestableLooper = TestableLooper.get(this);
+
+        when(mHost.getUserId()).thenReturn(DEFAULT_USER);
+        when(mHost.getContext()).thenReturn(mContext);
+
+        mTile = spy(constructTileForTest(true, false));
+
+        mTestableLooper.processAllMessages();
+        mTile.initialize();
+    }
+
+    @Test
+    public void testNotAvailable() throws RemoteException {
+        // Should not be available if screensaver is disabled
+        setScreensaverEnabled(false);
+
+        mTile.refreshState();
+        mTestableLooper.processAllMessages();
+        assertEquals(Tile.STATE_UNAVAILABLE, mTile.getState().state);
+
+        // Should not be available if component is not set
+        mSecureSettings.putInt(Settings.Secure.SCREENSAVER_ENABLED, 1);
+        when(mDreamManager.getDreamComponents()).thenReturn(null);
+
+        mTestableLooper.processAllMessages();
+        assertEquals(Tile.STATE_UNAVAILABLE, mTile.getState().state);
+        assertEquals(mExpectedTileLabel, mTile.getState().contentDescription);
+    }
+
+    @Test
+    public void testInactiveWhenDreaming() throws RemoteException {
+        setScreensaverEnabled(true);
+
+        when(mDreamManager.getDreamComponents()).thenReturn(new ComponentName[]{
+                COLORS_DREAM_COMPONENT_NAME
+        });
+        when(mDreamManager.isDreaming()).thenReturn(false);
+
+        mTile.refreshState();
+        mTestableLooper.processAllMessages();
+        assertEquals(Tile.STATE_INACTIVE, mTile.getState().state);
+    }
+
+    @Test
+    public void testActive() throws RemoteException {
+        setScreensaverEnabled(true);
+
+        when(mDreamManager.getDreamComponents()).thenReturn(new ComponentName[]{
+                COLORS_DREAM_COMPONENT_NAME
+        });
+        when(mDreamManager.isDreaming()).thenReturn(true);
+
+        mTile.refreshState();
+        mTestableLooper.processAllMessages();
+        assertEquals(Tile.STATE_ACTIVE, mTile.getState().state);
+    }
+
+    @Test
+    public void testClick() throws RemoteException {
+        // Set the AOSP dream enabled as the base setup.
+        setScreensaverEnabled(true);
+        when(mDreamManager.getDreamComponents()).thenReturn(new ComponentName[]{
+                COLORS_DREAM_COMPONENT_NAME
+        });
+        when(mDreamManager.isDreaming()).thenReturn(false);
+
+        mTile.refreshState();
+        mTestableLooper.processAllMessages();
+        assertEquals(Tile.STATE_INACTIVE, mTile.getState().state);
+
+        // Now click
+        mTile.handleClick(null /* view */);
+
+        verify(mDreamManager).dream();
+
+        when(mDreamManager.isDreaming()).thenReturn(true);
+        mTile.refreshState();
+        mTestableLooper.processAllMessages();
+        assertEquals(Tile.STATE_ACTIVE, mTile.getState().state);
+
+        // Click again to see that other method is called
+        mTile.handleClick(null /* view */);
+
+        verify(mDreamManager).awaken();
+    }
+
+    @Test
+    public void testContentDescription() {
+        assertEquals(mExpectedTileLabel, mTile.getContentDescription(null));
+
+        final String testDreamName = "MyDream";
+        assertEquals(mExpectedTileLabel + ", " + testDreamName,
+                mTile.getContentDescription(testDreamName));
+    }
+
+    @Test
+    public void testUserAvailability() {
+        DreamTile unsupportedTile = constructTileForTest(false, true);
+        assertFalse(unsupportedTile.isAvailable());
+
+        DreamTile supportedTileAllUsers = constructTileForTest(true, false);
+
+        UserHandle systemUserHandle = mock(UserHandle.class);
+        when(systemUserHandle.isSystem()).thenReturn(true);
+
+        UserHandle nonSystemUserHandle = mock(UserHandle.class);
+        when(nonSystemUserHandle.isSystem()).thenReturn(false);
+
+        when(mUserTracker.getUserHandle()).thenReturn(systemUserHandle);
+        assertTrue(supportedTileAllUsers.isAvailable());
+        when(mUserTracker.getUserHandle()).thenReturn(nonSystemUserHandle);
+        assertTrue(supportedTileAllUsers.isAvailable());
+
+        DreamTile supportedTileOnlySystemUser = constructTileForTest(true, true);
+        when(mUserTracker.getUserHandle()).thenReturn(systemUserHandle);
+        assertTrue(supportedTileOnlySystemUser.isAvailable());
+        when(mUserTracker.getUserHandle()).thenReturn(nonSystemUserHandle);
+        assertFalse(supportedTileOnlySystemUser.isAvailable());
+    }
+
+    @Test
+    public void testIconDockState() {
+        final DreamTile dockedTile = constructTileForTest(true, false);
+
+        final ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
+                BroadcastReceiver.class);
+        dockedTile.handleSetListening(true);
+        verify(mBroadcastDispatcher).registerReceiver(receiverCaptor.capture(), any());
+        final BroadcastReceiver receiver = receiverCaptor.getValue();
+
+        Intent dockIntent = new Intent(Intent.ACTION_DOCK_EVENT);
+        dockIntent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_DESK);
+        receiver.onReceive(mContext, dockIntent);
+        mTestableLooper.processAllMessages();
+        assertEquals(QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_screen_saver),
+                dockedTile.getState().icon);
+
+        dockIntent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
+        receiver.onReceive(mContext, dockIntent);
+        mTestableLooper.processAllMessages();
+        assertEquals(QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_screen_saver_undocked),
+                dockedTile.getState().icon);
+    }
+
+    private void setScreensaverEnabled(boolean enabled) {
+        mSecureSettings.putIntForUser(Settings.Secure.SCREENSAVER_ENABLED, enabled ? 1 : 0,
+                DEFAULT_USER);
+    }
+
+    private DreamTile constructTileForTest(boolean dreamSupported,
+            boolean dreamOnlyEnabledForSystemUser) {
+        return new DreamTile(
+                mHost,
+                mTestableLooper.getLooper(),
+                new Handler(mTestableLooper.getLooper()),
+                new FalsingManagerFake(),
+                mMetricsLogger,
+                mStatusBarStateController,
+                mActivityStarter,
+                mQSLogger,
+                mDreamManager,
+                mSecureSettings,
+                mBroadcastDispatcher,
+                mUserTracker,
+                dreamSupported, dreamOnlyEnabledForSystemUser);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
index 55c51b2..e9dfd3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/RotationLockTileTest.java
@@ -36,9 +36,11 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.DeviceStateRotationLockSettingController;
 import com.android.systemui.statusbar.policy.RotationLockController;
@@ -194,6 +196,26 @@
         assertEquals("", mLockTile.getState().secondaryLabel.toString());
     }
 
+    @Test
+    public void testIcon_whenDisabled_isOffState() {
+        QSTile.BooleanState state = new QSTile.BooleanState();
+        disableAutoRotation();
+
+        mLockTile.handleUpdateState(state, /* arg= */ null);
+
+        assertEquals(state.icon, QSTileImpl.ResourceIcon.get(R.drawable.qs_auto_rotate_icon_off));
+    }
+
+    @Test
+    public void testIcon_whenEnabled_isOnState() {
+        QSTile.BooleanState state = new QSTile.BooleanState();
+        enableAutoRotation();
+
+        mLockTile.handleUpdateState(state, /* arg= */ null);
+
+        assertEquals(state.icon, QSTileImpl.ResourceIcon.get(R.drawable.qs_auto_rotate_icon_on));
+    }
+
     private void enableAutoRotation() {
         when(mRotationPolicyWrapper.isRotationLocked()).thenReturn(false);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
index 030c65a..9d908fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
@@ -42,11 +42,12 @@
 import org.mockito.ArgumentMatcher
 import org.mockito.Captor
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
+import org.mockito.Mockito.anyBoolean
 import org.mockito.Mockito.anyInt
 import org.mockito.Mockito.argThat
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @SmallTest
@@ -82,19 +83,19 @@
         `when`(dialog.context).thenReturn(mContext)
 
         controller = UserSwitchDialogController(
-                { userDetailViewAdapter },
-                activityStarter,
-                falsingManager,
-                dialogLaunchAnimator,
-                uiEventLogger,
-                { dialog }
+            { userDetailViewAdapter },
+            activityStarter,
+            falsingManager,
+            dialogLaunchAnimator,
+            uiEventLogger,
+            { dialog }
         )
     }
 
     @Test
     fun showDialog_callsDialogShow() {
         controller.showDialog(launchView)
-        verify(dialogLaunchAnimator).showFromView(dialog, launchView)
+        verify(dialogLaunchAnimator).showFromView(eq(dialog), eq(launchView), any(), anyBoolean())
         verify(uiEventLogger).log(QSUserSwitcherEvent.QS_USER_DETAIL_OPEN)
     }
 
@@ -140,11 +141,11 @@
         clickCaptor.value.onClick(dialog, DialogInterface.BUTTON_NEUTRAL)
 
         verify(activityStarter)
-                .postStartActivityDismissingKeyguard(
-                        argThat(IntentMatcher(Settings.ACTION_USER_SETTINGS)),
-                        eq(0),
-                        eq(null)
-                )
+            .postStartActivityDismissingKeyguard(
+                argThat(IntentMatcher(Settings.ACTION_USER_SETTINGS)),
+                eq(0),
+                eq(null)
+            )
         verify(uiEventLogger).log(QSUserSwitcherEvent.QS_USER_MORE_SETTINGS)
     }
 
@@ -167,4 +168,4 @@
             return argument?.action == action
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
index 3231415..a4a89a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
@@ -1,3 +1,17 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
 package com.android.systemui.shared.animation
 
 import android.testing.AndroidTestingRunner
@@ -7,31 +21,24 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator.Direction
 import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator.ViewIdToTranslate
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.TestUnfoldTransitionProvider
 import org.junit.Assert.assertEquals
 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.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 class UnfoldConstantTranslateAnimatorTest : SysuiTestCase() {
 
-    @Mock private lateinit var progressProvider: UnfoldTransitionProgressProvider
+    private val progressProvider = TestUnfoldTransitionProvider()
 
     @Mock private lateinit var parent: ViewGroup
 
-    @Captor private lateinit var progressListenerCaptor: ArgumentCaptor<TransitionProgressListener>
-
     private lateinit var animator: UnfoldConstantTranslateAnimator
-    private lateinit var progressListener: TransitionProgressListener
 
     private val viewsIdToRegister =
         setOf(
@@ -46,17 +53,14 @@
             UnfoldConstantTranslateAnimator(viewsIdToRegister, progressProvider)
 
         animator.init(parent, MAX_TRANSLATION)
-
-        verify(progressProvider).addCallback(progressListenerCaptor.capture())
-        progressListener = progressListenerCaptor.value
     }
 
     @Test
     fun onTransition_noMatchingIds() {
         // GIVEN no views matching any ids
         // WHEN the transition starts
-        progressListener.onTransitionStarted()
-        progressListener.onTransitionProgress(.1f)
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(.1f)
 
         // THEN nothing... no exceptions
     }
@@ -86,22 +90,22 @@
         // Compare values as ints because -0f != 0f
 
         // WHEN the transition starts
-        progressListener.onTransitionStarted()
-        progressListener.onTransitionProgress(0f)
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(0f)
 
         list.forEach { (view, direction) ->
             assertEquals((-MAX_TRANSLATION * direction).toInt(), view.translationX.toInt())
         }
 
         // WHEN the transition progresses, translation is updated
-        progressListener.onTransitionProgress(.5f)
+        progressProvider.onTransitionProgress(.5f)
         list.forEach { (view, direction) ->
             assertEquals((-MAX_TRANSLATION / 2f * direction).toInt(), view.translationX.toInt())
         }
 
         // WHEN the transition ends, translation is completed
-        progressListener.onTransitionProgress(1f)
-        progressListener.onTransitionFinished()
+        progressProvider.onTransitionProgress(1f)
+        progressProvider.onTransitionFinished()
         list.forEach { (view, _) -> assertEquals(0, view.translationX.toInt()) }
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
index 2cfe6be..37f96c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
@@ -26,8 +26,9 @@
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.dreams.smartspace.DreamsSmartspaceController
+import com.android.systemui.dreams.smartspace.DreamSmartspaceController
 import com.android.systemui.plugins.BcSmartspaceDataPlugin
+import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.smartspace.dagger.SmartspaceViewComponent
 import com.android.systemui.util.concurrency.Execution
@@ -35,16 +36,17 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
+import java.util.Optional
+import java.util.concurrent.Executor
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
-import java.util.Optional
-import java.util.concurrent.Executor
+import org.mockito.Spy
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -74,8 +76,8 @@
     @Mock
     private lateinit var precondition: SmartspacePrecondition
 
-    @Mock
-    private lateinit var smartspaceView: BcSmartspaceDataPlugin.SmartspaceView
+    @Spy
+    private var smartspaceView: SmartspaceView = TestView(context)
 
     @Mock
     private lateinit var listener: BcSmartspaceDataPlugin.SmartspaceTargetListener
@@ -83,6 +85,36 @@
     @Mock
     private lateinit var session: SmartspaceSession
 
+    private lateinit var controller: DreamSmartspaceController
+
+    /**
+     * A class which implements SmartspaceView and extends View. This is mocked to provide the right
+     * object inheritance and interface implementation used in DreamSmartspaceController
+     */
+    private class TestView(context: Context?) : View(context), SmartspaceView {
+        override fun registerDataProvider(plugin: BcSmartspaceDataPlugin?) {}
+
+        override fun setPrimaryTextColor(color: Int) {}
+
+        override fun setIsDreaming(isDreaming: Boolean) {}
+
+        override fun setDozeAmount(amount: Float) {}
+
+        override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) {}
+
+        override fun setFalsingManager(falsingManager: FalsingManager?) {}
+
+        override fun setDnd(image: Drawable?, description: String?) {}
+
+        override fun setNextAlarm(image: Drawable?, description: String?) {}
+
+        override fun setMediaTarget(target: SmartspaceTarget?) {}
+
+        override fun getSelectedPage(): Int { return 0; }
+
+        override fun getCurrentCardTopPadding(): Int { return 0; }
+    }
+
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
@@ -90,6 +122,9 @@
                 .thenReturn(viewComponent)
         `when`(viewComponent.getView()).thenReturn(smartspaceView)
         `when`(smartspaceManager.createSmartspaceSession(any())).thenReturn(session)
+
+        controller = DreamSmartspaceController(context, smartspaceManager, execution, uiExecutor,
+                viewComponentFactory, precondition, Optional.of(targetFilter), Optional.of(plugin))
     }
 
     /**
@@ -97,10 +132,6 @@
      */
     @Test
     fun testConnectOnListen() {
-        val controller = DreamsSmartspaceController(context,
-        smartspaceManager, execution, uiExecutor, viewComponentFactory, precondition,
-                Optional.of(targetFilter), Optional.of(plugin))
-
         `when`(precondition.conditionsMet()).thenReturn(true)
         controller.addListener(listener)
 
@@ -127,44 +158,10 @@
     }
 
     /**
-     * A class which implements SmartspaceView and extends View. This is mocked to provide the right
-     * object inheritance and interface implementation used in DreamSmartspaceController
-     */
-    private class TestView(context: Context?) : View(context),
-            BcSmartspaceDataPlugin.SmartspaceView {
-        override fun registerDataProvider(plugin: BcSmartspaceDataPlugin?) {}
-
-        override fun setPrimaryTextColor(color: Int) {}
-
-        override fun setIsDreaming(isDreaming: Boolean) {}
-
-        override fun setDozeAmount(amount: Float) {}
-
-        override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) {}
-
-        override fun setFalsingManager(falsingManager: FalsingManager?) {}
-
-        override fun setDnd(image: Drawable?, description: String?) {}
-
-        override fun setNextAlarm(image: Drawable?, description: String?) {}
-
-        override fun setMediaTarget(target: SmartspaceTarget?) {}
-
-        override fun getSelectedPage(): Int { return 0; }
-
-        override fun getCurrentCardTopPadding(): Int { return 0; }
-    }
-
-    /**
      * Ensures session begins when a view is attached.
      */
     @Test
     fun testConnectOnViewCreate() {
-        val controller = DreamsSmartspaceController(context,
-                smartspaceManager, execution, uiExecutor, viewComponentFactory, precondition,
-                Optional.of(targetFilter),
-                Optional.of(plugin))
-
         `when`(precondition.conditionsMet()).thenReturn(true)
         controller.buildAndConnectView(Mockito.mock(ViewGroup::class.java))
 
@@ -183,4 +180,4 @@
 
         verify(session).close()
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
index 9d5099c..81d5c4d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
@@ -1,10 +1,10 @@
 package com.android.systemui.statusbar
 
-import org.mockito.Mockito.`when` as whenever
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.qs.QS
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.phone.ScrimController
@@ -19,6 +19,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
@@ -32,6 +33,7 @@
     @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
     @Mock private lateinit var qS: QS
     @Mock private lateinit var nsslController: NotificationStackScrollLayoutController
+    @Mock private lateinit var dumpManager: DumpManager
 
     private lateinit var overScroller: SplitShadeLockScreenOverScroller
 
@@ -44,11 +46,12 @@
         overScroller =
             SplitShadeLockScreenOverScroller(
                 configurationController,
+                dumpManager,
                 context,
                 scrimController,
                 statusBarStateController,
-                qS,
-                nsslController)
+                { qS },
+                { nsslController })
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt
index b4cae38..d0cf792 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/charging/WiredChargingRippleControllerTest.kt
@@ -74,9 +74,9 @@
 
         // Verify ripple added to window manager.
         captor.value.onBatteryLevelChanged(
-                0 /* unusedBatteryLevel */,
-                true /* plugged in */,
-                false /* charging */)
+                /* unusedBatteryLevel= */ 0,
+                /* plugged in= */ true,
+                /* charging= */ false)
         val attachListenerCaptor =
                 ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
         verify(rippleView).addOnAttachStateChangeListener(attachListenerCaptor.capture())
@@ -144,4 +144,22 @@
         // Verify that ripple is triggered.
         verify(rippleView).addOnAttachStateChangeListener(ArgumentMatchers.any())
     }
+
+    @Test
+    fun testRipple_whenDocked_doesNotPlayRipple() {
+        `when`(batteryController.isChargingSourceDock).thenReturn(true)
+        val captor = ArgumentCaptor
+                .forClass(BatteryController.BatteryStateChangeCallback::class.java)
+        verify(batteryController).addCallback(captor.capture())
+
+        captor.value.onBatteryLevelChanged(
+                /* unusedBatteryLevel= */ 0,
+                /* plugged in= */ true,
+                /* charging= */ false)
+
+        val attachListenerCaptor =
+                ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
+        verify(rippleView, never()).addOnAttachStateChangeListener(attachListenerCaptor.capture())
+        verify(windowManager, never()).addView(eq(rippleView), any<WindowManager.LayoutParams>())
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
index e01ebbd..0d1879c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
@@ -72,6 +72,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
+import com.android.systemui.log.LogBuffer;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
 import com.android.systemui.telephony.TelephonyListenerManager;
@@ -244,7 +245,8 @@
                 mWifiStatusTrackerFactory,
                 mMainHandler,
                 mFeatureFlags,
-                mock(DumpManager.class)
+                mock(DumpManager.class),
+                mock(LogBuffer.class)
         );
         setupNetworkController();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
index 3a0c203..e3dd6f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
@@ -38,6 +38,7 @@
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.log.LogBuffer;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.util.CarrierConfigTracker;
 
@@ -125,16 +126,29 @@
     public void test4gDataIcon() {
         // Switch to showing 4g icon and re-initialize the NetworkController.
         mConfig.show4gForLte = true;
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
-                mTelephonyListenerManager, mMockWm,
-                mMockSm, mConfig, Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
+        mNetworkController = new NetworkControllerImpl(
+                mContext,
+                mMockCm,
+                mMockTm,
+                mTelephonyListenerManager,
+                mMockWm,
+                mMockSm,
+                mConfig,
+                Looper.getMainLooper(),
+                mFakeExecutor,
+                mCallbackHandler,
                 mock(AccessPointControllerImpl.class),
-                mock(DataUsageController.class), mMockSubDefaults,
-                mock(DeviceProvisionedController.class), mMockBd, mDemoModeController,
+                mock(DataUsageController.class),
+                mMockSubDefaults,
+                mock(DeviceProvisionedController.class),
+                mMockBd,
+                mDemoModeController,
                 mock(CarrierConfigTracker.class),
                 mWifiStatusTrackerFactory,
                 new Handler(TestableLooper.get(this).getLooper()),
-                mFeatureFlags, mock(DumpManager.class));
+                mFeatureFlags,
+                mock(DumpManager.class),
+                mock(LogBuffer.class));
         setupNetworkController();
 
         setupDefaultSignal();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
index ae1b3d1..698899a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
@@ -43,6 +43,7 @@
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.R;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.log.LogBuffer;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.util.CarrierConfigTracker;
 
@@ -86,7 +87,8 @@
                 mWifiStatusTrackerFactory,
                 mMainHandler,
                 mFeatureFlags,
-                mock(DumpManager.class)
+                mock(DumpManager.class),
+                mock(LogBuffer.class)
         );
         TestableLooper.get(this).processAllMessages();
 
@@ -100,7 +102,8 @@
         when(mMockProvisionController.isCurrentUserSetup()).thenReturn(true);
 
         // WHEN - a NetworkController is created
-        mNetworkController = new NetworkControllerImpl(mContext,
+        mNetworkController = new NetworkControllerImpl(
+                mContext,
                 mMockCm,
                 mMockTm,
                 mTelephonyListenerManager,
@@ -120,8 +123,8 @@
                 mWifiStatusTrackerFactory,
                 mMainHandler,
                 mFeatureFlags,
-                mock(DumpManager.class)
-        );
+                mock(DumpManager.class),
+                mock(LogBuffer.class));
         TestableLooper.get(this).processAllMessages();
 
         // THEN - NetworkController claims the user is not setup
@@ -133,15 +136,29 @@
         // Turn off mobile network support.
         when(mMockTm.isDataCapable()).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
-                mTelephonyListenerManager, mMockWm, mMockSm, mConfig,
-                Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
-                mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
-                mDemoModeController, mock(CarrierConfigTracker.class),
+        mNetworkController = new NetworkControllerImpl(
+                mContext,
+                mMockCm,
+                mMockTm,
+                mTelephonyListenerManager,
+                mMockWm,
+                mMockSm,
+                mConfig,
+                Looper.getMainLooper(),
+                mFakeExecutor,
+                mCallbackHandler,
+                mock(AccessPointControllerImpl.class),
+                mock(DataUsageController.class),
+                mMockSubDefaults,
+                mock(DeviceProvisionedController.class),
+                mMockBd,
+                mDemoModeController,
+                mock(CarrierConfigTracker.class),
                 mWifiStatusTrackerFactory,
-                mMainHandler, mFeatureFlags,
-                mock(DumpManager.class));
+                mMainHandler,
+                mFeatureFlags,
+                mock(DumpManager.class),
+                mock(LogBuffer.class));
         setupNetworkController();
 
         verifyLastMobileDataIndicators(false, -1, 0);
@@ -156,14 +173,29 @@
         when(mMockTm.getServiceState()).thenReturn(mServiceState);
         when(mMockSm.getCompleteActiveSubscriptionInfoList()).thenReturn(Collections.emptyList());
 
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
-                mTelephonyListenerManager, mMockWm, mMockSm, mConfig,
-                Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
-                mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
-                mDemoModeController, mock(CarrierConfigTracker.class),
+        mNetworkController = new NetworkControllerImpl(
+                mContext,
+                mMockCm,
+                mMockTm,
+                mTelephonyListenerManager,
+                mMockWm,
+                mMockSm,
+                mConfig,
+                Looper.getMainLooper(),
+                mFakeExecutor,
+                mCallbackHandler,
+                mock(AccessPointControllerImpl.class),
+                mock(DataUsageController.class),
+                mMockSubDefaults,
+                mock(DeviceProvisionedController.class),
+                mMockBd,
+                mDemoModeController,
+                mock(CarrierConfigTracker.class),
                 mWifiStatusTrackerFactory,
-                mMainHandler, mFeatureFlags, mock(DumpManager.class));
+                mMainHandler,
+                mFeatureFlags,
+                mock(DumpManager.class),
+                mock(LogBuffer.class));
         mNetworkController.registerListeners();
 
         // Wait for the main looper to execute the previous command
@@ -226,14 +258,29 @@
         // Turn off mobile network support.
         when(mMockTm.isDataCapable()).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
-        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
-                mTelephonyListenerManager, mMockWm, mMockSm, mConfig,
-                Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
-                mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
-                mDemoModeController, mock(CarrierConfigTracker.class),
+        mNetworkController = new NetworkControllerImpl(
+                mContext,
+                mMockCm,
+                mMockTm,
+                mTelephonyListenerManager,
+                mMockWm,
+                mMockSm,
+                mConfig,
+                Looper.getMainLooper(),
+                mFakeExecutor,
+                mCallbackHandler,
+                mock(AccessPointControllerImpl.class),
+                mock(DataUsageController.class),
+                mMockSubDefaults,
+                mock(DeviceProvisionedController.class),
+                mMockBd,
+                mDemoModeController,
+                mock(CarrierConfigTracker.class),
                 mWifiStatusTrackerFactory,
-                mMainHandler, mFeatureFlags, mock(DumpManager.class));
+                mMainHandler,
+                mFeatureFlags,
+                mock(DumpManager.class),
+                mock(LogBuffer.class));
         setupNetworkController();
 
         // No Subscriptions.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
index b44f53c..20747a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
@@ -33,6 +33,8 @@
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.BcSmartspaceDataPlugin
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
@@ -41,8 +43,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
@@ -54,20 +55,20 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.settings.SecureSettings
 import com.android.systemui.util.time.FakeSystemClock
+import java.util.Optional
 import org.junit.Before
 import org.junit.Test
 import org.mockito.ArgumentCaptor
 import org.mockito.Captor
 import org.mockito.Mock
-import org.mockito.Mockito.`when`
 import org.mockito.Mockito.anyInt
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
-import java.util.Optional
 
 @SmallTest
 class LockscreenSmartspaceControllerTest : SysuiTestCase() {
@@ -81,36 +82,56 @@
     private lateinit var activityStarter: ActivityStarter
     @Mock
     private lateinit var falsingManager: FalsingManager
+
     @Mock
     private lateinit var secureSettings: SecureSettings
+
     @Mock
     private lateinit var userTracker: UserTracker
+
     @Mock
     private lateinit var contentResolver: ContentResolver
+
     @Mock
     private lateinit var configurationController: ConfigurationController
+
     @Mock
     private lateinit var statusBarStateController: StatusBarStateController
+
+    @Mock
+    private lateinit var keyguardBypassController: KeyguardBypassController
+
     @Mock
     private lateinit var deviceProvisionedController: DeviceProvisionedController
+
     @Mock
     private lateinit var handler: Handler
 
     @Mock
     private lateinit var plugin: BcSmartspaceDataPlugin
+
     @Mock
     private lateinit var controllerListener: SmartspaceTargetListener
 
     @Captor
     private lateinit var sessionListenerCaptor: ArgumentCaptor<OnTargetsAvailableListener>
+
     @Captor
     private lateinit var userTrackerCaptor: ArgumentCaptor<UserTracker.Callback>
+
     @Captor
     private lateinit var settingsObserverCaptor: ArgumentCaptor<ContentObserver>
+
     @Captor
     private lateinit var configChangeListenerCaptor: ArgumentCaptor<ConfigurationListener>
+
     @Captor
     private lateinit var statusBarStateListenerCaptor: ArgumentCaptor<StateListener>
+
+    @Captor
+    private lateinit var bypassStateChangedListenerCaptor:
+        ArgumentCaptor<KeyguardBypassController.OnBypassStateChangedListener>
+
     @Captor
     private lateinit var deviceProvisionedCaptor: ArgumentCaptor<DeviceProvisionedListener>
 
@@ -119,6 +140,8 @@
     private lateinit var settingsObserver: ContentObserver
     private lateinit var configChangeListener: ConfigurationListener
     private lateinit var statusBarStateListener: StateListener
+    private lateinit var bypassStateChangeListener:
+        KeyguardBypassController.OnBypassStateChangedListener
     private lateinit var deviceProvisionedListener: DeviceProvisionedListener
 
     private lateinit var smartspaceView: SmartspaceView
@@ -177,11 +200,12 @@
                 configurationController,
                 statusBarStateController,
                 deviceProvisionedController,
+                keyguardBypassController,
                 execution,
                 executor,
                 handler,
                 Optional.of(plugin)
-                )
+        )
 
         verify(deviceProvisionedController).addCallback(capture(deviceProvisionedCaptor))
         deviceProvisionedListener = deviceProvisionedCaptor.value
@@ -310,6 +334,19 @@
     }
 
     @Test
+    fun testKeyguardBypassEnabledUpdatesView() {
+        // GIVEN a connected smartspace session
+        connectSession()
+        `when`(keyguardBypassController.bypassEnabled).thenReturn(true)
+
+        // WHEN the doze amount changes
+        bypassStateChangeListener.onBypassStateChanged(true)
+
+        // We pass that along to the view
+        verify(smartspaceView).setKeyguardBypassEnabled(true)
+    }
+
+    @Test
     fun testSensitiveTargetsAreNotFilteredIfAllowed() {
         // GIVEN the active and managed users allow sensitive content
         connectSession()
@@ -457,6 +494,8 @@
         verify(contentResolver).unregisterContentObserver(settingsObserver)
         verify(configurationController).removeCallback(configChangeListener)
         verify(statusBarStateController).removeCallback(statusBarStateListener)
+        verify(keyguardBypassController)
+                .unregisterOnBypassStateChangedListener(bypassStateChangeListener)
     }
 
     @Test
@@ -478,6 +517,19 @@
     }
 
     @Test
+    fun testViewGetInitializedWithBypassEnabledState() {
+        // GIVEN keyguard bypass is enabled.
+        `when`(keyguardBypassController.bypassEnabled).thenReturn(true)
+
+        // WHEN the view is being built
+        val view = controller.buildAndConnectView(fakeParent)
+        smartspaceView = view as SmartspaceView
+
+        // THEN the view is initialized with the keyguard bypass enabled state.
+        verify(smartspaceView).setKeyguardBypassEnabled(true)
+    }
+
+    @Test
     fun testConnectAttemptBeforeInitializationShouldNotCreateSession() {
         // GIVEN an uninitalized smartspaceView
         // WHEN the device is provisioned
@@ -517,6 +569,9 @@
 
         verify(statusBarStateController).addCallback(statusBarStateListenerCaptor.capture())
         statusBarStateListener = statusBarStateListenerCaptor.value
+        verify(keyguardBypassController)
+            .registerOnBypassStateChangedListener(capture(bypassStateChangedListenerCaptor))
+        bypassStateChangeListener = bypassStateChangedListenerCaptor.value
 
         verify(smartspaceSession).requestSmartspaceUpdate()
         clearInvocations(smartspaceSession)
@@ -585,6 +640,9 @@
             override fun setDozeAmount(amount: Float) {
             }
 
+            override fun setKeyguardBypassEnabled(enabled: Boolean) {
+            }
+
             override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) {
             }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
index 7d06abf..3fc0c81 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
@@ -63,7 +63,7 @@
                 mock(StatusBarKeyguardViewManager.class));
         mDynamicPrivacyController.addListener(mListener);
         // Disable dynamic privacy by default
-        allowPrivateNotificationsInPublic(true);
+        allowNotificationsInPublic(false);
     }
 
     @Test
@@ -108,24 +108,21 @@
 
     @Test
     public void dynamicPrivacyOnlyWhenHidingPrivate() {
-        // Verify that when only hiding notifications, this isn't enabled
-        allowPrivateNotificationsInPublic(true);
-        when(mLockScreenUserManager.shouldHideNotifications(any())).thenReturn(
-                false);
-        assertFalse("Dynamic privacy shouldn't be enabled when only hiding notifications",
+        // Verify that when hiding notifications, this isn't enabled
+        allowNotificationsInPublic(false);
+        assertFalse("Dynamic privacy shouldn't be enabled when hiding notifications",
                 mDynamicPrivacyController.isDynamicPrivacyEnabled());
-        allowPrivateNotificationsInPublic(false);
-        assertTrue("Should be enabled when hiding notification contents",
+        allowNotificationsInPublic(true);
+        assertTrue("Should be enabled whenever notifications are visible",
                 mDynamicPrivacyController.isDynamicPrivacyEnabled());
     }
 
     private void enableDynamicPrivacy() {
-        allowPrivateNotificationsInPublic(false);
+        allowNotificationsInPublic(true);
     }
 
-    private void allowPrivateNotificationsInPublic(boolean allow) {
-        when(mLockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn(
-                allow);
+    private void allowNotificationsInPublic(boolean allow) {
+        when(mLockScreenUserManager.userAllowsNotificationsInPublic(anyInt())).thenReturn(allow);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java
index 4507366..ee7d558 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NoManSimulator.java
@@ -85,6 +85,11 @@
         mRankings.put(key, ranking);
     }
 
+    /** This is for testing error cases: b/216384850 */
+    public Ranking removeRankingWithoutEvent(String key) {
+        return mRankings.remove(key);
+    }
+
     private RankingMap buildRankingMap() {
         return new RankingMap(mRankings.values().toArray(new Ranking[0]));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
index 958d542..f286349 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
@@ -1492,6 +1492,80 @@
     }
 
     @Test
+    public void testMissingRankingWhenRemovalFeatureIsDisabled() {
+        // GIVEN a pipeline with one two notifications
+        when(mNotifPipelineFlags.removeUnrankedNotifs()).thenReturn(false);
+        String key1 = mNoMan.postNotif(buildNotif(TEST_PACKAGE, 1, "myTag")).key;
+        String key2 = mNoMan.postNotif(buildNotif(TEST_PACKAGE, 2, "myTag")).key;
+        NotificationEntry entry1 = mCollectionListener.getEntry(key1);
+        NotificationEntry entry2 = mCollectionListener.getEntry(key2);
+        clearInvocations(mCollectionListener);
+
+        // GIVEN the message for removing key1 gets does not reach NotifCollection
+        Ranking ranking1 = mNoMan.removeRankingWithoutEvent(key1);
+        // WHEN the message for removing key2 arrives
+        mNoMan.retractNotif(entry2.getSbn(), REASON_APP_CANCEL);
+
+        // THEN only entry2 gets removed
+        verify(mCollectionListener).onEntryRemoved(eq(entry2), eq(REASON_APP_CANCEL));
+        verify(mCollectionListener).onEntryCleanUp(eq(entry2));
+        verify(mCollectionListener).onRankingApplied();
+        verifyNoMoreInteractions(mCollectionListener);
+        verify(mLogger).logMissingRankings(eq(List.of(entry1)), eq(1), any());
+        verify(mLogger, never()).logRecoveredRankings(any());
+        clearInvocations(mCollectionListener, mLogger);
+
+        // WHEN a ranking update includes key1 again
+        mNoMan.setRanking(key1, ranking1);
+        mNoMan.issueRankingUpdate();
+
+        // VERIFY that we do nothing but log the 'recovery'
+        verify(mCollectionListener).onRankingUpdate(any());
+        verify(mCollectionListener).onRankingApplied();
+        verifyNoMoreInteractions(mCollectionListener);
+        verify(mLogger, never()).logMissingRankings(any(), anyInt(), any());
+        verify(mLogger).logRecoveredRankings(eq(List.of(key1)));
+    }
+
+    @Test
+    public void testMissingRankingWhenRemovalFeatureIsEnabled() {
+        // GIVEN a pipeline with one two notifications
+        when(mNotifPipelineFlags.removeUnrankedNotifs()).thenReturn(true);
+        String key1 = mNoMan.postNotif(buildNotif(TEST_PACKAGE, 1, "myTag")).key;
+        String key2 = mNoMan.postNotif(buildNotif(TEST_PACKAGE, 2, "myTag")).key;
+        NotificationEntry entry1 = mCollectionListener.getEntry(key1);
+        NotificationEntry entry2 = mCollectionListener.getEntry(key2);
+        clearInvocations(mCollectionListener);
+
+        // GIVEN the message for removing key1 gets does not reach NotifCollection
+        Ranking ranking1 = mNoMan.removeRankingWithoutEvent(key1);
+        // WHEN the message for removing key2 arrives
+        mNoMan.retractNotif(entry2.getSbn(), REASON_APP_CANCEL);
+
+        // THEN both entry1 and entry2 get removed
+        verify(mCollectionListener).onEntryRemoved(eq(entry2), eq(REASON_APP_CANCEL));
+        verify(mCollectionListener).onEntryRemoved(eq(entry1), eq(REASON_UNKNOWN));
+        verify(mCollectionListener).onEntryCleanUp(eq(entry2));
+        verify(mCollectionListener).onEntryCleanUp(eq(entry1));
+        verify(mCollectionListener).onRankingApplied();
+        verifyNoMoreInteractions(mCollectionListener);
+        verify(mLogger).logMissingRankings(eq(List.of(entry1)), eq(1), any());
+        verify(mLogger, never()).logRecoveredRankings(any());
+        clearInvocations(mCollectionListener, mLogger);
+
+        // WHEN a ranking update includes key1 again
+        mNoMan.setRanking(key1, ranking1);
+        mNoMan.issueRankingUpdate();
+
+        // VERIFY that we do nothing but log the 'recovery'
+        verify(mCollectionListener).onRankingUpdate(any());
+        verify(mCollectionListener).onRankingApplied();
+        verifyNoMoreInteractions(mCollectionListener);
+        verify(mLogger, never()).logMissingRankings(any(), anyInt(), any());
+        verify(mLogger).logRecoveredRankings(eq(List.of(key1)));
+    }
+
+    @Test
     public void testRegisterFutureDismissal() throws RemoteException {
         // GIVEN a pipeline with one notification
         NotifEvent notifEvent = mNoMan.postNotif(buildNotif(TEST_PACKAGE, 47, "myTag"));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
index 769143d..d4add75 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -108,6 +108,7 @@
     @Test
     public void testBlockableEntryWhenCritical() {
         doReturn(true).when(mChannel).isBlockable();
+        mEntry.setRanking(mEntry.getRanking());
 
         assertTrue(mEntry.isBlockable());
     }
@@ -117,6 +118,7 @@
     public void testBlockableEntryWhenCriticalAndChannelNotBlockable() {
         doReturn(true).when(mChannel).isBlockable();
         doReturn(true).when(mChannel).isImportanceLockedByCriticalDeviceFunction();
+        mEntry.setRanking(mEntry.getRanking());
 
         assertTrue(mEntry.isBlockable());
     }
@@ -125,6 +127,7 @@
     public void testNonBlockableEntryWhenCriticalAndChannelNotBlockable() {
         doReturn(false).when(mChannel).isBlockable();
         doReturn(true).when(mChannel).isImportanceLockedByCriticalDeviceFunction();
+        mEntry.setRanking(mEntry.getRanking());
 
         assertFalse(mEntry.isBlockable());
     }
@@ -164,6 +167,9 @@
         doReturn(true).when(mChannel).isImportanceLockedByCriticalDeviceFunction();
         doReturn(false).when(mChannel).isBlockable();
 
+        mEntry.setRanking(mEntry.getRanking());
+
+        assertFalse(mEntry.isBlockable());
         assertTrue(mEntry.isExemptFromDndVisualSuppression());
         assertFalse(mEntry.shouldSuppressAmbient());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
index 4e7e79f..9546058 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
@@ -53,6 +53,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.statusbar.NotificationInteractionTracker;
+import com.android.systemui.statusbar.RankingBuilder;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.collection.ShadeListBuilder.OnRenderListListener;
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection;
@@ -1797,6 +1798,7 @@
 
     @Test
     public void testStableMultipleSectionOrdering() {
+        // WHEN the list is originally built with reordering disabled
         mListBuilder.setSectioners(asList(
                 new PackageSectioner(PACKAGE_1), new PackageSectioner(PACKAGE_2)));
         mStabilityManager.setAllowEntryReordering(false);
@@ -1807,12 +1809,94 @@
         addNotif(3, PACKAGE_1).setRank(3);
         dispatchBuild();
 
+        // VERIFY the order and that entry reordering has not been suppressed
         verifyBuiltList(
                 notif(0),
                 notif(1),
                 notif(3),
                 notif(2)
         );
+        verify(mStabilityManager, never()).onEntryReorderSuppressed();
+
+        // WHEN the ranks change
+        setNewRank(notif(0).entry, 4);
+        dispatchBuild();
+
+        // VERIFY the order does not change that entry reordering has been suppressed
+        verifyBuiltList(
+                notif(0),
+                notif(1),
+                notif(3),
+                notif(2)
+        );
+        verify(mStabilityManager).onEntryReorderSuppressed();
+
+        // WHEN reordering is now allowed again
+        mStabilityManager.setAllowEntryReordering(true);
+        dispatchBuild();
+
+        // VERIFY that list order changes
+        verifyBuiltList(
+                notif(1),
+                notif(3),
+                notif(0),
+                notif(2)
+        );
+    }
+
+    @Test
+    public void testStableChildOrdering() {
+        // WHEN the list is originally built with reordering disabled
+        mStabilityManager.setAllowEntryReordering(false);
+        addGroupSummary(0, PACKAGE_1, GROUP_1).setRank(0);
+        addGroupChild(1, PACKAGE_1, GROUP_1).setRank(1);
+        addGroupChild(2, PACKAGE_1, GROUP_1).setRank(2);
+        addGroupChild(3, PACKAGE_1, GROUP_1).setRank(3);
+        dispatchBuild();
+
+        // VERIFY the order and that entry reordering has not been suppressed
+        verifyBuiltList(
+                group(
+                        summary(0),
+                        child(1),
+                        child(2),
+                        child(3)
+                )
+        );
+        verify(mStabilityManager, never()).onEntryReorderSuppressed();
+
+        // WHEN the ranks change
+        setNewRank(notif(2).entry, 5);
+        dispatchBuild();
+
+        // VERIFY the order does not change that entry reordering has been suppressed
+        verifyBuiltList(
+                group(
+                        summary(0),
+                        child(1),
+                        child(2),
+                        child(3)
+                )
+        );
+        verify(mStabilityManager).onEntryReorderSuppressed();
+
+        // WHEN reordering is now allowed again
+        mStabilityManager.setAllowEntryReordering(true);
+        dispatchBuild();
+
+        // VERIFY that list order changes
+        verifyBuiltList(
+                group(
+                        summary(0),
+                        child(1),
+                        child(3),
+                        child(2)
+                )
+        );
+    }
+
+    private static void setNewRank(NotificationEntry entry, int rank) {
+        entry.setRanking(new RankingBuilder(entry.getRanking()).setRank(rank).build());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
index 699f77f..2ee3126 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
@@ -59,6 +59,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 import java.util.ArrayList
+import java.util.function.Consumer
 import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
@@ -75,6 +76,7 @@
     private lateinit var mBeforeFinalizeFilterListener: OnBeforeFinalizeFilterListener
     private lateinit var mOnHeadsUpChangedListener: OnHeadsUpChangedListener
     private lateinit var mNotifSectioner: NotifSectioner
+    private lateinit var mActionPressListener: Consumer<NotificationEntry>
 
     private val mNotifPipeline: NotifPipeline = mock()
     private val mLogger = HeadsUpCoordinatorLogger(logcatLogBuffer(), verbose = true)
@@ -131,6 +133,9 @@
         mOnHeadsUpChangedListener = withArgCaptor {
             verify(mHeadsUpManager).addListener(capture())
         }
+        mActionPressListener = withArgCaptor {
+            verify(mRemoteInputManager).addActionPressListener(capture())
+        }
         given(mHeadsUpManager.allEntries).willAnswer { mHuns.stream() }
         given(mHeadsUpManager.isAlerting(anyString())).willAnswer { invocation ->
             val key = invocation.getArgument<String>(0)
@@ -199,6 +204,19 @@
     }
 
     @Test
+    fun hunExtensionCancelledWhenHunActionPressed() {
+        whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true)
+        addHUN(mEntry)
+        whenever(mHeadsUpManager.canRemoveImmediately(anyString())).thenReturn(false)
+        whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L)
+        assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0))
+        mActionPressListener.accept(mEntry)
+        mExecutor.advanceClockToLast()
+        mExecutor.runAllReady()
+        verify(mHeadsUpManager, times(1)).removeNotification(eq(mEntry.key), eq(true))
+    }
+
+    @Test
     fun testCancelUpdatedStickyNotification() {
         whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true)
         addHUN(mEntry)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
deleted file mode 100644
index d082d74..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
+++ /dev/null
@@ -1,89 +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.systemui.statusbar.notification.collection.coordinator;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.os.Handler;
-import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
-import com.android.systemui.statusbar.notification.collection.NotifPipeline;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
-import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
-import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * TODO(b/224771204) Create test cases
- */
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@Ignore
-public class KeyguardCoordinatorTest extends SysuiTestCase {
-    private static final int NOTIF_USER_ID = 0;
-    private static final int CURR_USER_ID = 1;
-
-    @Mock private Handler mMainHandler;
-    @Mock private KeyguardStateController mKeyguardStateController;
-    @Mock private BroadcastDispatcher mBroadcastDispatcher;
-    @Mock private StatusBarStateController mStatusBarStateController;
-    @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    @Mock private HighPriorityProvider mHighPriorityProvider;
-    @Mock private SectionHeaderVisibilityProvider mSectionHeaderVisibilityProvider;
-    @Mock private NotifPipeline mNotifPipeline;
-    @Mock private KeyguardNotificationVisibilityProvider mKeyguardNotificationVisibilityProvider;
-
-    private NotificationEntry mEntry;
-    private NotifFilter mKeyguardFilter;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        KeyguardCoordinator keyguardCoordinator = new KeyguardCoordinator(
-                mStatusBarStateController,
-                mKeyguardUpdateMonitor, mHighPriorityProvider, mSectionHeaderVisibilityProvider,
-                mKeyguardNotificationVisibilityProvider, mock(SharedCoordinatorLogger.class));
-
-        mEntry = new NotificationEntryBuilder()
-                .setUser(new UserHandle(NOTIF_USER_ID))
-                .build();
-
-        ArgumentCaptor<NotifFilter> filterCaptor = ArgumentCaptor.forClass(NotifFilter.class);
-        keyguardCoordinator.attach(mNotifPipeline);
-        verify(mNotifPipeline, times(1)).addFinalizeFilter(filterCaptor.capture());
-        mKeyguardFilter = filterCaptor.getValue();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
new file mode 100644
index 0000000..8c506a6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
+import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.withArgCaptor
+import java.util.function.Consumer
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class KeyguardCoordinatorTest : SysuiTestCase() {
+    private val notifPipeline: NotifPipeline = mock()
+    private val keyguardNotifVisibilityProvider: KeyguardNotificationVisibilityProvider = mock()
+    private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider = mock()
+    private val sharedCoordinatorLogger: SharedCoordinatorLogger = mock()
+    private val statusBarStateController: StatusBarStateController = mock()
+
+    private lateinit var onStateChangeListener: Consumer<String>
+    private lateinit var keyguardFilter: NotifFilter
+
+    @Before
+    fun setup() {
+        val keyguardCoordinator = KeyguardCoordinator(
+            keyguardNotifVisibilityProvider,
+            sectionHeaderVisibilityProvider,
+            sharedCoordinatorLogger,
+            statusBarStateController
+        )
+        keyguardCoordinator.attach(notifPipeline)
+        onStateChangeListener = withArgCaptor {
+            verify(keyguardNotifVisibilityProvider).addOnStateChangedListener(capture())
+        }
+        keyguardFilter = withArgCaptor {
+            verify(notifPipeline).addFinalizeFilter(capture())
+        }
+    }
+
+    @Test
+    fun testSetSectionHeadersVisibleInShade() {
+        clearInvocations(sectionHeaderVisibilityProvider)
+        whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
+        onStateChangeListener.accept("state change")
+        verify(sectionHeaderVisibilityProvider).sectionHeadersVisible = eq(true)
+    }
+
+    @Test
+    fun testSetSectionHeadersNotVisibleOnKeyguard() {
+        clearInvocations(sectionHeaderVisibilityProvider)
+        whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+        onStateChangeListener.accept("state change")
+        verify(sectionHeaderVisibilityProvider).sectionHeadersVisible = eq(false)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index d327be4..a6d3719 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
@@ -31,6 +31,7 @@
 
 import static java.util.Objects.requireNonNull;
 
+import android.os.Handler;
 import android.os.RemoteException;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -42,7 +43,6 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.RankingBuilder;
-import com.android.systemui.statusbar.notification.SectionClassifier;
 import com.android.systemui.statusbar.notification.collection.GroupEntry;
 import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
@@ -57,8 +57,10 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
 import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn;
 import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
+import com.android.systemui.util.settings.SecureSettings;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -97,8 +99,10 @@
     @Mock private IStatusBarService mService;
     @Mock private BindEventManagerImpl mBindEventManagerImpl;
     @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
+    @Mock private Handler mHandler;
+    @Mock private SecureSettings mSecureSettings;
     @Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
-    private final SectionClassifier mSectionClassifier = new SectionClassifier();
+    private final SectionStyleProvider mSectionStyleProvider = new SectionStyleProvider();
 
     private NotifUiAdjustmentProvider mAdjustmentProvider;
 
@@ -110,8 +114,11 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mAdjustmentProvider =
-            new NotifUiAdjustmentProvider(mLockscreenUserManager, mSectionClassifier);
+        mAdjustmentProvider = new NotifUiAdjustmentProvider(
+                mHandler,
+                mSecureSettings,
+                mLockscreenUserManager,
+                mSectionStyleProvider);
         mEntry = getNotificationEntryBuilder().setParent(ROOT_ENTRY).build();
         mInflationError = new Exception(TEST_MESSAGE);
         mErrorManager = new NotifInflationErrorManager();
@@ -449,6 +456,7 @@
             mInflateCallbacks.put(entry, callback);
         }
 
+
         @Override
         public void rebindViews(@NonNull NotificationEntry entry, @NonNull Params params,
                 @NonNull InflationCallback callback) {
@@ -465,6 +473,10 @@
         public void invokeInflateCallbackForEntry(NotificationEntry entry) {
             getInflateCallback(entry).onInflationFinished(entry, entry.getRowController());
         }
+
+        @Override
+        public void releaseViews(@NonNull NotificationEntry entry) {
+        }
     }
 
     private void fireAddEvents(List<? extends ListEntry> entries) {
@@ -490,7 +502,7 @@
     private static final int TEST_MAX_GROUP_DELAY = 100;
 
     private void setSectionIsLowPriority(boolean minimized) {
-        mSectionClassifier.setMinimizedSections(minimized
+        mSectionStyleProvider.setMinimizedSections(minimized
                 ? Collections.singleton(mNotifSection.getSectioner())
                 : Collections.emptyList());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
index 15c1cb7..50b3fc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
@@ -42,7 +42,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.RankingBuilder;
 import com.android.systemui.statusbar.SbnBuilder;
-import com.android.systemui.statusbar.notification.SectionClassifier;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -50,6 +49,7 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
 import com.android.systemui.statusbar.notification.collection.render.NodeController;
 import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
 
@@ -70,7 +70,7 @@
 
     @Mock private StatusBarStateController mStatusBarStateController;
     @Mock private HighPriorityProvider mHighPriorityProvider;
-    @Mock private SectionClassifier mSectionClassifier;
+    @Mock private SectionStyleProvider mSectionStyleProvider;
     @Mock private NotifPipeline mNotifPipeline;
     @Mock private NodeController mAlertingHeaderController;
     @Mock private NodeController mSilentNodeController;
@@ -94,7 +94,7 @@
         mRankingCoordinator = new RankingCoordinator(
                 mStatusBarStateController,
                 mHighPriorityProvider,
-                mSectionClassifier,
+                mSectionStyleProvider,
                 mAlertingHeaderController,
                 mSilentHeaderController,
                 mSilentNodeController);
@@ -102,7 +102,7 @@
         mEntry.setRanking(getRankingForUnfilteredNotif().build());
 
         mRankingCoordinator.attach(mNotifPipeline);
-        verify(mSectionClassifier).setMinimizedSections(any());
+        verify(mSectionStyleProvider).setMinimizedSections(any());
         verify(mNotifPipeline, times(2)).addPreGroupFilter(mNotifFilterCaptor.capture());
         mCapturedSuspendedFilter = mNotifFilterCaptor.getAllValues().get(0);
         mCapturedDozingFilter = mNotifFilterCaptor.getAllValues().get(1);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
index 447ba15..3f3de00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
@@ -21,13 +21,13 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.notification.AssistantFeedbackController
 import com.android.systemui.statusbar.notification.FeedbackIcon
-import com.android.systemui.statusbar.notification.SectionClassifier
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
 import com.android.systemui.statusbar.notification.collection.render.NotifRowController
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
@@ -37,8 +37,8 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations.initMocks
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations.initMocks
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -53,7 +53,7 @@
 
     @Mock private lateinit var pipeline: NotifPipeline
     @Mock private lateinit var assistantFeedbackController: AssistantFeedbackController
-    @Mock private lateinit var sectionClassifier: SectionClassifier
+    @Mock private lateinit var sectionStyleProvider: SectionStyleProvider
 
     @Mock private lateinit var section1: NotifSection
     @Mock private lateinit var section2: NotifSection
@@ -66,7 +66,7 @@
         coordinator = RowAppearanceCoordinator(
             mContext,
             assistantFeedbackController,
-            sectionClassifier
+            sectionStyleProvider
         )
         coordinator.attach(pipeline)
         beforeRenderListListener = withArgCaptor {
@@ -82,8 +82,8 @@
 
     @Test
     fun testSetSystemExpandedOnlyOnFirst() {
-        whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(false)
-        whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(false)
+        whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(false)
+        whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(false)
         beforeRenderListListener.onBeforeRenderList(listOf(entry1, entry2))
         afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
         verify(controller1).setSystemExpanded(eq(true))
@@ -93,8 +93,8 @@
 
     @Test
     fun testSetSystemExpandedNeverIfMinimized() {
-        whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(true)
-        whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(true)
+        whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(true)
+        whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(true)
         beforeRenderListListener.onBeforeRenderList(listOf(entry1, entry2))
         afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
         verify(controller1).setSystemExpanded(eq(false))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
new file mode 100644
index 0000000..5ba926e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.withArgCaptor
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper
+class ViewConfigCoordinatorTest : SysuiTestCase() {
+    private lateinit var coordinator: ViewConfigCoordinator
+
+    // Captured
+    private lateinit var userChangedListener: UserChangedListener
+    private lateinit var configurationListener: ConfigurationController.ConfigurationListener
+    private lateinit var keyguardUpdateMonitorCallback: KeyguardUpdateMonitorCallback
+
+    // Mocks
+    private val entry: NotificationEntry = mock()
+    private val row: ExpandableNotificationRow = mock()
+    private val pipeline: NotifPipeline = mock()
+    private val configurationController: ConfigurationController = mock()
+    private val lockscreenUserManager: NotificationLockscreenUserManager = mock()
+    private val gutsManager: NotificationGutsManager = mock()
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor = mock()
+
+    @Before
+    fun setUp() {
+        whenever(pipeline.isNewPipelineEnabled).thenReturn(true)
+        whenever(pipeline.allNotifs).thenReturn(listOf(entry))
+        whenever(entry.row).thenReturn(row)
+        coordinator = ViewConfigCoordinator(
+            configurationController,
+            lockscreenUserManager,
+            gutsManager,
+            keyguardUpdateMonitor)
+        coordinator.attach(pipeline)
+        userChangedListener = withArgCaptor {
+            verify(lockscreenUserManager).addUserChangedListener(capture())
+        }
+        configurationListener = withArgCaptor {
+            verify(configurationController).addCallback(capture())
+        }
+        keyguardUpdateMonitorCallback = withArgCaptor {
+            verify(keyguardUpdateMonitor).registerCallback(capture())
+        }
+    }
+
+    @Test
+    fun uiModeChangePropagatesToRow() {
+        configurationListener.onUiModeChanged()
+        verify(entry).row
+        verify(row).onUiModeChanged()
+        verifyNoMoreInteractions(entry, row)
+    }
+
+    @Test
+    fun themeChangePropagatesToEntry() {
+        configurationListener.onThemeChanged()
+        verify(entry).onDensityOrFontScaleChanged()
+        verify(entry).areGutsExposed()
+        verifyNoMoreInteractions(entry, row)
+    }
+
+    @Test
+    fun densityChangePropagatesToEntry() {
+        configurationListener.onDensityOrFontScaleChanged()
+        verify(entry).onDensityOrFontScaleChanged()
+        verify(entry).areGutsExposed()
+        verifyNoMoreInteractions(entry, row)
+    }
+
+    @Test
+    fun switchingUserDefersChangesWithUserChangedEventAfter() {
+        // GIVEN switching users
+        keyguardUpdateMonitorCallback.onUserSwitching(10)
+
+        // WHEN configuration changes happen
+        configurationListener.onUiModeChanged()
+        configurationListener.onDensityOrFontScaleChanged()
+        configurationListener.onThemeChanged()
+
+        // VERIFY no changes are propagated
+        verifyNoMoreInteractions(entry, row)
+
+        // WHEN user switch completes
+        keyguardUpdateMonitorCallback.onUserSwitchComplete(10)
+
+        // VERIFY the changes propagate
+        verify(entry).row
+        verify(row).onUiModeChanged()
+        verify(entry).onDensityOrFontScaleChanged()
+        verify(entry).areGutsExposed()
+        verifyNoMoreInteractions(entry, row)
+        clearInvocations(entry, row)
+
+        // WHEN user change happens after the switching window
+        userChangedListener.onUserChanged(10)
+
+        // VERIFY user change itself does not re-trigger updates
+        verifyNoMoreInteractions(entry, row)
+    }
+
+    @Test
+    fun switchingUserDefersChangesWithUserChangedEventDuring() {
+        // GIVEN switching users
+        keyguardUpdateMonitorCallback.onUserSwitching(10)
+
+        // WHEN configuration changes happen
+        configurationListener.onUiModeChanged()
+        configurationListener.onDensityOrFontScaleChanged()
+        configurationListener.onThemeChanged()
+
+        // VERIFY no changes are propagated
+        verifyNoMoreInteractions(entry, row)
+
+        // WHEN user change happens during the switching window
+        userChangedListener.onUserChanged(10)
+
+        // VERIFY the changes propagate
+        verify(entry).row
+        verify(row).onUiModeChanged()
+        verify(entry).onDensityOrFontScaleChanged()
+        verify(entry).areGutsExposed()
+        verifyNoMoreInteractions(entry, row)
+        clearInvocations(entry, row)
+
+        // WHEN user switch completes
+        keyguardUpdateMonitorCallback.onUserSwitchComplete(10)
+
+        // VERIFY the switching window closing does not re-propagate
+        verifyNoMoreInteractions(entry, row)
+    }
+
+    @Test
+    fun switchingUserDefersChangesWithUserChangedEventBefore() {
+        // WHEN user change happens before configuration changes or switching window
+        userChangedListener.onUserChanged(10)
+
+        // VERIFY no changes happen
+        verifyNoMoreInteractions(entry, row)
+
+        // WHEN switching users then configuration changes happen
+        keyguardUpdateMonitorCallback.onUserSwitching(10)
+
+        configurationListener.onUiModeChanged()
+        configurationListener.onDensityOrFontScaleChanged()
+        configurationListener.onThemeChanged()
+
+        // VERIFY no changes happen
+        verifyNoMoreInteractions(entry, row)
+
+        // WHEN user switch completes
+        keyguardUpdateMonitorCallback.onUserSwitchComplete(10)
+
+        // VERIFY the changes propagate
+        verify(entry).row
+        verify(row).onUiModeChanged()
+        verify(entry).onDensityOrFontScaleChanged()
+        verify(entry).areGutsExposed()
+        verifyNoMoreInteractions(entry, row)
+        clearInvocations(entry, row)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
index f3aa20b..2f37f89 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
@@ -136,7 +136,8 @@
     @Test
     public void testScreenOff_groupAndSectionChangesAllowed() {
         // GIVEN screen is off, panel isn't expanded and device isn't pulsing
-        setScreenOn(false);
+        setFullyDozed(true);
+        setSleepy(true);
         setPanelExpanded(false);
         setPulsing(false);
 
@@ -149,9 +150,42 @@
     }
 
     @Test
+    public void testScreenTurningOff_groupAndSectionChangesNotAllowed() {
+        // GIVEN the screen is turning off (sleepy but partially dozed)
+        setFullyDozed(false);
+        setSleepy(true);
+        setPanelExpanded(true);
+        setPulsing(false);
+
+        // THEN group changes are NOT allowed
+        assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+        assertFalse(mNotifStabilityManager.isGroupPruneAllowed(mGroupEntry));
+
+        // THEN section changes are NOT allowed
+        assertFalse(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+    }
+
+    @Test
+    public void testScreenTurningOn_groupAndSectionChangesNotAllowed() {
+        // GIVEN the screen is turning on (still fully dozed, not sleepy)
+        setFullyDozed(true);
+        setSleepy(false);
+        setPanelExpanded(true);
+        setPulsing(false);
+
+        // THEN group changes are NOT allowed
+        assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+        assertFalse(mNotifStabilityManager.isGroupPruneAllowed(mGroupEntry));
+
+        // THEN section changes are NOT allowed
+        assertFalse(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+    }
+
+    @Test
     public void testPanelNotExpanded_groupAndSectionChangesAllowed() {
         // GIVEN screen is on but the panel isn't expanded and device isn't pulsing
-        setScreenOn(true);
+        setFullyDozed(false);
+        setSleepy(false);
         setPanelExpanded(false);
         setPulsing(false);
 
@@ -166,7 +200,8 @@
     @Test
     public void testPanelExpanded_groupAndSectionChangesNotAllowed() {
         // GIVEN the panel true expanded and device isn't pulsing
-        setScreenOn(true);
+        setFullyDozed(false);
+        setSleepy(false);
         setPanelExpanded(true);
         setPulsing(false);
 
@@ -181,7 +216,8 @@
     @Test
     public void testPulsing_screenOff_groupAndSectionChangesNotAllowed() {
         // GIVEN the device is pulsing and screen is off
-        setScreenOn(false);
+        setFullyDozed(true);
+        setSleepy(true);
         setPulsing(true);
 
         // THEN group changes are NOT allowed
@@ -195,7 +231,8 @@
     @Test
     public void testPulsing_panelNotExpanded_groupAndSectionChangesNotAllowed() {
         // GIVEN the device is pulsing and screen is off with the panel not expanded
-        setScreenOn(false);
+        setFullyDozed(true);
+        setSleepy(true);
         setPanelExpanded(false);
         setPulsing(true);
 
@@ -211,7 +248,8 @@
     public void testOverrideReorderingSuppression_onlySectionChangesAllowed() {
         // GIVEN section changes typically wouldn't be allowed because the panel is expanded and
         // we're not pulsing
-        setScreenOn(true);
+        setFullyDozed(false);
+        setSleepy(false);
         setPanelExpanded(true);
         setPulsing(true);
 
@@ -233,7 +271,8 @@
     @Test
     public void testTemporarilyAllowSectionChanges_callsInvalidate() {
         // GIVEN section changes typically wouldn't be allowed because the panel is expanded
-        setScreenOn(true);
+        setFullyDozed(false);
+        setSleepy(false);
         setPanelExpanded(true);
         setPulsing(false);
 
@@ -247,7 +286,8 @@
     @Test
     public void testTemporarilyAllowSectionChanges_noInvalidationCalled() {
         // GIVEN section changes typically WOULD be allowed
-        setScreenOn(false);
+        setFullyDozed(true);
+        setSleepy(true);
         setPanelExpanded(false);
         setPulsing(false);
 
@@ -261,7 +301,8 @@
     @Test
     public void testTemporarilyAllowSectionChangesTimeout() {
         // GIVEN section changes typically WOULD be allowed
-        setScreenOn(false);
+        setFullyDozed(true);
+        setSleepy(true);
         setPanelExpanded(false);
         setPulsing(false);
         assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
@@ -292,7 +333,8 @@
     @Test
     public void testTemporarilyAllowSectionChanges_isPulsingChangeBeforeTimeout() {
         // GIVEN section changes typically wouldn't be allowed because the device is pulsing
-        setScreenOn(false);
+        setFullyDozed(true);
+        setSleepy(true);
         setPanelExpanded(false);
         setPulsing(true);
 
@@ -315,8 +357,11 @@
         // WHEN device isn't pulsing anymore
         setPulsing(false);
 
-        // WHEN screen isn't on
-        setScreenOn(false);
+        // WHEN fully dozed
+        setFullyDozed(true);
+
+        // WHEN sleepy
+        setSleepy(true);
 
         // WHEN panel isn't expanded
         setPanelExpanded(false);
@@ -330,7 +375,8 @@
     public void testNotSuppressingGroupChangesAnymore_invalidationCalled() {
         // GIVEN visual stability is being maintained b/c panel is expanded
         setPulsing(false);
-        setScreenOn(true);
+        setFullyDozed(false);
+        setSleepy(false);
         setPanelExpanded(true);
 
         assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
@@ -399,7 +445,8 @@
     public void testNotSuppressingEntryReorderingAnymoreWillInvalidate() {
         // GIVEN visual stability is being maintained b/c panel is expanded
         setPulsing(false);
-        setScreenOn(true);
+        setFullyDozed(false);
+        setSleepy(false);
         setPanelExpanded(true);
 
         assertFalse(mNotifStabilityManager.isEntryReorderingAllowed(mEntry));
@@ -417,7 +464,8 @@
     public void testQueryingEntryReorderingButNotReportingReorderSuppressedDoesNotInvalidate() {
         // GIVEN visual stability is being maintained b/c panel is expanded
         setPulsing(false);
-        setScreenOn(true);
+        setFullyDozed(false);
+        setSleepy(false);
         setPanelExpanded(true);
 
         assertFalse(mNotifStabilityManager.isEntryReorderingAllowed(mEntry));
@@ -432,7 +480,8 @@
     @Test
     public void testHeadsUp_allowedToChangeGroupAndSection() {
         // GIVEN group + section changes disallowed
-        setScreenOn(true);
+        setFullyDozed(false);
+        setSleepy(false);
         setPanelExpanded(true);
         setPulsing(true);
         assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
@@ -462,11 +511,16 @@
         mStatusBarStateListener.onPulsingChanged(pulsing);
     }
 
-    private void setScreenOn(boolean screenOn) {
-        if (screenOn) {
-            mWakefulnessObserver.onStartedWakingUp();
-        } else {
+    private void setFullyDozed(boolean fullyDozed) {
+        float dozeAmount = fullyDozed ? 1 : 0;
+        mStatusBarStateListener.onDozeAmountChanged(dozeAmount, dozeAmount);
+    }
+
+    private void setSleepy(boolean sleepy) {
+        if (sleepy) {
             mWakefulnessObserver.onFinishedGoingToSleep();
+        } else {
+            mWakefulnessObserver.onStartedWakingUp();
         }
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
index dd15cae..246943e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
@@ -1,29 +1,87 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package com.android.systemui.statusbar.notification.collection.inflation
 
+import android.database.ContentObserver
+import android.os.Handler
+import android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
-import com.android.systemui.statusbar.notification.SectionClassifier
+import com.android.systemui.statusbar.notification.collection.GroupEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.withArgCaptor
+import com.android.systemui.util.settings.FakeSettings
+import com.android.systemui.util.settings.SecureSettings
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.inOrder
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @RunWithLooper
 class NotifUiAdjustmentProviderTest : SysuiTestCase() {
     private val lockscreenUserManager: NotificationLockscreenUserManager = mock()
-    private val sectionClassifier: SectionClassifier = mock()
+    private val sectionStyleProvider: SectionStyleProvider = mock()
+    private val handler: Handler = mock()
+    private val secureSettings: SecureSettings = mock()
+    private val uri = FakeSettings().getUriFor(SHOW_NOTIFICATION_SNOOZE)
+    private val dirtyListener: Runnable = mock()
+
+    private val section = NotifSection(mock(), 0)
+    private val entry = NotificationEntryBuilder()
+        .setSection(section)
+        .setParent(GroupEntry.ROOT_ENTRY)
+        .build()
+
+    private lateinit var contentObserver: ContentObserver
 
     private val adjustmentProvider = NotifUiAdjustmentProvider(
+        handler,
+        secureSettings,
         lockscreenUserManager,
-        sectionClassifier,
+        sectionStyleProvider,
     )
 
+    @Before
+    fun setup() {
+        verifyNoMoreInteractions(secureSettings)
+        adjustmentProvider.addDirtyListener(dirtyListener)
+        verify(secureSettings).getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())
+        contentObserver = withArgCaptor {
+            verify(secureSettings).registerContentObserverForUser(
+                eq(SHOW_NOTIFICATION_SNOOZE), capture(), any()
+            )
+        }
+        verifyNoMoreInteractions(secureSettings, dirtyListener)
+    }
+
     @Test
     fun notifLockscreenStateChangeWillNotifDirty() {
         val dirtyListener = mock<Runnable>()
@@ -33,6 +91,35 @@
                 verify(lockscreenUserManager).addNotificationStateChangedListener(capture())
             }
         notifLocksreenStateChangeListener.onNotificationStateChanged()
-        verify(dirtyListener).run();
+        verify(dirtyListener).run()
+    }
+
+    @Test
+    fun additionalAddDoesNotRegisterAgain() {
+        clearInvocations(secureSettings)
+        adjustmentProvider.addDirtyListener(mock())
+        verifyNoMoreInteractions(secureSettings)
+    }
+
+    @Test
+    fun onChangeWillQueryThenNotifyDirty() {
+        contentObserver.onChange(false, listOf(uri), 0, 0)
+        with(inOrder(secureSettings, dirtyListener)) {
+            verify(secureSettings).getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())
+            verify(dirtyListener).run()
+        }
+    }
+
+    @Test
+    fun changingSnoozeChangesProvidedAdjustment() {
+        whenever(secureSettings.getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())).thenReturn(0)
+        val original = adjustmentProvider.calculateAdjustment(entry)
+        assertThat(original.isSnoozeEnabled).isFalse()
+
+        whenever(secureSettings.getInt(eq(SHOW_NOTIFICATION_SNOOZE), any())).thenReturn(1)
+        contentObserver.onChange(false, listOf(uri), 0, 0)
+        val withSnoozing = adjustmentProvider.calculateAdjustment(entry)
+        assertThat(withSnoozing.isSnoozeEnabled).isTrue()
+        assertThat(withSnoozing).isNotEqualTo(original)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLoggerTest.kt
new file mode 100644
index 0000000..6c07174
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLoggerTest.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.collection.notifcollection
+
+import android.service.notification.NotificationListenerService.RankingMap
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper
+class NotifCollectionLoggerTest : SysuiTestCase() {
+    private val logger: NotifCollectionLogger = mock()
+    private val entry1: NotificationEntry = NotificationEntryBuilder().setId(1).build()
+    private val entry2: NotificationEntry = NotificationEntryBuilder().setId(2).build()
+
+    private fun mapOfEntries(vararg entries: NotificationEntry): Map<String, NotificationEntry> =
+        entries.associateBy { it.key }
+
+    private fun rankingMapOf(vararg entries: NotificationEntry): RankingMap =
+        RankingMap(entries.map { it.ranking }.toTypedArray())
+
+    @Test
+    fun testMaybeLogInconsistentRankings_logsNewlyInconsistentRanking() {
+        val rankingMap = rankingMapOf(entry1)
+        maybeLogInconsistentRankings(
+            logger = logger,
+            oldKeysWithoutRankings = emptySet(),
+            newEntriesWithoutRankings = mapOfEntries(entry2),
+            rankingMap = rankingMap
+        )
+        verify(logger).logMissingRankings(
+            newlyInconsistentEntries = eq(listOf(entry2)),
+            totalInconsistent = eq(1),
+            rankingMap = eq(rankingMap),
+        )
+        verifyNoMoreInteractions(logger)
+    }
+
+    @Test
+    fun testMaybeLogInconsistentRankings_doesNotLogAlreadyInconsistentRanking() {
+        maybeLogInconsistentRankings(
+            logger = logger,
+            oldKeysWithoutRankings = setOf(entry2.key),
+            newEntriesWithoutRankings = mapOfEntries(entry2),
+            rankingMap = rankingMapOf(entry1)
+        )
+        verifyNoMoreInteractions(logger)
+    }
+
+    @Test
+    fun testMaybeLogInconsistentRankings_logsWhenRankingIsAdded() {
+        maybeLogInconsistentRankings(
+            logger = logger,
+            oldKeysWithoutRankings = setOf(entry2.key),
+            newEntriesWithoutRankings = mapOfEntries(),
+            rankingMap = rankingMapOf(entry1, entry2)
+        )
+        verify(logger).logRecoveredRankings(
+            newlyConsistentKeys = eq(listOf(entry2.key)),
+        )
+        verifyNoMoreInteractions(logger)
+    }
+
+    @Test
+    fun testMaybeLogInconsistentRankings_doesNotLogsWhenEntryIsRemoved() {
+        maybeLogInconsistentRankings(
+            logger = logger,
+            oldKeysWithoutRankings = setOf(entry2.key),
+            newEntriesWithoutRankings = mapOfEntries(),
+            rankingMap = rankingMapOf(entry1)
+        )
+        verifyNoMoreInteractions(logger)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
index 0e18658..ac254ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
@@ -19,7 +19,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
 import com.android.systemui.statusbar.notification.collection.ListEntry
@@ -28,6 +27,7 @@
 import com.android.systemui.statusbar.notification.collection.getAttachState
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
 import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
 import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
@@ -413,4 +413,4 @@
             return nodeController
         }
     }, index)
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
index 0d5a5fe..3f641df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java
@@ -72,32 +72,32 @@
         });
 
         mViewBinder.bindHeadsUpView(mEntry, null);
-        verify(mLogger).startBindingHun(eq("key"));
+        verify(mLogger).startBindingHun(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
         callback.get().onBindFinished(mEntry);
-        verify(mLogger).entryBoundSuccessfully(eq("key"));
+        verify(mLogger).entryBoundSuccessfully(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
         mViewBinder.bindHeadsUpView(mEntry, null);
-        verify(mLogger).startBindingHun(eq("key"));
+        verify(mLogger).startBindingHun(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
         callback.get().onBindFinished(mEntry);
-        verify(mLogger).entryBoundSuccessfully(eq("key"));
+        verify(mLogger).entryBoundSuccessfully(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
         mViewBinder.unbindHeadsUpView(mEntry);
-        verify(mLogger).entryContentViewMarkedFreeable(eq("key"));
+        verify(mLogger).entryContentViewMarkedFreeable(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
         callback.get().onBindFinished(mEntry);
-        verify(mLogger).entryUnbound(eq("key"));
+        verify(mLogger).entryUnbound(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
     }
@@ -111,12 +111,12 @@
         });
 
         mViewBinder.bindHeadsUpView(mEntry, null);
-        verify(mLogger).startBindingHun(eq("key"));
+        verify(mLogger).startBindingHun(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
         mViewBinder.abortBindCallback(mEntry);
-        verify(mLogger).currentOngoingBindingAborted(eq("key"));
+        verify(mLogger).currentOngoingBindingAborted(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
@@ -135,18 +135,18 @@
         });
 
         mViewBinder.bindHeadsUpView(mEntry, null);
-        verify(mLogger).startBindingHun(eq("key"));
+        verify(mLogger).startBindingHun(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
         mViewBinder.unbindHeadsUpView(mEntry);
-        verify(mLogger).currentOngoingBindingAborted(eq("key"));
-        verify(mLogger).entryContentViewMarkedFreeable(eq("key"));
+        verify(mLogger).currentOngoingBindingAborted(eq(mEntry));
+        verify(mLogger).entryContentViewMarkedFreeable(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
 
         callback.get().onBindFinished(mEntry);
-        verify(mLogger).entryUnbound(eq("key"));
+        verify(mLogger).entryUnbound(eq(mEntry));
         verifyNoMoreInteractions(mLogger);
         clearInvocations(mLogger);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index 90627cb..3f56cf9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -17,6 +17,7 @@
 
 
 import static android.app.Notification.FLAG_BUBBLE;
+import static android.app.Notification.GROUP_ALERT_SUMMARY;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
@@ -432,6 +433,17 @@
     }
 
     /**
+     * Test that notification can bubble even if it is a child in a group and group settings are
+     * set to alert only for summary notifications.
+     */
+    @Test
+    public void testShouldBubbleUp_notifInGroupWithOnlySummaryAlerts() {
+        ensureStateForBubbleUp();
+        NotificationEntry bubble = createBubble("testgroup", GROUP_ALERT_SUMMARY);
+        assertThat(mNotifInterruptionStateProvider.shouldBubbleUp(bubble)).isTrue();
+    }
+
+    /**
      * If the notification doesn't have permission to bubble, it shouldn't bubble.
      */
     @Test
@@ -498,16 +510,27 @@
     }
 
     private NotificationEntry createBubble() {
+        return createBubble(null, null);
+    }
+
+    private NotificationEntry createBubble(String groupKey, Integer groupAlert) {
         Notification.BubbleMetadata data = new Notification.BubbleMetadata.Builder(
                 PendingIntent.getActivity(mContext, 0, new Intent(),
                     PendingIntent.FLAG_MUTABLE),
                         Icon.createWithResource(mContext.getResources(), R.drawable.android))
                 .build();
-        Notification n = new Notification.Builder(getContext(), "a")
+        Notification.Builder nb = new Notification.Builder(getContext(), "a")
                 .setContentTitle("title")
                 .setContentText("content text")
-                .setBubbleMetadata(data)
-                .build();
+                .setBubbleMetadata(data);
+        if (groupKey != null) {
+            nb.setGroup(groupKey);
+            nb.setGroupSummary(false);
+        }
+        if (groupAlert != null) {
+            nb.setGroupAlertBehavior(groupAlert);
+        }
+        Notification n = nb.build();
         n.flags |= FLAG_BUBBLE;
 
         return new NotificationEntryBuilder()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index b1bf971..f8b39e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -43,6 +43,7 @@
 
 import android.app.Notification;
 import android.app.NotificationChannel;
+import android.graphics.Color;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -110,6 +111,28 @@
     }
 
     @Test
+    public void testUpdateBackgroundColors_isRecursive() {
+        mGroupRow.setTintColor(Color.RED);
+        mGroupRow.getChildNotificationAt(0).setTintColor(Color.GREEN);
+        mGroupRow.getChildNotificationAt(1).setTintColor(Color.BLUE);
+
+        assertThat(mGroupRow.getCurrentBackgroundTint()).isEqualTo(Color.RED);
+        assertThat(mGroupRow.getChildNotificationAt(0).getCurrentBackgroundTint())
+                .isEqualTo(Color.GREEN);
+        assertThat(mGroupRow.getChildNotificationAt(1).getCurrentBackgroundTint())
+                .isEqualTo(Color.BLUE);
+
+        mGroupRow.updateBackgroundColors();
+
+        int resetTint = mGroupRow.getCurrentBackgroundTint();
+        assertThat(resetTint).isNotEqualTo(Color.RED);
+        assertThat(mGroupRow.getChildNotificationAt(0).getCurrentBackgroundTint())
+                .isEqualTo(resetTint);
+        assertThat(mGroupRow.getChildNotificationAt(1).getCurrentBackgroundTint())
+                .isEqualTo(resetTint);
+    }
+
+    @Test
     public void testSetSensitiveOnNotifRowNotifiesOfHeightChange() throws InterruptedException {
         // GIVEN a sensitive notification row that's currently redacted
         measureAndLayout(mNotifRow);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 94a93ad..4efd5c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -47,6 +47,7 @@
 import com.android.systemui.classifier.FalsingCollectorFake;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.media.KeyguardMediaController;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
@@ -113,6 +114,7 @@
     @Mock private SysuiColorExtractor mColorExtractor;
     @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
     @Mock private MetricsLogger mMetricsLogger;
+    @Mock private DumpManager mDumpManager;
     @Mock private Resources mResources;
     @Mock(answer = Answers.RETURNS_SELF)
     private NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder;
@@ -167,6 +169,7 @@
                 mColorExtractor,
                 mNotificationLockscreenUserManager,
                 mMetricsLogger,
+                mDumpManager,
                 new FalsingCollectorFake(),
                 new FalsingManagerFake(),
                 mResources,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index f5fe6f3..b83743c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -39,6 +39,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -122,12 +123,12 @@
         allowTestableLooperAsMainThread();
 
         // Interact with real instance of AmbientState.
-        mAmbientState = new AmbientState(
+        mAmbientState = spy(new AmbientState(
                 mContext,
                 mDumpManager,
                 mNotificationSectionsManager,
                 mBypassController,
-                mStatusBarKeyguardViewManager);
+                mStatusBarKeyguardViewManager));
 
         // Inject dependencies before initializing the layout
         mDependency.injectTestDependency(SysuiStatusBarStateController.class, mBarState);
@@ -190,7 +191,7 @@
                 endHeight, dozeAmount);
 
         mStackScroller.updateStackHeight(endHeight, expansionFraction);
-        assertTrue(mAmbientState.getStackHeight() == expected);
+        assertThat(mAmbientState.getStackHeight()).isEqualTo(expected);
     }
 
     @Test
@@ -205,7 +206,74 @@
                 endHeight, expansionFraction);
 
         mStackScroller.updateStackHeight(endHeight, expansionFraction);
-        assertTrue(mAmbientState.getStackHeight() == expected);
+        assertThat(mAmbientState.getStackHeight()).isEqualTo(expected);
+    }
+
+    @Test
+    public void updateStackEndHeightAndStackHeight_normallyUpdatesBoth() {
+        final float expansionFraction = 0.5f;
+        mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
+
+        // Validate that by default we update everything
+        clearInvocations(mAmbientState);
+        mStackScroller.updateStackEndHeightAndStackHeight(expansionFraction);
+        verify(mAmbientState).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
+    }
+
+    @Test
+    public void updateStackEndHeightAndStackHeight_onlyUpdatesStackHeightDuringSwipeUp() {
+        final float expansionFraction = 0.5f;
+        mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
+        mAmbientState.setSwipingUp(true);
+
+        // Validate that when the gesture is in progress, we update only the stackHeight
+        clearInvocations(mAmbientState);
+        mStackScroller.updateStackEndHeightAndStackHeight(expansionFraction);
+        verify(mAmbientState, never()).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
+    }
+
+    @Test
+    public void setPanelFlinging_updatesStackEndHeightOnlyOnFinish() {
+        final float expansionFraction = 0.5f;
+        mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
+        mAmbientState.setSwipingUp(true);
+        mStackScroller.setPanelFlinging(true);
+        mAmbientState.setSwipingUp(false);
+
+        // Validate that when the animation is running, we update only the stackHeight
+        clearInvocations(mAmbientState);
+        mStackScroller.updateStackEndHeightAndStackHeight(expansionFraction);
+        verify(mAmbientState, never()).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
+
+        // Validate that when the animation ends the stackEndHeight is recalculated immediately
+        clearInvocations(mAmbientState);
+        mStackScroller.setPanelFlinging(false);
+        verify(mAmbientState).setIsFlinging(eq(false));
+        verify(mAmbientState).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
+    }
+
+    @Test
+    public void setUnlockHintRunning_updatesStackEndHeightOnlyOnFinish() {
+        final float expansionFraction = 0.5f;
+        mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
+        mStackScroller.setUnlockHintRunning(true);
+
+        // Validate that when the animation is running, we update only the stackHeight
+        clearInvocations(mAmbientState);
+        mStackScroller.updateStackEndHeightAndStackHeight(expansionFraction);
+        verify(mAmbientState, never()).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
+
+        // Validate that when the animation ends the stackEndHeight is recalculated immediately
+        clearInvocations(mAmbientState);
+        mStackScroller.setUnlockHintRunning(false);
+        verify(mAmbientState).setUnlockHintRunning(eq(false));
+        verify(mAmbientState).setStackEndHeight(anyFloat());
+        verify(mAmbientState).setStackHeight(anyFloat());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index ec20271..ed3f710 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -266,7 +266,6 @@
     @Test
     public void clockPositionedDependingOnMarginInSplitShade() {
         setSplitShadeTopMargin(400);
-        mClockPositionAlgorithm.loadDimens(mResources);
         givenLockScreen();
         mIsSplitShade = true;
         // WHEN the position algorithm is run
@@ -294,7 +293,6 @@
     public void notifPaddingAccountsForMultiUserSwitcherInSplitShade() {
         setSplitShadeTopMargin(100);
         mUserSwitchHeight = 150;
-        mClockPositionAlgorithm.loadDimens(mResources);
         givenLockScreen();
         mIsSplitShade = true;
         // WHEN the position algorithm is run
@@ -307,7 +305,6 @@
     public void clockDoesntAccountForMultiUserSwitcherInSplitShade() {
         setSplitShadeTopMargin(100);
         mUserSwitchHeight = 150;
-        mClockPositionAlgorithm.loadDimens(mResources);
         givenLockScreen();
         mIsSplitShade = true;
         // WHEN the position algorithm is run
@@ -382,11 +379,25 @@
         mQsExpansion = 1;
         // WHEN the clock position algorithm is run
         positionClock();
-        // THEN the clock Y position is the middle of the screen (SCREEN_HEIGHT / 2).
+        // THEN the clock is transparent.
         assertThat(mClockPosition.clockAlpha).isEqualTo(TRANSPARENT);
     }
 
     @Test
+    public void clockNotHiddenWhenQsIsExpandedInSplitShade() {
+        // GIVEN on the split lock screen with QS expansion
+        givenLockScreen();
+        mIsSplitShade = true;
+        setSplitShadeTopMargin(100);
+        mQsExpansion = 1;
+
+        // WHEN the clock position algorithm is run
+        positionClock();
+
+        assertThat(mClockPosition.clockAlpha).isEqualTo(1);
+    }
+
+    @Test
     public void clockPositionMinimizesBurnInMovementToAvoidUdfpsOnAOD() {
         // GIVEN a center aligned clock
         mClockTopAligned = false;
@@ -524,6 +535,7 @@
     private void setSplitShadeTopMargin(int value) {
         when(mResources.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin))
                 .thenReturn(value);
+        mClockPositionAlgorithm.loadDimens(mResources);
     }
 
     private void givenHighestBurnInOffset() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
index d47644f..79c7e55 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java
@@ -60,6 +60,7 @@
 import android.view.ViewParent;
 import android.view.ViewPropertyAnimator;
 import android.view.ViewStub;
+import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 
@@ -349,6 +350,8 @@
     private View mQsHeader;
     @Mock
     private ViewParent mViewParent;
+    @Mock
+    private ViewTreeObserver mViewTreeObserver;
     private NotificationPanelViewController.PanelEventsEmitter mPanelEventsEmitter;
     private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
     private SysuiStatusBarStateController mStatusBarStateController;
@@ -474,6 +477,7 @@
             return null;
         }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
 
+        when(mView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
         when(mView.getParent()).thenReturn(mViewParent);
         when(mQs.getHeader()).thenReturn(mQsHeader);
 
@@ -1006,6 +1010,16 @@
     }
 
     @Test
+    public void testRotatingToSplitShadeWithQsExpanded_transitionsToShadeLocked() {
+        mStatusBarStateController.setState(KEYGUARD);
+        mNotificationPanelViewController.setQsExpanded(true);
+
+        enableSplitShade(true);
+
+        assertThat(mStatusBarStateController.getState()).isEqualTo(SHADE_LOCKED);
+    }
+
+    @Test
     public void testSwitchesToCorrectClockInSinglePaneShade() {
         mStatusBarStateController.setState(KEYGUARD);
 
@@ -1286,6 +1300,43 @@
                 false/*goingToFullShade*/, SHADE/*oldStatusBarState*/);
     }
 
+    @Test
+    public void getMaxPanelHeight_expanding_inSplitShade_returnsSplitShadeFullTransitionDistance() {
+        int splitShadeFullTransitionDistance = 123456;
+        enableSplitShade(true);
+        setSplitShadeFullTransitionDistance(splitShadeFullTransitionDistance);
+        mNotificationPanelViewController.expandWithQs();
+
+        int maxPanelHeight = mNotificationPanelViewController.getMaxPanelHeight();
+
+        assertThat(maxPanelHeight).isEqualTo(splitShadeFullTransitionDistance);
+    }
+
+    @Test
+    public void getMaxPanelHeight_expandingSplitShade_keyguard_returnsNonSplitShadeValue() {
+        mStatusBarStateController.setState(KEYGUARD);
+        int splitShadeFullTransitionDistance = 123456;
+        enableSplitShade(true);
+        setSplitShadeFullTransitionDistance(splitShadeFullTransitionDistance);
+        mNotificationPanelViewController.expandWithQs();
+
+        int maxPanelHeight = mNotificationPanelViewController.getMaxPanelHeight();
+
+        assertThat(maxPanelHeight).isNotEqualTo(splitShadeFullTransitionDistance);
+    }
+
+    @Test
+    public void getMaxPanelHeight_expanding_notSplitShade_returnsNonSplitShadeValue() {
+        int splitShadeFullTransitionDistance = 123456;
+        enableSplitShade(false);
+        setSplitShadeFullTransitionDistance(splitShadeFullTransitionDistance);
+        mNotificationPanelViewController.expandWithQs();
+
+        int maxPanelHeight = mNotificationPanelViewController.getMaxPanelHeight();
+
+        assertThat(maxPanelHeight).isNotEqualTo(splitShadeFullTransitionDistance);
+    }
+
     private static MotionEvent createMotionEvent(int x, int y, int action) {
         return MotionEvent.obtain(
                 /* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0);
@@ -1345,4 +1396,10 @@
     private void onTouchEvent(MotionEvent ev) {
         mTouchHandler.onTouch(mView, ev);
     }
+
+    private void setSplitShadeFullTransitionDistance(int splitShadeFullTransitionDistance) {
+        when(mResources.getDimensionPixelSize(R.dimen.split_shade_full_transition_distance))
+                .thenReturn(splitShadeFullTransitionDistance);
+        mNotificationPanelViewController.updateResources();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 9ab88dc..ba29e95 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -136,6 +136,7 @@
     private class UnfoldConfig : UnfoldTransitionConfig {
         override var isEnabled: Boolean = false
         override var isHingeAngleEnabled: Boolean = false
+        override val halfFoldedTimeoutMillis: Int = 0
     }
 
     private class TestTouchEventHandler : PhoneStatusBarView.TouchEventHandler {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 32df2d7..837b045 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -59,7 +59,6 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.scrim.ScrimView;
-import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.concurrency.FakeExecutor;
@@ -122,8 +121,6 @@
     // TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
     //   event-dispatch-on-registration pattern caused some of these unit tests to fail.)
     @Mock
-    private PanelExpansionStateManager mPanelExpansionStateManager;
-    @Mock
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
 
     private static class AnimatorListener implements Animator.AnimatorListener {
@@ -237,7 +234,6 @@
                 new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
                 mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
                 mScreenOffAnimationController,
-                mPanelExpansionStateManager,
                 mKeyguardUnlockAnimationController,
                 mStatusBarKeyguardViewManager);
         mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
@@ -860,7 +856,6 @@
                 new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
                 mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
                 mScreenOffAnimationController,
-                mPanelExpansionStateManager,
                 mKeyguardUnlockAnimationController,
                 mStatusBarKeyguardViewManager);
         mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 4f2abf2..0c1d042 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -61,7 +61,9 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.util.Optional;
@@ -97,6 +99,7 @@
     @Mock private LatencyTracker mLatencyTracker;
 
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private KeyguardBouncer.BouncerExpansionCallback mBouncerExpansionCallback;
 
     @Before
     public void setUp() {
@@ -136,6 +139,11 @@
                 mBypassController);
         when(mKeyguardStateController.isOccluded()).thenReturn(false);
         mStatusBarKeyguardViewManager.show(null);
+        ArgumentCaptor<KeyguardBouncer.BouncerExpansionCallback> callbackArgumentCaptor =
+                ArgumentCaptor.forClass(KeyguardBouncer.BouncerExpansionCallback.class);
+        verify(mKeyguardBouncerFactory).create(any(ViewGroup.class),
+                callbackArgumentCaptor.capture());
+        mBouncerExpansionCallback = callbackArgumentCaptor.getValue();
     }
 
     @Test
@@ -441,4 +449,24 @@
         return new PanelExpansionChangeEvent(
                 fraction, expanded, tracking, /* dragDownPxAmount= */ 0f);
     }
+
+    @Test
+    public void testReportBouncerOnDreamWhenVisible() {
+        mBouncerExpansionCallback.onVisibilityChanged(true);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
+        Mockito.clearInvocations(mCentralSurfaces);
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+        mBouncerExpansionCallback.onVisibilityChanged(true);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(true);
+    }
+
+    @Test
+    public void testReportBouncerOnDreamWhenNotVisible() {
+        mBouncerExpansionCallback.onVisibilityChanged(false);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
+        Mockito.clearInvocations(mCentralSurfaces);
+        when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
+        mBouncerExpansionCallback.onVisibilityChanged(false);
+        verify(mCentralSurfaces).setBouncerShowingOverDream(false);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt
new file mode 100644
index 0000000..cafe113
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ScrimShadeTransitionControllerTest.kt
@@ -0,0 +1,128 @@
+package com.android.systemui.statusbar.phone.shade.transition
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.phone.ScrimController
+import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
+import com.android.systemui.statusbar.policy.FakeConfigurationController
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ScrimShadeTransitionControllerTest : SysuiTestCase() {
+
+    @Mock private lateinit var scrimController: ScrimController
+    @Mock private lateinit var dumpManager: DumpManager
+    @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
+    private val configurationController = FakeConfigurationController()
+
+    private lateinit var controller: ScrimShadeTransitionController
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        context.ensureTestableResources()
+        controller =
+            ScrimShadeTransitionController(
+                configurationController,
+                dumpManager,
+                scrimController,
+                context.resources,
+                statusBarStateController
+            )
+    }
+
+    @Test
+    fun onPanelExpansionChanged_inSingleShade_setsFractionEqualToEventFraction() {
+        setSplitShadeEnabled(false)
+
+        controller.onPanelExpansionChanged(EXPANSION_EVENT)
+
+        verify(scrimController).setRawPanelExpansionFraction(EXPANSION_EVENT.fraction)
+    }
+
+    @Test
+    fun onPanelExpansionChanged_inSplitShade_unlockedShade_setsFractionBasedOnDragDownAmount() {
+        whenever(statusBarStateController.currentOrUpcomingState)
+            .thenReturn(StatusBarState.SHADE)
+        val scrimShadeTransitionDistance =
+            context.resources.getDimensionPixelSize(R.dimen.split_shade_scrim_transition_distance)
+        setSplitShadeEnabled(true)
+
+        controller.onPanelExpansionChanged(EXPANSION_EVENT)
+
+        val expectedFraction = EXPANSION_EVENT.dragDownPxAmount / scrimShadeTransitionDistance
+        verify(scrimController).setRawPanelExpansionFraction(expectedFraction)
+    }
+
+    @Test
+    fun onPanelExpansionChanged_inSplitShade_largeDragDownAmount_fractionIsNotGreaterThan1() {
+        whenever(statusBarStateController.currentOrUpcomingState)
+            .thenReturn(StatusBarState.SHADE)
+        val scrimShadeTransitionDistance =
+            context.resources.getDimensionPixelSize(R.dimen.split_shade_scrim_transition_distance)
+        setSplitShadeEnabled(true)
+
+        controller.onPanelExpansionChanged(
+            EXPANSION_EVENT.copy(dragDownPxAmount = 100f * scrimShadeTransitionDistance)
+        )
+
+        verify(scrimController).setRawPanelExpansionFraction(1f)
+    }
+
+    @Test
+    fun onPanelExpansionChanged_inSplitShade_negativeDragDownAmount_fractionIsNotLessThan0() {
+        whenever(statusBarStateController.currentOrUpcomingState)
+            .thenReturn(StatusBarState.SHADE)
+        setSplitShadeEnabled(true)
+
+        controller.onPanelExpansionChanged(EXPANSION_EVENT.copy(dragDownPxAmount = -100f))
+
+        verify(scrimController).setRawPanelExpansionFraction(0f)
+    }
+
+    @Test
+    fun onPanelExpansionChanged_inSplitShade_onLockedShade_setsFractionEqualToEventFraction() {
+        whenever(statusBarStateController.currentOrUpcomingState)
+            .thenReturn(StatusBarState.SHADE_LOCKED)
+        setSplitShadeEnabled(true)
+
+        controller.onPanelExpansionChanged(EXPANSION_EVENT)
+
+        verify(scrimController).setRawPanelExpansionFraction(EXPANSION_EVENT.fraction)
+    }
+
+    @Test
+    fun onPanelExpansionChanged_inSplitShade_onKeyguard_setsFractionEqualToEventFraction() {
+        whenever(statusBarStateController.currentOrUpcomingState)
+            .thenReturn(StatusBarState.KEYGUARD)
+        setSplitShadeEnabled(true)
+
+        controller.onPanelExpansionChanged(EXPANSION_EVENT)
+
+        verify(scrimController).setRawPanelExpansionFraction(EXPANSION_EVENT.fraction)
+    }
+
+    private fun setSplitShadeEnabled(enabled: Boolean) {
+        overrideResource(R.bool.config_use_split_notification_shade, enabled)
+        configurationController.notifyConfigurationChanged()
+    }
+
+    companion object {
+        val EXPANSION_EVENT =
+            PanelExpansionChangeEvent(
+                fraction = 0.5f, expanded = true, tracking = true, dragDownPxAmount = 10f
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt
index 39d33e8..85a8c6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/ShadeTransitionControllerTest.kt
@@ -4,6 +4,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.qs.QS
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.phone.NotificationPanelViewController
@@ -28,6 +29,8 @@
     @Mock private lateinit var qs: QS
     @Mock private lateinit var noOpOverScroller: NoOpOverScroller
     @Mock private lateinit var splitShadeOverScroller: SplitShadeOverScroller
+    @Mock private lateinit var scrimShadeTransitionController: ScrimShadeTransitionController
+    @Mock private lateinit var dumpManager: DumpManager
 
     private lateinit var controller: ShadeTransitionController
 
@@ -42,9 +45,12 @@
             ShadeTransitionController(
                 configurationController,
                 panelExpansionStateManager,
+                dumpManager,
                 context,
                 splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
-                noOpOverScroller)
+                noOpOverScroller,
+                scrimShadeTransitionController
+            )
 
         // Resetting as they are notified upon initialization.
         reset(noOpOverScroller, splitShadeOverScroller)
@@ -109,7 +115,8 @@
             fraction = 0.5f,
             expanded = true,
             tracking = true,
-            dragDownPxAmount = DEFAULT_DRAG_DOWN_AMOUNT)
+            dragDownPxAmount = DEFAULT_DRAG_DOWN_AMOUNT
+        )
     }
 
     companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScrollerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScrollerTest.kt
index 219737d..5ca15bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScrollerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/shade/transition/SplitShadeOverScrollerTest.kt
@@ -1,6 +1,5 @@
 package com.android.systemui.statusbar.phone.shade.transition
 
-import org.mockito.Mockito.`when` as whenever
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
@@ -21,6 +20,7 @@
 import org.mockito.Mockito.atLeastOnce
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
@@ -43,7 +43,12 @@
         whenever(nsslController.height).thenReturn(1000)
         overScroller =
             SplitShadeOverScroller(
-                configurationController, dumpManager, context, scrimController, qs, nsslController)
+                configurationController,
+                dumpManager,
+                context,
+                scrimController,
+                { qs },
+                { nsslController })
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index fec2123..fda80a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -28,6 +28,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Intent;
+import android.os.BatteryManager;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.PowerSaveState;
@@ -196,4 +197,26 @@
         TestableLooper.get(this).processAllMessages();
         // Should not throw an exception
     }
+
+    @Test
+    public void batteryStateChanged_withChargingSourceDock_isChargingSourceDockTrue() {
+        Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
+        intent.putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_CHARGING);
+        intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_DOCK);
+
+        mBatteryController.onReceive(getContext(), intent);
+
+        Assert.assertTrue(mBatteryController.isChargingSourceDock());
+    }
+
+    @Test
+    public void batteryStateChanged_withChargingSourceNotDock_isChargingSourceDockFalse() {
+        Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
+        intent.putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_DISCHARGING);
+        intent.putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_WIRELESS);
+
+        mBatteryController.onReceive(getContext(), intent);
+
+        Assert.assertFalse(mBatteryController.isChargingSourceDock());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt
new file mode 100644
index 0000000..db0029a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy
+
+import android.content.pm.PackageManager
+import android.hardware.camera2.CameraCharacteristics
+import android.hardware.camera2.CameraManager
+import android.hardware.camera2.impl.CameraMetadataNative
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastSender
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.settings.FakeSettings
+import com.android.systemui.util.time.FakeSystemClock
+import java.util.concurrent.Executor
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.eq
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class FlashlightControllerImplTest : SysuiTestCase() {
+
+    @Mock
+    private lateinit var dumpManager: DumpManager
+
+    @Mock
+    private lateinit var cameraManager: CameraManager
+
+    @Mock
+    private lateinit var broadcastSender: BroadcastSender
+
+    @Mock
+    private lateinit var packageManager: PackageManager
+
+    private lateinit var fakeSettings: FakeSettings
+    private lateinit var fakeSystemClock: FakeSystemClock
+    private lateinit var backgroundExecutor: FakeExecutor
+    private lateinit var controller: FlashlightControllerImpl
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        fakeSystemClock = FakeSystemClock()
+        backgroundExecutor = FakeExecutor(fakeSystemClock)
+        fakeSettings = FakeSettings()
+
+        `when`(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH))
+                .thenReturn(true)
+
+        controller = FlashlightControllerImpl(
+                dumpManager,
+                cameraManager,
+                backgroundExecutor,
+                fakeSettings,
+                broadcastSender,
+                packageManager
+        )
+    }
+
+    @Test
+    fun testNoCameraManagerInteractionDirectlyOnConstructor() {
+        verifyZeroInteractions(cameraManager)
+    }
+
+    @Test
+    fun testCameraManagerInitAfterConstructionOnExecutor() {
+        injectCamera()
+        backgroundExecutor.runAllReady()
+
+        verify(cameraManager).registerTorchCallback(eq(backgroundExecutor), any())
+    }
+
+    @Test
+    fun testNoCallbackIfNoFlashCamera() {
+        injectCamera(flash = false)
+        backgroundExecutor.runAllReady()
+
+        verify(cameraManager, never()).registerTorchCallback(any<Executor>(), any())
+    }
+
+    @Test
+    fun testNoCallbackIfNoBackCamera() {
+        injectCamera(facing = CameraCharacteristics.LENS_FACING_FRONT)
+        backgroundExecutor.runAllReady()
+
+        verify(cameraManager, never()).registerTorchCallback(any<Executor>(), any())
+    }
+
+    @Test
+    fun testSetFlashlightInBackgroundExecutor() {
+        val id = injectCamera()
+        backgroundExecutor.runAllReady()
+
+        clearInvocations(cameraManager)
+        val enable = !controller.isEnabled
+        controller.setFlashlight(enable)
+        verifyNoMoreInteractions(cameraManager)
+
+        backgroundExecutor.runAllReady()
+        verify(cameraManager).setTorchMode(id, enable)
+    }
+
+    private fun injectCamera(
+        flash: Boolean = true,
+        facing: Int = CameraCharacteristics.LENS_FACING_BACK
+    ): String {
+        val cameraID = "ID"
+        val camera = CameraCharacteristics(CameraMetadataNative().apply {
+            set(CameraCharacteristics.FLASH_INFO_AVAILABLE, flash)
+            set(CameraCharacteristics.LENS_FACING, facing)
+        })
+        `when`(cameraManager.cameraIdList).thenReturn(arrayOf(cameraID))
+        `when`(cameraManager.getCameraCharacteristics(cameraID)).thenReturn(camera)
+        return cameraID
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
index 424a40058..b8e25ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
@@ -106,7 +106,7 @@
     public void testHunRemovedLogging() {
         mAlertEntry.mEntry = mEntry;
         mHeadsUpManager.onAlertEntryRemoved(mAlertEntry);
-        verify(mLogger, times(1)).logNotificationActuallyRemoved(eq(mEntry.getKey()));
+        verify(mLogger, times(1)).logNotificationActuallyRemoved(eq(mEntry));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
index 6bd8b98..e0bf9e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.policy
 
 import android.app.IActivityManager
+import android.app.NotificationManager
 import android.app.admin.DevicePolicyManager
 import android.content.BroadcastReceiver
 import android.content.Context
@@ -38,7 +39,9 @@
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.internal.util.LatencyTracker
 import com.android.internal.util.UserIcons
+import com.android.systemui.GuestResetOrExitSessionReceiver
 import com.android.systemui.GuestResumeSessionReceiver
+import com.android.systemui.GuestSessionNotification
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
@@ -102,6 +105,11 @@
     @Mock private lateinit var threadedRenderer: ThreadedRenderer
     @Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
     @Mock private lateinit var globalSettings: GlobalSettings
+    @Mock private lateinit var guestSessionNotification: GuestSessionNotification
+    @Mock private lateinit var guestResetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
+    private lateinit var resetSessionDialogFactory:
+                            GuestResumeSessionReceiver.ResetSessionDialog.Factory
+    private lateinit var guestResumeSessionReceiver: GuestResumeSessionReceiver
     private lateinit var testableLooper: TestableLooper
     private lateinit var bgExecutor: FakeExecutor
     private lateinit var longRunningExecutor: FakeExecutor
@@ -133,9 +141,28 @@
                 com.android.internal.R.bool.config_guestUserAutoCreated, false)
 
         mContext.addMockSystemService(Context.FACE_SERVICE, mock(FaceManager::class.java))
+        mContext.addMockSystemService(Context.NOTIFICATION_SERVICE,
+                mock(NotificationManager::class.java))
         mContext.addMockSystemService(Context.FINGERPRINT_SERVICE,
                 mock(FingerprintManager::class.java))
 
+        resetSessionDialogFactory = object : GuestResumeSessionReceiver.ResetSessionDialog.Factory {
+                override fun create(userId: Int): GuestResumeSessionReceiver.ResetSessionDialog {
+                    return GuestResumeSessionReceiver.ResetSessionDialog(
+                                mContext,
+                                mock(UserSwitcherController::class.java),
+                                uiEventLogger,
+                                userId
+                            )
+                }
+            }
+
+        guestResumeSessionReceiver = GuestResumeSessionReceiver(userTracker,
+                                        secureSettings,
+                                        broadcastDispatcher,
+                                        guestSessionNotification,
+                                        resetSessionDialogFactory)
+
         `when`(userManager.canAddMoreUsers(eq(UserManager.USER_TYPE_FULL_SECONDARY)))
                 .thenReturn(true)
         `when`(notificationShadeWindowView.context).thenReturn(context)
@@ -198,7 +225,9 @@
                 interactionJankMonitor,
                 latencyTracker,
                 dumpManager,
-                dialogLaunchAnimator)
+                dialogLaunchAnimator,
+                guestResumeSessionReceiver,
+                guestResetOrExitSessionReceiver)
         userSwitcherController.init(notificationShadeWindowView)
     }
 
@@ -288,7 +317,10 @@
                 .getButton(DialogInterface.BUTTON_POSITIVE).performClick()
         testableLooper.processAllMessages()
         assertEquals(1, uiEventLogger.numLogs())
-        assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE.id, uiEventLogger.eventId(0))
+        assertTrue(
+            QSUserSwitcherEvent.QS_USER_GUEST_REMOVE.id == uiEventLogger.eventId(0) ||
+            QSUserSwitcherEvent.QS_USER_SWITCH.id == uiEventLogger.eventId(0)
+        )
     }
 
     @Test
@@ -350,7 +382,7 @@
         userSwitcherController.onUserListItemClicked(currentGuestUserRecord, null)
         assertNotNull(userSwitcherController.mExitGuestDialog)
         userSwitcherController.mExitGuestDialog
-                .getButton(DialogInterface.BUTTON_NEGATIVE).performClick()
+                .getButton(DialogInterface.BUTTON_NEUTRAL).performClick()
         testableLooper.processAllMessages()
         assertEquals(0, uiEventLogger.numLogs())
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt
index 8076b4e..39e4e64 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt
@@ -25,28 +25,20 @@
 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN
 import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
 import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING
-import com.android.systemui.unfold.updates.FoldStateProvider
 import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
+import com.android.systemui.unfold.util.TestFoldStateProvider
 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
 
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
 class FoldStateLoggingProviderTest : SysuiTestCase() {
 
-    @Captor
-    private lateinit var foldUpdatesListener: ArgumentCaptor<FoldStateProvider.FoldUpdatesListener>
-
-    @Mock private lateinit var foldStateProvider: FoldStateProvider
-
+    private val testFoldStateProvider = TestFoldStateProvider()
     private val fakeClock = FakeSystemClock()
 
     private lateinit var foldStateLoggingProvider: FoldStateLoggingProvider
@@ -65,12 +57,10 @@
         MockitoAnnotations.initMocks(this)
 
         foldStateLoggingProvider =
-            FoldStateLoggingProviderImpl(foldStateProvider, fakeClock).apply {
+            FoldStateLoggingProviderImpl(testFoldStateProvider, fakeClock).apply {
                 addCallback(foldStateLoggingListener)
                 init()
             }
-
-        verify(foldStateProvider).addCallback(foldUpdatesListener.capture())
     }
 
     @Test
@@ -183,10 +173,10 @@
     fun uninit_removesCallback() {
         foldStateLoggingProvider.uninit()
 
-        verify(foldStateProvider).removeCallback(foldUpdatesListener.value)
+        assertThat(testFoldStateProvider.hasListeners).isFalse()
     }
 
     private fun sendFoldUpdate(@FoldUpdate foldUpdate: Int) {
-        foldUpdatesListener.value.onFoldUpdate(foldUpdate)
+        testFoldStateProvider.sendFoldUpdate(foldUpdate)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
new file mode 100644
index 0000000..ab450e2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.config
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+
+/**
+ * A test that checks that we load correct resources in
+ * ResourceUnfoldTransitionConfig as we use strings there instead of R constants.
+ * Internal Android resource constants are not available in public APIs,
+ * so we can't use them there directly.
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ResourceUnfoldTransitionConfigTest : SysuiTestCase() {
+
+    private val config = ResourceUnfoldTransitionConfig()
+
+    @Test
+    fun testIsEnabled() {
+        assertThat(config.isEnabled).isEqualTo(mContext.resources
+            .getBoolean(com.android.internal.R.bool.config_unfoldTransitionEnabled))
+    }
+
+    @Test
+    fun testHingeAngleEnabled() {
+        assertThat(config.isHingeAngleEnabled).isEqualTo(mContext.resources
+            .getBoolean(com.android.internal.R.bool.config_unfoldTransitionHingeAngle))
+    }
+
+    @Test
+    fun testHalfFoldedTimeout() {
+        assertThat(config.halfFoldedTimeoutMillis).isEqualTo(mContext.resources
+            .getInteger(com.android.internal.R.integer.config_unfoldTransitionHalfFoldedTimeout))
+    }
+}
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 1f1f88b..87fca1f 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
@@ -16,82 +16,69 @@
 
 package com.android.systemui.unfold.updates
 
-import android.app.ActivityManager
-import android.app.ActivityManager.RunningTaskInfo
-import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
-import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
-import android.app.WindowConfiguration.ActivityType
-import android.hardware.devicestate.DeviceStateManager
-import android.hardware.devicestate.DeviceStateManager.FoldStateListener
 import android.os.Handler
 import android.testing.AndroidTestingRunner
 import androidx.core.util.Consumer
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
+import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.system.ActivityManagerActivityTypeProvider
+import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
 import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
-import com.android.systemui.unfold.util.FoldableDeviceStates
-import com.android.systemui.unfold.util.FoldableTestUtils
 import com.android.systemui.util.mockito.any
 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.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import java.util.concurrent.Executor
+import org.mockito.Mockito.`when` as whenever
 
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
 class DeviceFoldStateProviderTest : SysuiTestCase() {
 
-    @Mock private lateinit var hingeAngleProvider: HingeAngleProvider
+    @Mock
+    private lateinit var activityTypeProvider: ActivityManagerActivityTypeProvider
 
-    @Mock private lateinit var screenStatusProvider: ScreenStatusProvider
+    @Mock
+    private lateinit var handler: Handler
 
-    @Mock private lateinit var deviceStateManager: DeviceStateManager
-
-    @Mock private lateinit var activityManager: ActivityManager
-
-    @Mock private lateinit var handler: Handler
-
-    @Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
-
-    @Captor private lateinit var screenOnListenerCaptor: ArgumentCaptor<ScreenListener>
-
-    @Captor private lateinit var hingeAngleCaptor: ArgumentCaptor<Consumer<Float>>
+    private val foldProvider = TestFoldProvider()
+    private val screenOnStatusProvider = TestScreenOnStatusProvider()
+    private val testHingeAngleProvider = TestHingeAngleProvider()
 
     private lateinit var foldStateProvider: DeviceFoldStateProvider
 
     private val foldUpdates: MutableList<Int> = arrayListOf()
     private val hingeAngleUpdates: MutableList<Float> = arrayListOf()
 
-    private lateinit var deviceStates: FoldableDeviceStates
-
     private var scheduledRunnable: Runnable? = null
     private var scheduledRunnableDelay: Long? = null
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        overrideResource(
-            com.android.internal.R.integer.config_unfoldTransitionHalfFoldedTimeout,
-            HALF_OPENED_TIMEOUT_MILLIS.toInt())
-        deviceStates = FoldableTestUtils.findDeviceStates(context)
+
+        val config = object : UnfoldTransitionConfig by ResourceUnfoldTransitionConfig() {
+            override val halfFoldedTimeoutMillis: Int
+                get() = HALF_OPENED_TIMEOUT_MILLIS.toInt()
+        }
 
         foldStateProvider =
             DeviceFoldStateProvider(
-                context,
-                hingeAngleProvider,
-                screenStatusProvider,
-                deviceStateManager,
-                activityManager,
+                config,
+                testHingeAngleProvider,
+                screenOnStatusProvider,
+                foldProvider,
+                activityTypeProvider,
                 context.mainExecutor,
-                handler)
+                handler
+            )
 
         foldStateProvider.addCallback(
             object : FoldStateProvider.FoldUpdatesListener {
@@ -105,10 +92,6 @@
             })
         foldStateProvider.start()
 
-        verify(deviceStateManager).registerCallback(any(), foldStateListenerCaptor.capture())
-        verify(screenStatusProvider).addCallback(screenOnListenerCaptor.capture())
-        verify(hingeAngleProvider).addCallback(hingeAngleCaptor.capture())
-
         whenever(handler.postDelayed(any<Runnable>(), any())).then { invocationOnMock ->
             scheduledRunnable = invocationOnMock.getArgument<Runnable>(0)
             scheduledRunnableDelay = invocationOnMock.getArgument<Long>(1)
@@ -125,7 +108,7 @@
         }
 
         // By default, we're on launcher.
-        setupForegroundActivityType(ACTIVITY_TYPE_HOME)
+        setupForegroundActivityType(isHomeActivity = true)
     }
 
     @Test
@@ -146,14 +129,14 @@
     fun testOnFolded_stopsHingeAngleProvider() {
         setFoldState(folded = true)
 
-        verify(hingeAngleProvider).stop()
+        assertThat(testHingeAngleProvider.isStarted).isFalse()
     }
 
     @Test
     fun testOnUnfolded_startsHingeAngleProvider() {
         setFoldState(folded = false)
 
-        verify(hingeAngleProvider).start()
+        assertThat(testHingeAngleProvider.isStarted).isTrue()
     }
 
     @Test
@@ -310,7 +293,7 @@
 
     @Test
     fun startClosingEvent_whileNotOnLauncher_doesNotTriggerBeforeThreshold() {
-        setupForegroundActivityType(ACTIVITY_TYPE_STANDARD)
+        setupForegroundActivityType(isHomeActivity = false)
         sendHingeAngleEvent(180)
 
         sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
@@ -319,8 +302,28 @@
     }
 
     @Test
+    fun startClosingEvent_whileActivityTypeNotAvailable_triggerBeforeThreshold() {
+        setupForegroundActivityType(isHomeActivity = null)
+        sendHingeAngleEvent(180)
+
+        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
+
+        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+    }
+
+    @Test
+    fun startClosingEvent_whileOnLauncher_doesTriggerBeforeThreshold() {
+        setupForegroundActivityType(isHomeActivity = true)
+        sendHingeAngleEvent(180)
+
+        sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
+
+        assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+    }
+
+    @Test
     fun startClosingEvent_whileNotOnLauncher_triggersAfterThreshold() {
-        setupForegroundActivityType(ACTIVITY_TYPE_STANDARD)
+        setupForegroundActivityType(isHomeActivity = false)
         sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
 
         sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES - 1)
@@ -328,9 +331,8 @@
         assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
     }
 
-    private fun setupForegroundActivityType(@ActivityType type: Int) {
-        val taskInfo = RunningTaskInfo().apply { topActivityType = type }
-        whenever(activityManager.getRunningTasks(1)).thenReturn(listOf(taskInfo))
+    private fun setupForegroundActivityType(isHomeActivity: Boolean?) {
+        whenever(activityTypeProvider.isHomeActivity).thenReturn(isHomeActivity)
     }
 
     private fun simulateTimeout(waitTime: Long = HALF_OPENED_TIMEOUT_MILLIS) {
@@ -348,16 +350,72 @@
     }
 
     private fun setFoldState(folded: Boolean) {
-        val state = if (folded) deviceStates.folded else deviceStates.unfolded
-        foldStateListenerCaptor.value.onStateChanged(state)
+        foldProvider.notifyFolded(folded)
     }
 
     private fun fireScreenOnEvent() {
-        screenOnListenerCaptor.value.onScreenTurnedOn()
+        screenOnStatusProvider.notifyScreenTurnedOn()
     }
 
     private fun sendHingeAngleEvent(angle: Int) {
-        hingeAngleCaptor.value.accept(angle.toFloat())
+        testHingeAngleProvider.notifyAngle(angle.toFloat())
+    }
+
+    private class TestFoldProvider : FoldProvider {
+        private val callbacks = arrayListOf<FoldCallback>()
+
+        override fun registerCallback(callback: FoldCallback, executor: Executor) {
+            callbacks += callback
+        }
+
+        override fun unregisterCallback(callback: FoldCallback) {
+            callbacks -= callback
+        }
+
+        fun notifyFolded(isFolded: Boolean) {
+            callbacks.forEach { it.onFoldUpdated(isFolded) }
+        }
+    }
+
+    private class TestScreenOnStatusProvider : ScreenStatusProvider {
+        private val callbacks = arrayListOf<ScreenListener>()
+
+        override fun addCallback(listener: ScreenListener) {
+            callbacks += listener
+        }
+
+        override fun removeCallback(listener: ScreenListener) {
+            callbacks -= listener
+        }
+
+        fun notifyScreenTurnedOn() {
+            callbacks.forEach { it.onScreenTurnedOn() }
+        }
+    }
+
+    private class TestHingeAngleProvider : HingeAngleProvider {
+        private val callbacks = arrayListOf<Consumer<Float>>()
+        var isStarted: Boolean = false
+
+        override fun start() {
+            isStarted = true;
+        }
+
+        override fun stop() {
+            isStarted = false;
+        }
+
+        override fun addCallback(listener: Consumer<Float>) {
+            callbacks += listener
+        }
+
+        override fun removeCallback(listener: Consumer<Float>) {
+            callbacks -= listener
+        }
+
+        fun notifyAngle(angle: Float) {
+            callbacks.forEach { it.accept(angle) }
+        }
     }
 
     companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
index a3f17aa..b2cedbf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
@@ -20,18 +20,18 @@
 import android.view.IWindowManager
 import android.view.Surface
 import androidx.test.filters.SmallTest
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.unfold.TestUnfoldTransitionProvider
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
 import com.android.systemui.util.mockito.any
-import com.android.systemui.SysuiTestCase
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.Mock
-import org.mockito.Mockito.verify
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 @RunWith(AndroidTestingRunner::class)
@@ -41,16 +41,13 @@
     @Mock
     lateinit var windowManager: IWindowManager
 
-    @Mock
-    lateinit var sourceProvider: UnfoldTransitionProgressProvider
+    private val sourceProvider = TestUnfoldTransitionProvider()
 
     @Mock
     lateinit var transitionListener: TransitionProgressListener
 
     lateinit var progressProvider: NaturalRotationUnfoldProgressProvider
 
-    private val sourceProviderListenerCaptor =
-        ArgumentCaptor.forClass(TransitionProgressListener::class.java)
     private val rotationWatcherCaptor =
         ArgumentCaptor.forClass(IRotationWatcher.Stub::class.java)
 
@@ -66,7 +63,6 @@
 
         progressProvider.init()
 
-        verify(sourceProvider).addCallback(sourceProviderListenerCaptor.capture())
         verify(windowManager).watchRotation(rotationWatcherCaptor.capture(), any())
 
         progressProvider.addCallback(transitionListener)
@@ -76,7 +72,7 @@
     fun testNaturalRotation0_sendTransitionStartedEvent_eventReceived() {
         onRotationChanged(Surface.ROTATION_0)
 
-        source.onTransitionStarted()
+        sourceProvider.onTransitionStarted()
 
         verify(transitionListener).onTransitionStarted()
     }
@@ -85,7 +81,7 @@
     fun testNaturalRotation0_sendTransitionProgressEvent_eventReceived() {
         onRotationChanged(Surface.ROTATION_0)
 
-        source.onTransitionProgress(0.5f)
+        sourceProvider.onTransitionProgress(0.5f)
 
         verify(transitionListener).onTransitionProgress(0.5f)
     }
@@ -94,7 +90,7 @@
     fun testNotNaturalRotation90_sendTransitionStartedEvent_eventNotReceived() {
         onRotationChanged(Surface.ROTATION_90)
 
-        source.onTransitionStarted()
+        sourceProvider.onTransitionStarted()
 
         verify(transitionListener, never()).onTransitionStarted()
     }
@@ -103,7 +99,7 @@
     fun testNaturalRotation90_sendTransitionProgressEvent_eventNotReceived() {
         onRotationChanged(Surface.ROTATION_90)
 
-        source.onTransitionProgress(0.5f)
+        sourceProvider.onTransitionProgress(0.5f)
 
         verify(transitionListener, never()).onTransitionProgress(0.5f)
     }
@@ -111,7 +107,7 @@
     @Test
     fun testRotationBecameUnnaturalDuringTransition_sendsTransitionFinishedEvent() {
         onRotationChanged(Surface.ROTATION_0)
-        source.onTransitionStarted()
+        sourceProvider.onTransitionStarted()
         clearInvocations(transitionListener)
 
         onRotationChanged(Surface.ROTATION_90)
@@ -122,7 +118,7 @@
     @Test
     fun testRotationBecameNaturalDuringTransition_sendsTransitionStartedEvent() {
         onRotationChanged(Surface.ROTATION_90)
-        source.onTransitionStarted()
+        sourceProvider.onTransitionStarted()
         clearInvocations(transitionListener)
 
         onRotationChanged(Surface.ROTATION_0)
@@ -133,7 +129,4 @@
     private fun onRotationChanged(rotation: Int) {
         rotationWatcherCaptor.value.onRotationChanged(rotation)
     }
-
-    private val source: TransitionProgressListener
-        get() = sourceProviderListenerCaptor.value
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
index db7a8516..fc2a78a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
@@ -21,6 +21,7 @@
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.unfold.TestUnfoldTransitionProvider
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
 import com.android.systemui.util.mockito.any
@@ -41,15 +42,11 @@
     lateinit var contentResolver: ContentResolver
 
     @Mock
-    lateinit var sourceProvider: UnfoldTransitionProgressProvider
-
-    @Mock
     lateinit var sinkProvider: TransitionProgressListener
 
-    lateinit var progressProvider: ScaleAwareTransitionProgressProvider
+    private val sourceProvider = TestUnfoldTransitionProvider()
 
-    private val sourceProviderListenerCaptor =
-            ArgumentCaptor.forClass(TransitionProgressListener::class.java)
+    lateinit var progressProvider: ScaleAwareTransitionProgressProvider
 
     private val animatorDurationScaleListenerCaptor =
             ArgumentCaptor.forClass(ContentObserver::class.java)
@@ -63,7 +60,6 @@
                 contentResolver
         )
 
-        verify(sourceProvider).addCallback(sourceProviderListenerCaptor.capture())
         verify(contentResolver).registerContentObserver(any(), any(),
                 animatorDurationScaleListenerCaptor.capture())
 
@@ -74,7 +70,7 @@
     fun onTransitionStarted_animationsEnabled_eventReceived() {
         setAnimationsEnabled(true)
 
-        source.onTransitionStarted()
+        sourceProvider.onTransitionStarted()
 
         verify(sinkProvider).onTransitionStarted()
     }
@@ -83,7 +79,7 @@
     fun onTransitionStarted_animationsNotEnabled_eventNotReceived() {
         setAnimationsEnabled(false)
 
-        source.onTransitionStarted()
+        sourceProvider.onTransitionStarted()
 
         verifyNoMoreInteractions(sinkProvider)
     }
@@ -92,7 +88,7 @@
     fun onTransitionEnd_animationsEnabled_eventReceived() {
         setAnimationsEnabled(true)
 
-        source.onTransitionFinished()
+        sourceProvider.onTransitionFinished()
 
         verify(sinkProvider).onTransitionFinished()
     }
@@ -101,7 +97,7 @@
     fun onTransitionEnd_animationsNotEnabled_eventNotReceived() {
         setAnimationsEnabled(false)
 
-        source.onTransitionFinished()
+        sourceProvider.onTransitionFinished()
 
         verifyNoMoreInteractions(sinkProvider)
     }
@@ -110,7 +106,7 @@
     fun onTransitionProgress_animationsEnabled_eventReceived() {
         setAnimationsEnabled(true)
 
-        source.onTransitionProgress(42f)
+        sourceProvider.onTransitionProgress(42f)
 
         verify(sinkProvider).onTransitionProgress(42f)
     }
@@ -119,7 +115,7 @@
     fun onTransitionProgress_animationsNotEnabled_eventNotReceived() {
         setAnimationsEnabled(false)
 
-        source.onTransitionProgress(42f)
+        sourceProvider.onTransitionProgress(42f)
 
         verifyNoMoreInteractions(sinkProvider)
     }
@@ -133,7 +129,4 @@
         ValueAnimator.setDurationScale(durationScale)
         animatorDurationScaleListenerCaptor.value.dispatchChange(/* selfChange= */false)
     }
-
-    private val source: TransitionProgressListener
-        get() = sourceProviderListenerCaptor.value
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
index 8f851ec..a064e8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
@@ -24,6 +24,8 @@
 class TestFoldStateProvider : FoldStateProvider {
 
     private val listeners: MutableList<FoldUpdatesListener> = arrayListOf()
+    val hasListeners: Boolean
+        get() = listeners.isNotEmpty()
 
     override fun start() {
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/NotificationChannelsTest.java
similarity index 81%
rename from packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/util/NotificationChannelsTest.java
index c7bcdef..900d792 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/NotificationChannelsTest.java
@@ -28,7 +28,6 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.util.NotificationChannels;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -41,7 +40,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class ChannelsTest extends SysuiTestCase {
+public class NotificationChannelsTest extends SysuiTestCase {
     private final NotificationManager mMockNotificationManager = mock(NotificationManager.class);
 
     @Before
@@ -55,9 +54,10 @@
                 NotificationChannels.ALERTS,
                 NotificationChannels.SCREENSHOTS_HEADSUP,
                 NotificationChannels.STORAGE,
-                NotificationChannels.GENERAL,
+                NotificationChannels.INSTANT,
                 NotificationChannels.BATTERY,
-                NotificationChannels.HINTS
+                NotificationChannels.HINTS,
+                NotificationChannels.SETUP
         ));
         NotificationChannels.createAll(mContext);
         ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
@@ -67,4 +67,11 @@
         list.forEach((chan) -> assertTrue(ALL_CHANNELS.contains(chan.getId())));
     }
 
+    @Test
+    public void testChannelCleanup() {
+        new NotificationChannels(mContext).start();
+        ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+        verify(mMockNotificationManager).deleteNotificationChannel(captor.capture());
+        assertEquals(NotificationChannels.GENERAL, captor.getValue());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java
index 5118637..1e35b0f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionMonitorTest.java
@@ -65,7 +65,12 @@
         mCondition3 = spy(new FakeCondition());
         mConditions = new HashSet<>(Arrays.asList(mCondition1, mCondition2, mCondition3));
 
-        mConditionMonitor = new Monitor(mExecutor, mConditions, null /*callbacks*/);
+        mConditionMonitor = new Monitor(mExecutor);
+    }
+
+    public Monitor.Subscription.Builder getDefaultBuilder(Monitor.Callback callback) {
+        return new Monitor.Subscription.Builder(callback)
+                .addConditions(mConditions);
     }
 
     @Test
@@ -74,10 +79,20 @@
         final Condition regularCondition = Mockito.mock(Condition.class);
         final Monitor.Callback callback = Mockito.mock(Monitor.Callback.class);
 
-        final Monitor monitor = new Monitor(
-                mExecutor,
-                new HashSet<>(Arrays.asList(overridingCondition, regularCondition)),
-                new HashSet<>(Arrays.asList(callback)));
+        final Monitor.Callback referenceCallback = Mockito.mock(Monitor.Callback.class);
+
+        final Monitor monitor = new Monitor(mExecutor);
+
+        monitor.addSubscription(getDefaultBuilder(callback)
+                .addCondition(overridingCondition)
+                .addCondition(regularCondition)
+                .build());
+
+        monitor.addSubscription(getDefaultBuilder(referenceCallback)
+                .addCondition(regularCondition)
+                .build());
+
+        mExecutor.runAllReady();
 
         when(overridingCondition.isOverridingCondition()).thenReturn(true);
         when(overridingCondition.isConditionMet()).thenReturn(true);
@@ -92,7 +107,9 @@
         mExecutor.runAllReady();
 
         verify(callback).onConditionsChanged(eq(true));
+        verify(referenceCallback).onConditionsChanged(eq(false));
         Mockito.clearInvocations(callback);
+        Mockito.clearInvocations(referenceCallback);
 
         when(regularCondition.isConditionMet()).thenReturn(true);
         when(overridingCondition.isConditionMet()).thenReturn(false);
@@ -101,12 +118,7 @@
         mExecutor.runAllReady();
 
         verify(callback).onConditionsChanged(eq(false));
-
-        clearInvocations(callback);
-        monitor.removeCondition(overridingCondition);
-        mExecutor.runAllReady();
-
-        verify(callback).onConditionsChanged(eq(true));
+        verify(referenceCallback, never()).onConditionsChanged(anyBoolean());
     }
 
     /**
@@ -120,11 +132,14 @@
         final Condition regularCondition = Mockito.mock(Condition.class);
         final Monitor.Callback callback = Mockito.mock(Monitor.Callback.class);
 
-        final Monitor monitor = new Monitor(
-                mExecutor,
-                new HashSet<>(Arrays.asList(overridingCondition, overridingCondition2,
-                        regularCondition)),
-                new HashSet<>(Arrays.asList(callback)));
+        final Monitor monitor = new Monitor(mExecutor);
+
+        monitor.addSubscription(getDefaultBuilder(callback)
+                .addCondition(overridingCondition)
+                .addCondition(overridingCondition2)
+                .build());
+
+        mExecutor.runAllReady();
 
         when(overridingCondition.isOverridingCondition()).thenReturn(true);
         when(overridingCondition.isConditionMet()).thenReturn(true);
@@ -148,13 +163,13 @@
     public void addCallback_addFirstCallback_addCallbackToAllConditions() {
         final Monitor.Callback callback1 =
                 mock(Monitor.Callback.class);
-        mConditionMonitor.addCallback(callback1);
+        mConditionMonitor.addSubscription(getDefaultBuilder(callback1).build());
         mExecutor.runAllReady();
         mConditions.forEach(condition -> verify(condition).addCallback(any()));
 
         final Monitor.Callback callback2 =
                 mock(Monitor.Callback.class);
-        mConditionMonitor.addCallback(callback2);
+        mConditionMonitor.addSubscription(getDefaultBuilder(callback2).build());
         mExecutor.runAllReady();
         mConditions.forEach(condition -> verify(condition, times(1)).addCallback(any()));
     }
@@ -163,7 +178,7 @@
     public void addCallback_addFirstCallback_reportWithDefaultValue() {
         final Monitor.Callback callback =
                 mock(Monitor.Callback.class);
-        mConditionMonitor.addCallback(callback);
+        mConditionMonitor.addSubscription(getDefaultBuilder(callback).build());
         mExecutor.runAllReady();
         verify(callback).onConditionsChanged(false);
     }
@@ -174,67 +189,65 @@
                 mock(Monitor.Callback.class);
         final Condition condition = mock(Condition.class);
         when(condition.isConditionMet()).thenReturn(true);
-        final Monitor monitor = new Monitor(mExecutor, new HashSet<>(Arrays.asList(condition)),
-                new HashSet<>(Arrays.asList(callback1)));
+        final Monitor monitor = new Monitor(mExecutor);
+        monitor.addSubscription(new Monitor.Subscription.Builder(callback1)
+                .addCondition(condition)
+                .build());
 
         final Monitor.Callback callback2 =
                 mock(Monitor.Callback.class);
-        monitor.addCallback(callback2);
+        monitor.addSubscription(new Monitor.Subscription.Builder(callback2)
+                .addCondition(condition)
+                .build());
         mExecutor.runAllReady();
         verify(callback2).onConditionsChanged(eq(true));
     }
 
     @Test
     public void addCallback_noConditions_reportAllConditionsMet() {
-        final Monitor monitor = new Monitor(mExecutor, new HashSet<>(), null /*callbacks*/);
+        final Monitor monitor = new Monitor(mExecutor);
         final Monitor.Callback callback = mock(Monitor.Callback.class);
 
-        monitor.addCallback(callback);
+        monitor.addSubscription(new Monitor.Subscription.Builder(callback).build());
         mExecutor.runAllReady();
         verify(callback).onConditionsChanged(true);
     }
 
     @Test
-    public void addCallback_withMultipleInstancesOfTheSameCallback_registerOnlyOne() {
-        final Monitor monitor = new Monitor(mExecutor, new HashSet<>(), null /*callbacks*/);
-        final Monitor.Callback callback = mock(Monitor.Callback.class);
-
-        // Adds the same instance multiple times.
-        monitor.addCallback(callback);
-        monitor.addCallback(callback);
-        monitor.addCallback(callback);
+    public void removeCallback_noFailureOnDoubleRemove() {
+        final Condition condition = mock(Condition.class);
+        final Monitor monitor = new Monitor(mExecutor);
+        final Monitor.Callback callback =
+                mock(Monitor.Callback.class);
+        final Monitor.Subscription.Token token = monitor.addSubscription(
+                new Monitor.Subscription.Builder(callback).addCondition(condition).build()
+        );
+        monitor.removeSubscription(token);
         mExecutor.runAllReady();
-
-        // Callback should only be triggered once.
-        verify(callback, times(1)).onConditionsChanged(true);
+        // Ensure second removal doesn't cause an exception.
+        monitor.removeSubscription(token);
+        mExecutor.runAllReady();
     }
 
     @Test
     public void removeCallback_shouldNoLongerReceiveUpdate() {
         final Condition condition = mock(Condition.class);
-        final Monitor monitor = new Monitor(mExecutor, new HashSet<>(Arrays.asList(condition)),
-                null);
+        final Monitor monitor = new Monitor(mExecutor);
         final Monitor.Callback callback =
                 mock(Monitor.Callback.class);
-        monitor.addCallback(callback);
-        monitor.removeCallback(callback);
+        final Monitor.Subscription.Token token = monitor.addSubscription(
+                new Monitor.Subscription.Builder(callback).addCondition(condition).build()
+        );
+        monitor.removeSubscription(token);
         mExecutor.runAllReady();
         clearInvocations(callback);
 
         final ArgumentCaptor<Condition.Callback> conditionCallbackCaptor =
                 ArgumentCaptor.forClass(Condition.Callback.class);
         verify(condition).addCallback(conditionCallbackCaptor.capture());
+
         final Condition.Callback conditionCallback = conditionCallbackCaptor.getValue();
-
-        when(condition.isConditionMet()).thenReturn(true);
-        conditionCallback.onConditionChanged(condition);
-        mExecutor.runAllReady();
-        verify(callback, never()).onConditionsChanged(true);
-
-        when(condition.isConditionMet()).thenReturn(false);
-        conditionCallback.onConditionChanged(condition);
-        mExecutor.runAllReady();
-        verify(callback, never()).onConditionsChanged(false);
+        verify(condition).removeCallback(conditionCallback);
     }
 
     @Test
@@ -243,14 +256,16 @@
                 mock(Monitor.Callback.class);
         final Monitor.Callback callback2 =
                 mock(Monitor.Callback.class);
-        mConditionMonitor.addCallback(callback1);
-        mConditionMonitor.addCallback(callback2);
+        final Monitor.Subscription.Token subscription1 =
+                mConditionMonitor.addSubscription(getDefaultBuilder(callback1).build());
+        final Monitor.Subscription.Token subscription2 =
+                mConditionMonitor.addSubscription(getDefaultBuilder(callback2).build());
 
-        mConditionMonitor.removeCallback(callback1);
+        mConditionMonitor.removeSubscription(subscription1);
         mExecutor.runAllReady();
         mConditions.forEach(condition -> verify(condition, never()).removeCallback(any()));
 
-        mConditionMonitor.removeCallback(callback2);
+        mConditionMonitor.removeSubscription(subscription2);
         mExecutor.runAllReady();
         mConditions.forEach(condition -> verify(condition).removeCallback(any()));
     }
@@ -259,7 +274,7 @@
     public void updateCallbacks_allConditionsMet_reportTrue() {
         final Monitor.Callback callback =
                 mock(Monitor.Callback.class);
-        mConditionMonitor.addCallback(callback);
+        mConditionMonitor.addSubscription(getDefaultBuilder(callback).build());
         clearInvocations(callback);
 
         mCondition1.fakeUpdateCondition(true);
@@ -274,7 +289,7 @@
     public void updateCallbacks_oneConditionStoppedMeeting_reportFalse() {
         final Monitor.Callback callback =
                 mock(Monitor.Callback.class);
-        mConditionMonitor.addCallback(callback);
+        mConditionMonitor.addSubscription(getDefaultBuilder(callback).build());
 
         mCondition1.fakeUpdateCondition(true);
         mCondition2.fakeUpdateCondition(true);
@@ -290,7 +305,7 @@
     public void updateCallbacks_shouldOnlyUpdateWhenValueChanges() {
         final Monitor.Callback callback =
                 mock(Monitor.Callback.class);
-        mConditionMonitor.addCallback(callback);
+        mConditionMonitor.addSubscription(getDefaultBuilder(callback).build());
         mExecutor.runAllReady();
         verify(callback).onConditionsChanged(false);
         clearInvocations(callback);
diff --git a/packages/SystemUI/unfold/Android.bp b/packages/SystemUI/unfold/Android.bp
new file mode 100644
index 0000000..108295b
--- /dev/null
+++ b/packages/SystemUI/unfold/Android.bp
@@ -0,0 +1,39 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"],
+}
+
+android_library {
+    name: "SystemUIUnfoldLib",
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+        "src/**/*.aidl",
+    ],
+    static_libs: [
+        "androidx.dynamicanimation_dynamicanimation",
+        "dagger2",
+        "jsr330",
+    ],
+    java_version: "1.8",
+    min_sdk_version: "current",
+    plugins: ["dagger2-compiler"],
+}
diff --git a/libs/WindowManager/Shell/res/color/unfold_transition_background.xml b/packages/SystemUI/unfold/AndroidManifest.xml
similarity index 69%
rename from libs/WindowManager/Shell/res/color/unfold_transition_background.xml
rename to packages/SystemUI/unfold/AndroidManifest.xml
index 63289a3..ee8afe1 100644
--- a/libs/WindowManager/Shell/res/color/unfold_transition_background.xml
+++ b/packages/SystemUI/unfold/AndroidManifest.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
+<!--
+     Copyright (C) 2017 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,7 +14,9 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- Matches taskbar color -->
-    <item android:color="@android:color/system_neutral2_500" android:lStar="35" />
-</selector>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.systemui.unfold">
+
+
+</manifest>
diff --git a/packages/SystemUI/unfold/lint-baseline.xml b/packages/SystemUI/unfold/lint-baseline.xml
new file mode 100644
index 0000000..449ed2e
--- /dev/null
+++ b/packages/SystemUI/unfold/lint-baseline.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 7.1.0-dev" type="baseline" client="" name="" variant="all" version="7.1.0-dev">
+</issues>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
similarity index 79%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
index 9e5aeb8..a5ec0a4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
@@ -16,16 +16,16 @@
 
 package com.android.systemui.unfold
 
-import android.app.ActivityManager
 import android.content.ContentResolver
 import android.content.Context
 import android.hardware.SensorManager
-import android.hardware.devicestate.DeviceStateManager
 import android.os.Handler
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.dagger.UnfoldBackground
+import com.android.systemui.unfold.dagger.UnfoldMain
+import com.android.systemui.unfold.updates.FoldProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
+import com.android.systemui.unfold.util.CurrentActivityTypeProvider
 import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix
 import dagger.BindsInstance
 import dagger.Component
@@ -51,12 +51,12 @@
             @BindsInstance context: Context,
             @BindsInstance config: UnfoldTransitionConfig,
             @BindsInstance screenStatusProvider: ScreenStatusProvider,
-            @BindsInstance deviceStateManager: DeviceStateManager,
-            @BindsInstance activityManager: ActivityManager,
+            @BindsInstance foldProvider: FoldProvider,
+            @BindsInstance activityTypeProvider: CurrentActivityTypeProvider,
             @BindsInstance sensorManager: SensorManager,
-            @BindsInstance @Main handler: Handler,
-            @BindsInstance @Main executor: Executor,
-            @BindsInstance @UiBackground backgroundExecutor: Executor,
+            @BindsInstance @UnfoldMain handler: Handler,
+            @BindsInstance @UnfoldMain executor: Executor,
+            @BindsInstance @UnfoldBackground backgroundExecutor: Executor,
             @BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
             @BindsInstance contentResolver: ContentResolver = context.contentResolver
         ): UnfoldSharedComponent
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
similarity index 96%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
index c612995..8f4ee4d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.unfold
 
 import android.hardware.SensorManager
-import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.dagger.UnfoldBackground
 import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
 import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
 import com.android.systemui.unfold.updates.DeviceFoldStateProvider
@@ -70,7 +70,7 @@
     fun hingeAngleProvider(
         config: UnfoldTransitionConfig,
         sensorManager: SensorManager,
-        @UiBackground executor: Executor
+        @UnfoldBackground executor: Executor
     ): HingeAngleProvider =
         if (config.isHingeAngleEnabled) {
             HingeSensorAngleProvider(sensorManager, executor)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
similarity index 83%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
index cc56007c..402dd84 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
@@ -17,14 +17,13 @@
 
 package com.android.systemui.unfold
 
-import android.app.ActivityManager
 import android.content.Context
 import android.hardware.SensorManager
-import android.hardware.devicestate.DeviceStateManager
 import android.os.Handler
-import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.updates.FoldProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
+import com.android.systemui.unfold.util.CurrentActivityTypeProvider
 import java.util.concurrent.Executor
 
 /**
@@ -39,8 +38,8 @@
     context: Context,
     config: UnfoldTransitionConfig,
     screenStatusProvider: ScreenStatusProvider,
-    deviceStateManager: DeviceStateManager,
-    activityManager: ActivityManager,
+    foldProvider: FoldProvider,
+    activityTypeProvider: CurrentActivityTypeProvider,
     sensorManager: SensorManager,
     mainHandler: Handler,
     mainExecutor: Executor,
@@ -52,8 +51,8 @@
             context,
             config,
             screenStatusProvider,
-            deviceStateManager,
-            activityManager,
+            foldProvider,
+            activityTypeProvider,
             sensorManager,
             mainHandler,
             mainExecutor,
@@ -64,5 +63,3 @@
         ?: throw IllegalStateException(
             "Trying to create " +
                 "UnfoldTransitionProgressProvider when the transition is disabled")
-
-fun createConfig(context: Context): UnfoldTransitionConfig = ResourceUnfoldTransitionConfig(context)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionProgressProvider.kt
similarity index 93%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionProgressProvider.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionProgressProvider.kt
index 409dc95..d54481c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionProgressProvider.kt
@@ -15,9 +15,9 @@
  */
 package com.android.systemui.unfold
 
-import android.annotation.FloatRange
-import com.android.systemui.statusbar.policy.CallbackController
+import androidx.annotation.FloatRange
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.util.CallbackController
 
 /**
  * Interface that allows to receive unfold transition progress updates.
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt
new file mode 100644
index 0000000..2044f05
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.compat
+
+import android.content.Context
+import android.content.res.Configuration
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
+import java.util.concurrent.Executor
+
+/**
+ * Fold provider that notifies about fold state based on the screen size
+ * It could be used when no activity context is available
+ * TODO(b/232369816): use Jetpack WM library when non-activity contexts supported b/169740873
+ */
+class ScreenSizeFoldProvider(private val context: Context) : FoldProvider {
+
+    private var callbacks: MutableList<FoldCallback> = arrayListOf()
+    private var lastWidth: Int = 0
+
+    override fun registerCallback(callback: FoldCallback, executor: Executor) {
+        callbacks += callback
+        onConfigurationChange(context.resources.configuration)
+    }
+
+    override fun unregisterCallback(callback: FoldCallback) {
+        callbacks -= callback
+    }
+
+    fun onConfigurationChange(newConfig: Configuration) {
+        if (lastWidth == newConfig.smallestScreenWidthDp) {
+            return
+        }
+
+        if (newConfig.smallestScreenWidthDp > INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP) {
+            callbacks.forEach { it.onFoldUpdated(false) }
+        } else {
+            callbacks.forEach { it.onFoldUpdated(true) }
+        }
+        lastWidth = newConfig.smallestScreenWidthDp
+    }
+}
+
+private const val INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP = 600
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/SizeScreenStatusProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/SizeScreenStatusProvider.kt
new file mode 100644
index 0000000..c405f31
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/SizeScreenStatusProvider.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.compat
+
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
+import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
+import java.util.concurrent.Executor
+
+class SizeScreenStatusProvider(
+    private val foldProvider: FoldProvider,
+    private val executor: Executor
+) : ScreenStatusProvider {
+
+    private val listeners: MutableList<ScreenListener> = arrayListOf()
+    private val callback = object : FoldProvider.FoldCallback {
+        override fun onFoldUpdated(isFolded: Boolean) {
+            if (!isFolded) {
+                listeners.forEach { it.onScreenTurnedOn() }
+            }
+        }
+    }
+
+    fun start() {
+        foldProvider.registerCallback(
+            callback,
+            executor
+        )
+    }
+
+    fun stop() {
+        foldProvider.unregisterCallback(callback)
+    }
+
+    override fun addCallback(listener: ScreenListener) {
+        listeners.add(listener)
+    }
+
+    override fun removeCallback(listener: ScreenListener) {
+        listeners.remove(listener)
+    }
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
new file mode 100644
index 0000000..c513729
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.config
+
+import android.content.res.Resources
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class ResourceUnfoldTransitionConfig @Inject constructor() : UnfoldTransitionConfig {
+
+    override val isEnabled: Boolean by lazy {
+        val id = Resources.getSystem()
+            .getIdentifier("config_unfoldTransitionEnabled", "bool", "android")
+        Resources.getSystem().getBoolean(id)
+    }
+
+    override val isHingeAngleEnabled: Boolean by lazy {
+        val id = Resources.getSystem()
+            .getIdentifier("config_unfoldTransitionHingeAngle", "bool", "android")
+        Resources.getSystem().getBoolean(id)
+    }
+
+    override val halfFoldedTimeoutMillis: Int by lazy {
+        val id = Resources.getSystem()
+            .getIdentifier("config_unfoldTransitionHalfFoldedTimeout", "integer", "android")
+        Resources.getSystem().getInteger(id)
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
similarity index 95%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
index 5b187b3..765e862 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
@@ -18,4 +18,5 @@
 interface UnfoldTransitionConfig {
     val isEnabled: Boolean
     val isHingeAngleEnabled: Boolean
+    val halfFoldedTimeoutMillis: Int
 }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBackground.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBackground.kt
new file mode 100644
index 0000000..6074795
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBackground.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.dagger
+
+import javax.inject.Qualifier
+
+/**
+ * Alternative to [UiBackground] qualifier annotation in unfold module.
+ * It is needed as we can't depend on SystemUI code in this module.
+ */
+@Qualifier
+@Retention(AnnotationRetention.RUNTIME)
+annotation class UnfoldBackground
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldMain.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldMain.kt
new file mode 100644
index 0000000..5553690f
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldMain.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.dagger
+
+import javax.inject.Qualifier
+
+/**
+ * Alternative to [Main] qualifier annotation in unfold module.
+ * It is needed as we can't depend on SystemUI code in this module.
+ */
+@Qualifier
+@Retention(AnnotationRetention.RUNTIME)
+annotation class UnfoldMain
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
similarity index 100%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
similarity index 97%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
index 04d920c..2ab28c6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
@@ -16,7 +16,6 @@
 package com.android.systemui.unfold.progress
 
 import android.util.Log
-import android.util.MathUtils.saturate
 import androidx.dynamicanimation.animation.DynamicAnimation
 import androidx.dynamicanimation.animation.FloatPropertyCompat
 import androidx.dynamicanimation.animation.SpringAnimation
@@ -70,6 +69,9 @@
         springAnimation.animateToFinalPosition(progress)
     }
 
+    private fun saturate(amount: Float, low: Float = 0f, high: Float = 1f): Float =
+        if (amount < low) low else if (amount > high) high else amount
+
     override fun onFoldUpdate(@FoldUpdate update: Int) {
         when (update) {
             FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE -> {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
similarity index 74%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index 14581cc..e8038fd 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -15,46 +15,46 @@
  */
 package com.android.systemui.unfold.updates
 
-import android.annotation.FloatRange
-import android.app.ActivityManager
-import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
-import android.content.Context
-import android.hardware.devicestate.DeviceStateManager
 import android.os.Handler
 import android.util.Log
+import androidx.annotation.FloatRange
 import androidx.annotation.VisibleForTesting
 import androidx.core.util.Consumer
-import com.android.systemui.dagger.qualifiers.Main
+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.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 java.util.concurrent.Executor
 import javax.inject.Inject
 
 class DeviceFoldStateProvider
 @Inject
 constructor(
-    context: Context,
+    config: UnfoldTransitionConfig,
     private val hingeAngleProvider: HingeAngleProvider,
     private val screenStatusProvider: ScreenStatusProvider,
-    private val deviceStateManager: DeviceStateManager,
-    private val activityManager: ActivityManager,
-    @Main private val mainExecutor: Executor,
-    @Main private val handler: Handler
+    private val foldProvider: FoldProvider,
+    private val activityTypeProvider: CurrentActivityTypeProvider,
+    @UnfoldMain private val mainExecutor: Executor,
+    @UnfoldMain private val handler: Handler
 ) : FoldStateProvider {
 
     private val outputListeners: MutableList<FoldUpdatesListener> = mutableListOf()
 
-    @FoldUpdate private var lastFoldUpdate: Int? = null
+    @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 lastHingeAngle: Float = 0f
 
     private val hingeAngleListener = HingeAngleListener()
     private val screenListener = ScreenStatusListener()
-    private val foldStateListener = FoldStateListener(context)
+    private val foldStateListener = FoldStateListener()
     private val timeoutRunnable = TimeoutRunnable()
 
     /**
@@ -62,22 +62,20 @@
      * [FOLD_UPDATE_START_CLOSING] or [FOLD_UPDATE_START_OPENING] event, if an end state is not
      * reached.
      */
-    private val halfOpenedTimeoutMillis: Int =
-        context.resources.getInteger(
-            com.android.internal.R.integer.config_unfoldTransitionHalfFoldedTimeout)
+    private val halfOpenedTimeoutMillis: Int = config.halfFoldedTimeoutMillis
 
     private var isFolded = false
     private var isUnfoldHandled = true
 
     override fun start() {
-        deviceStateManager.registerCallback(mainExecutor, foldStateListener)
+        foldProvider.registerCallback(foldStateListener, mainExecutor)
         screenStatusProvider.addCallback(screenListener)
         hingeAngleProvider.addCallback(hingeAngleListener)
     }
 
     override fun stop() {
         screenStatusProvider.removeCallback(screenListener)
-        deviceStateManager.unregisterCallback(foldStateListener)
+        foldProvider.unregisterCallback(foldStateListener)
         hingeAngleProvider.removeCallback(hingeAngleListener)
         hingeAngleProvider.stop()
     }
@@ -92,13 +90,13 @@
 
     override val isFinishedOpening: Boolean
         get() = !isFolded &&
-            (lastFoldUpdate == FOLD_UPDATE_FINISH_FULL_OPEN ||
-                lastFoldUpdate == FOLD_UPDATE_FINISH_HALF_OPEN)
+                (lastFoldUpdate == FOLD_UPDATE_FINISH_FULL_OPEN ||
+                        lastFoldUpdate == FOLD_UPDATE_FINISH_HALF_OPEN)
 
     private val isTransitionInProgress: Boolean
         get() =
             lastFoldUpdate == FOLD_UPDATE_START_OPENING ||
-                lastFoldUpdate == FOLD_UPDATE_START_CLOSING
+                    lastFoldUpdate == FOLD_UPDATE_START_CLOSING
 
     private fun onHingeAngle(angle: Float) {
         if (DEBUG) {
@@ -136,39 +134,36 @@
      * apps that support table-top/HALF_FOLDED mode. Only for launcher, there is no threshold.
      */
     private fun getClosingThreshold(): Int? {
-        val activityType =
-            activityManager.getRunningTasks(/* maxNum= */ 1)?.getOrNull(0)?.topActivityType
-                ?: return null
+        val isHomeActivity = activityTypeProvider.isHomeActivity ?: return null
 
         if (DEBUG) {
-            Log.d(TAG, "activityType=" + activityType)
+            Log.d(TAG, "isHomeActivity=$isHomeActivity")
         }
 
-        return if (activityType == ACTIVITY_TYPE_HOME) {
+        return if (isHomeActivity) {
             null
         } else {
             START_CLOSING_ON_APPS_THRESHOLD_DEGREES
         }
     }
 
-    private inner class FoldStateListener(context: Context) :
-        DeviceStateManager.FoldStateListener(
-            context,
-            { folded: Boolean ->
-                isFolded = folded
-                lastHingeAngle = FULLY_CLOSED_DEGREES
+    private inner class FoldStateListener : FoldProvider.FoldCallback {
+        override fun onFoldUpdated(isFolded: Boolean) {
+            this@DeviceFoldStateProvider.isFolded = isFolded
+            lastHingeAngle = FULLY_CLOSED_DEGREES
 
-                if (folded) {
-                    hingeAngleProvider.stop()
-                    notifyFoldUpdate(FOLD_UPDATE_FINISH_CLOSED)
-                    cancelTimeout()
-                    isUnfoldHandled = false
-                } else {
-                    notifyFoldUpdate(FOLD_UPDATE_START_OPENING)
-                    rescheduleAbortAnimationTimeout()
-                    hingeAngleProvider.start()
-                }
-            })
+            if (isFolded) {
+                hingeAngleProvider.stop()
+                notifyFoldUpdate(FOLD_UPDATE_FINISH_CLOSED)
+                cancelTimeout()
+                isUnfoldHandled = false
+            } else {
+                notifyFoldUpdate(FOLD_UPDATE_START_OPENING)
+                rescheduleAbortAnimationTimeout()
+                hingeAngleProvider.start()
+            }
+        }
+    }
 
     private fun notifyFoldUpdate(@FoldUpdate update: Int) {
         if (DEBUG) {
@@ -234,7 +229,9 @@
 private const val DEBUG = false
 
 /** Threshold after which we consider the device fully unfolded. */
-@VisibleForTesting const val FULLY_OPEN_THRESHOLD_DEGREES = 15f
+@VisibleForTesting
+const val FULLY_OPEN_THRESHOLD_DEGREES = 15f
 
 /** Fold animation on top of apps only when the angle exceeds this threshold. */
-@VisibleForTesting const val START_CLOSING_ON_APPS_THRESHOLD_DEGREES = 60
+@VisibleForTesting
+const val START_CLOSING_ON_APPS_THRESHOLD_DEGREES = 60
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldProvider.kt
new file mode 100644
index 0000000..6e87bee
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldProvider.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.updates
+
+import java.util.concurrent.Executor
+
+interface FoldProvider {
+    fun registerCallback(callback: FoldCallback, executor: Executor)
+    fun unregisterCallback(callback: FoldCallback)
+
+    interface FoldCallback {
+        fun onFoldUpdated(isFolded: Boolean)
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
similarity index 91%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
index 14a3a70..c7a8bf3 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
@@ -15,10 +15,10 @@
  */
 package com.android.systemui.unfold.updates
 
-import android.annotation.FloatRange
-import android.annotation.IntDef
-import com.android.systemui.statusbar.policy.CallbackController
+import androidx.annotation.FloatRange
+import androidx.annotation.IntDef
 import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
+import com.android.systemui.unfold.util.CallbackController
 
 /**
  * Allows to subscribe to main events related to fold/unfold process such as hinge angle update,
@@ -36,7 +36,6 @@
     }
 
     @IntDef(
-        prefix = ["FOLD_UPDATE_"],
         value =
             [
                 FOLD_UPDATE_START_OPENING,
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/EmptyHingeAngleProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/EmptyHingeAngleProvider.kt
new file mode 100644
index 0000000..e985506
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/EmptyHingeAngleProvider.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.updates.hinge
+
+import androidx.core.util.Consumer
+
+internal object EmptyHingeAngleProvider : HingeAngleProvider {
+    override fun start() {}
+
+    override fun stop() {}
+
+    override fun removeCallback(listener: Consumer<Float>) {}
+
+    override fun addCallback(listener: Consumer<Float>) {}
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeAngleProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeAngleProvider.kt
new file mode 100644
index 0000000..e464c3f
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeAngleProvider.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.updates.hinge
+
+import androidx.core.util.Consumer
+import com.android.systemui.unfold.util.CallbackController
+
+/**
+ * Emits device hinge angle values (angle between two integral parts of the device).
+ *
+ * The hinge angle could be from 0 to 360 degrees inclusive. For foldable devices usually 0
+ * corresponds to fully closed (folded) state and 180 degrees corresponds to fully open (flat)
+ * state.
+ */
+interface HingeAngleProvider : CallbackController<Consumer<Float>> {
+    fun start()
+    fun stop()
+}
+
+const val FULLY_OPEN_DEGREES = 180f
+const val FULLY_CLOSED_DEGREES = 0f
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
similarity index 71%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
index c93412b..3fc5d61 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
@@ -1,3 +1,17 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
 package com.android.systemui.unfold.updates.hinge
 
 import android.hardware.Sensor
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
similarity index 93%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
index 668c694..d95e050 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
@@ -15,8 +15,8 @@
  */
 package com.android.systemui.unfold.updates.screen
 
-import com.android.systemui.statusbar.policy.CallbackController
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
+import com.android.systemui.unfold.util.CallbackController
 
 interface ScreenStatusProvider : CallbackController<ScreenListener> {
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt
similarity index 65%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt
index 1574c8d..d8bc018 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt
@@ -1,3 +1,17 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
 package com.android.systemui.unfold.util
 
 import android.os.Trace
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/CallbackController.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/CallbackController.kt
new file mode 100644
index 0000000..46ad534
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/CallbackController.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.util
+
+interface CallbackController<T> {
+    fun addCallback(listener: T)
+    fun removeCallback(listener: T)
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/CurrentActivityTypeProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/CurrentActivityTypeProvider.kt
new file mode 100644
index 0000000..d0e6cdc
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/CurrentActivityTypeProvider.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.util
+
+interface CurrentActivityTypeProvider {
+    val isHomeActivity: Boolean?
+}
+
+class EmptyCurrentActivityTypeProvider(override val isHomeActivity: Boolean? = null) :
+    CurrentActivityTypeProvider
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
similarity index 78%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
index dfe8792..5c92b34 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
@@ -1,3 +1,17 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
 package com.android.systemui.unfold.util
 
 import android.animation.ValueAnimator
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
similarity index 100%
rename from packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
rename to packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index dfa34bb..0a4ecb2 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -286,10 +286,18 @@
     // Package: android
     NOTE_MTE_OVERRIDE_ENABLED = 69;
 
+    // Notify the user that this is a guest session with information
+    // about first login and ephemeral state
+    // Package: android
+    NOTE_GUEST_SESSION = 70;
+
     // Inform the user of notification permissions changes.
     // Package: android
     NOTE_REVIEW_NOTIFICATION_PERMISSIONS = 71;
 
+    // Notify the user to setup their dock
+    NOTE_SETUP_DOCK = 72;
+
     // ADD_NEW_IDS_ABOVE_THIS_LINE
     // Legacy IDs with arbitrary values appear below
     // Legacy IDs existed as stable non-conflicting constants prior to the O release
diff --git a/services/companion/java/com/android/server/companion/AssociationStoreImpl.java b/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
index 229799a..d5991d3 100644
--- a/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
+++ b/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
@@ -73,6 +73,9 @@
     private final Set<OnChangeListener> mListeners = new LinkedHashSet<>();
 
     void addAssociation(@NonNull AssociationInfo association) {
+        // Validity check first.
+        checkNotRevoked(association);
+
         final int id = association.getId();
 
         if (DEBUG) {
@@ -99,6 +102,9 @@
     }
 
     void updateAssociation(@NonNull AssociationInfo updated) {
+        // Validity check first.
+        checkNotRevoked(updated);
+
         final int id = updated.getId();
 
         if (DEBUG) {
@@ -292,6 +298,9 @@
     }
 
     void setAssociations(Collection<AssociationInfo> allAssociations) {
+        // Validity check first.
+        allAssociations.forEach(AssociationStoreImpl::checkNotRevoked);
+
         if (DEBUG) {
             Log.i(TAG, "setAssociations() n=" + allAssociations.size());
             final StringJoiner stringJoiner = new StringJoiner(", ");
@@ -324,4 +333,11 @@
         mAddressMap.clear();
         mCachedPerUser.clear();
     }
+
+    private static void checkNotRevoked(@NonNull AssociationInfo association) {
+        if (association.isRevoked()) {
+            throw new IllegalArgumentException(
+                    "Revoked (removed) associations MUST NOT appear in the AssociationStore");
+        }
+    }
 }
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 2714add..abc4937 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -18,6 +18,7 @@
 package com.android.server.companion;
 
 import static android.Manifest.permission.MANAGE_COMPANION_DEVICES;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
 import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Process.SYSTEM_UID;
@@ -48,6 +49,8 @@
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
 import android.app.NotificationManager;
@@ -91,6 +94,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.content.PackageMonitor;
+import com.android.internal.infra.PerUser;
 import com.android.internal.notification.NotificationAccessConfirmationActivityContract;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ArrayUtils;
@@ -105,6 +109,7 @@
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -128,6 +133,9 @@
 
     private static final long ASSOCIATION_REMOVAL_TIME_WINDOW_DEFAULT = DAYS.toMillis(90);
 
+    private final ActivityManager mActivityManager;
+    private final OnPackageVisibilityChangeListener mOnPackageVisibilityChangeListener;
+
     private PersistentDataStore mPersistentStore;
     private final PersistUserStateHandler mUserPersistenceHandler;
 
@@ -152,12 +160,40 @@
     @GuardedBy("mPreviouslyUsedIds")
     private final SparseArray<Map<String, Set<Integer>>> mPreviouslyUsedIds = new SparseArray<>();
 
+    /**
+     * A structure that consists of a set of revoked associations that pending for role holder
+     * removal per each user.
+     *
+     * @see #maybeRemoveRoleHolderForAssociation(AssociationInfo)
+     * @see #addToPendingRoleHolderRemoval(AssociationInfo)
+     * @see #removeFromPendingRoleHolderRemoval(AssociationInfo)
+     * @see #getPendingRoleHolderRemovalAssociationsForUser(int)
+     */
+    @GuardedBy("mRevokedAssociationsPendingRoleHolderRemoval")
+    private final PerUserAssociationSet mRevokedAssociationsPendingRoleHolderRemoval =
+            new PerUserAssociationSet();
+    /**
+     * Contains uid-s of packages pending to be removed from the role holder list (after
+     * revocation of an association), which will happen one the package is no longer visible to the
+     * user.
+     * For quicker uid -> (userId, packageName) look-up this is not a {@code Set<Integer>} but
+     * a {@code Map<Integer, String>} which maps uid-s to packageName-s (userId-s can be derived
+     * from uid-s using {@link UserHandle#getUserId(int)}).
+     *
+     * @see #maybeRemoveRoleHolderForAssociation(AssociationInfo)
+     * @see #addToPendingRoleHolderRemoval(AssociationInfo)
+     * @see #removeFromPendingRoleHolderRemoval(AssociationInfo)
+     */
+    @GuardedBy("mRevokedAssociationsPendingRoleHolderRemoval")
+    private final Map<Integer, String> mUidsPendingRoleHolderRemoval = new HashMap<>();
+
     private final RemoteCallbackList<IOnAssociationsChangedListener> mListeners =
             new RemoteCallbackList<>();
 
     public CompanionDeviceManagerService(Context context) {
         super(context);
 
+        mActivityManager = context.getSystemService(ActivityManager.class);
         mPowerWhitelistManager = context.getSystemService(PowerWhitelistManager.class);
         mAppOpsManager = IAppOpsService.Stub.asInterface(
                 ServiceManager.getService(Context.APP_OPS_SERVICE));
@@ -168,6 +204,9 @@
 
         mUserPersistenceHandler = new PersistUserStateHandler();
         mAssociationStore = new AssociationStoreImpl();
+
+        mOnPackageVisibilityChangeListener =
+                new OnPackageVisibilityChangeListener(mActivityManager);
     }
 
     @Override
@@ -204,7 +243,33 @@
                     mUserManager.getAliveUsers(), allAssociations, mPreviouslyUsedIds);
         }
 
-        mAssociationStore.setAssociations(allAssociations);
+        final Set<AssociationInfo> activeAssociations =
+                new ArraySet<>(/* capacity */ allAssociations.size());
+        // A set contains the userIds that need to persist state after remove the app
+        // from the list of role holders.
+        final Set<Integer> usersToPersistStateFor = new ArraySet<>();
+
+        for (AssociationInfo association : allAssociations) {
+            if (!association.isRevoked()) {
+                activeAssociations.add(association);
+            } else if (maybeRemoveRoleHolderForAssociation(association)) {
+                // Nothing more to do here, but we'll need to persist all the associations to the
+                // disk afterwards.
+                usersToPersistStateFor.add(association.getUserId());
+            } else {
+                addToPendingRoleHolderRemoval(association);
+            }
+        }
+
+        mAssociationStore.setAssociations(activeAssociations);
+
+        // IMPORTANT: only do this AFTER mAssociationStore.setAssociations(), because
+        // persistStateForUser() queries AssociationStore.
+        // (If persistStateForUser() is invoked before mAssociationStore.setAssociations() it
+        // would effectively just clear-out all the persisted associations).
+        for (int userId : usersToPersistStateFor) {
+            persistStateForUser(userId);
+        }
     }
 
     @Override
@@ -354,10 +419,18 @@
     }
 
     private void persistStateForUser(@UserIdInt int userId) {
-        final List<AssociationInfo> updatedAssociations =
-                mAssociationStore.getAssociationsForUser(userId);
+        // We want to store both active associations and the revoked (removed) association that we
+        // are keeping around for the final clean-up (delayed role holder removal).
+        final List<AssociationInfo> allAssociations;
+        // Start with the active associations - these we can get from the AssociationStore.
+        allAssociations = new ArrayList<>(
+                mAssociationStore.getAssociationsForUser(userId));
+        // ... and add the revoked (removed) association, that are yet to be permanently removed.
+        allAssociations.addAll(getPendingRoleHolderRemovalAssociationsForUser(userId));
+
         final Map<String, Set<Integer>> usedIdsForUser = getPreviouslyUsedIdsForUser(userId);
-        mPersistentStore.persistStateForUser(userId, updatedAssociations, usedIdsForUser);
+
+        mPersistentStore.persistStateForUser(userId, allAssociations, usedIdsForUser);
     }
 
     private void notifyListeners(
@@ -425,13 +498,17 @@
             removalWindow = ASSOCIATION_REMOVAL_TIME_WINDOW_DEFAULT;
         }
 
-        for (AssociationInfo ai : mAssociationStore.getAssociations()) {
-            if (!ai.isSelfManaged()) continue;
-            final boolean isInactive =  currentTime - ai.getLastTimeConnectedMs() >= removalWindow;
-            if (isInactive) {
-                Slog.i(TAG, "Removing inactive self-managed association: " + ai.getId());
-                disassociateInternal(ai.getId());
-            }
+        for (AssociationInfo association : mAssociationStore.getAssociations()) {
+            if (!association.isSelfManaged()) continue;
+
+            final boolean isInactive =
+                    currentTime - association.getLastTimeConnectedMs() >= removalWindow;
+            if (!isInactive) continue;
+
+            final int id = association.getId();
+
+            Slog.i(TAG, "Removing inactive self-managed association id=" + id);
+            disassociateInternal(id);
         }
     }
 
@@ -671,7 +748,7 @@
             enforceCallerIsSystemOr(userId, packageName);
 
             AssociationInfo association = mAssociationStore.getAssociationsForPackageWithAddress(
-                            userId, packageName, deviceAddress);
+                    userId, packageName, deviceAddress);
 
             if (association == null) {
                 throw new RemoteException(new DeviceNotAssociatedException("App " + packageName
@@ -731,7 +808,7 @@
 
             enforceUsesCompanionDeviceFeature(getContext(), userId, callingPackage);
             checkState(!ArrayUtils.isEmpty(
-                    mAssociationStore.getAssociationsForPackage(userId, callingPackage)),
+                            mAssociationStore.getAssociationsForPackage(userId, callingPackage)),
                     "App must have an association before calling this API");
         }
 
@@ -791,8 +868,8 @@
         final long timestamp = System.currentTimeMillis();
 
         final AssociationInfo association = new AssociationInfo(id, userId, packageName,
-                macAddress, displayName, deviceProfile, selfManaged, false, timestamp,
-                Long.MAX_VALUE);
+                macAddress, displayName, deviceProfile, selfManaged,
+                /* notifyOnDeviceNearby */ false, /* revoked */ false, timestamp, Long.MAX_VALUE);
         Slog.i(TAG, "New CDM association created=" + association);
         mAssociationStore.addAssociation(association);
 
@@ -804,6 +881,11 @@
 
         updateSpecialAccessPermissionForAssociatedPackage(association);
         logCreateAssociation(deviceProfile);
+
+        // Don't need to update the mRevokedAssociationsPendingRoleHolderRemoval since
+        // maybeRemoveRoleHolderForAssociation in PackageInactivityListener will handle the case
+        // that there are other devices with the same profile, so the role holder won't be removed.
+
         return association;
     }
 
@@ -884,36 +966,184 @@
         final String packageName = association.getPackageName();
         final String deviceProfile = association.getDeviceProfile();
 
+        if (!maybeRemoveRoleHolderForAssociation(association)) {
+            // Need to remove the app from list of the role holders, but will have to do it later
+            // (the app is in foreground at the moment).
+            addToPendingRoleHolderRemoval(association);
+        }
+
+        // Need to check if device still present now because CompanionDevicePresenceMonitor will
+        // remove current connected device after mAssociationStore.removeAssociation
         final boolean wasPresent = mDevicePresenceMonitor.isDevicePresent(associationId);
 
         // Removing the association.
         mAssociationStore.removeAssociation(associationId);
+        // Do not need to persistUserState since CompanionDeviceManagerService will get callback
+        // from #onAssociationChanged, and it will handle the persistUserState which including
+        // active and revoked association.
         logRemoveAssociation(deviceProfile);
 
-        final List<AssociationInfo> otherAssociations =
-                mAssociationStore.getAssociationsForPackage(userId, packageName);
-
-        // Check if the package is associated with other devices with the same profile.
-        // If not: take away the role.
-        if (deviceProfile != null) {
-            final boolean shouldKeepTheRole = any(otherAssociations,
-                    it -> deviceProfile.equals(it.getDeviceProfile()));
-            if (!shouldKeepTheRole) {
-                Binder.withCleanCallingIdentity(() ->
-                        removeRoleHolderForAssociation(getContext(), association));
-            }
-        }
-
         if (!wasPresent || !association.isNotifyOnDeviceNearby()) return;
         // The device was connected and the app was notified: check if we need to unbind the app
         // now.
-        final boolean shouldStayBound = any(otherAssociations,
+        final boolean shouldStayBound = any(
+                mAssociationStore.getAssociationsForPackage(userId, packageName),
                 it -> it.isNotifyOnDeviceNearby()
                         && mDevicePresenceMonitor.isDevicePresent(it.getId()));
         if (shouldStayBound) return;
         mCompanionAppController.unbindCompanionApplication(userId, packageName);
     }
 
+    /**
+     * First, checks if the companion application should be removed from the list role holders when
+     * upon association's removal, i.e.: association's profile (matches the role) is not null,
+     * the application does not have other associations with the same profile, etc.
+     *
+     * <p>
+     * Then, if establishes that the application indeed has to be removed from the list of the role
+     * holders, checks if it could be done right now -
+     * {@link android.app.role.RoleManager#removeRoleHolderAsUser(String, String, int, UserHandle, java.util.concurrent.Executor, java.util.function.Consumer) RoleManager#removeRoleHolderAsUser()}
+     * will kill the application's process, which leads poor user experience if the application was
+     * in foreground when this happened, to avoid this CDMS delays invoking
+     * {@code RoleManager.removeRoleHolderAsUser()} until the app is no longer in foreground.
+     *
+     * @return {@code true} if the application does NOT need be removed from the list of the role
+     *         holders OR if the application was successfully removed from the list of role holders.
+     *         I.e.: from the role-management perspective the association is done with.
+     *         {@code false} if the application needs to be removed from the list of role the role
+     *         holders, BUT it CDMS would prefer to do it later.
+     *         I.e.: application is in the foreground at the moment, but invoking
+     *         {@code RoleManager.removeRoleHolderAsUser()} will kill the application's process,
+     *         which would lead to the poor UX, hence need to try later.
+     */
+
+    private boolean maybeRemoveRoleHolderForAssociation(@NonNull AssociationInfo association) {
+        if (DEBUG) Log.d(TAG, "maybeRemoveRoleHolderForAssociation() association=" + association);
+
+        final String deviceProfile = association.getDeviceProfile();
+        if (deviceProfile == null) {
+            // No role was granted to for this association, there is nothing else we need to here.
+            return true;
+        }
+
+        // Check if the applications is associated with another devices with the profile. If so,
+        // it should remain the role holder.
+        final int id = association.getId();
+        final int userId = association.getUserId();
+        final String packageName = association.getPackageName();
+        final boolean roleStillInUse = any(
+                mAssociationStore.getAssociationsForPackage(userId, packageName),
+                it -> deviceProfile.equals(it.getDeviceProfile()) && id != it.getId());
+        if (roleStillInUse) {
+            // Application should remain a role holder, there is nothing else we need to here.
+            return true;
+        }
+
+        final int packageProcessImportance = getPackageProcessImportance(userId, packageName);
+        if (packageProcessImportance <= IMPORTANCE_VISIBLE) {
+            // Need to remove the app from the list of role holders, but the process is visible to
+            // the user at the moment, so we'll need to it later: log and return false.
+            Slog.i(TAG, "Cannot remove role holder for the removed association id=" + id
+                    + " now - process is visible.");
+            return false;
+        }
+
+        removeRoleHolderForAssociation(getContext(), association);
+        return true;
+    }
+
+    private int getPackageProcessImportance(@UserIdInt int userId, @NonNull String packageName) {
+        return Binder.withCleanCallingIdentity(() -> {
+            final int uid =
+                    mPackageManagerInternal.getPackageUid(packageName, /* flags */0, userId);
+            return mActivityManager.getUidImportance(uid);
+        });
+    }
+
+    /**
+     * Set revoked flag for active association and add the revoked association and the uid into
+     * the caches.
+     *
+     * @see #mRevokedAssociationsPendingRoleHolderRemoval
+     * @see #mUidsPendingRoleHolderRemoval
+     * @see OnPackageVisibilityChangeListener
+     */
+    private void addToPendingRoleHolderRemoval(@NonNull AssociationInfo association) {
+        // First: set revoked flag.
+        association = AssociationInfo.builder(association)
+                .setRevoked(true)
+                .build();
+
+        final String packageName = association.getPackageName();
+        final int userId = association.getUserId();
+        final int uid = mPackageManagerInternal.getPackageUid(packageName, /* flags */0, userId);
+
+        // Second: add to the set.
+        synchronized (mRevokedAssociationsPendingRoleHolderRemoval) {
+            mRevokedAssociationsPendingRoleHolderRemoval.forUser(association.getUserId())
+                    .add(association);
+            if (!mUidsPendingRoleHolderRemoval.containsKey(uid)) {
+                mUidsPendingRoleHolderRemoval.put(uid, packageName);
+
+                if (mUidsPendingRoleHolderRemoval.size() == 1) {
+                    // Just added first uid: start the listener
+                    mOnPackageVisibilityChangeListener.startListening();
+                }
+            }
+        }
+    }
+
+    /**
+     * Remove the revoked association form the cache and also remove the uid form the map if
+     * there are other associations with the same package still pending for role holder removal.
+     *
+     * @see #mRevokedAssociationsPendingRoleHolderRemoval
+     * @see #mUidsPendingRoleHolderRemoval
+     * @see OnPackageVisibilityChangeListener
+     */
+    private void removeFromPendingRoleHolderRemoval(@NonNull AssociationInfo association) {
+        final String packageName = association.getPackageName();
+        final int userId = association.getUserId();
+        final int uid = mPackageManagerInternal.getPackageUid(packageName, /* flags */0, userId);
+
+        synchronized (mRevokedAssociationsPendingRoleHolderRemoval) {
+            mRevokedAssociationsPendingRoleHolderRemoval.forUser(userId)
+                    .remove(association);
+
+            final boolean shouldKeepUidForRemoval = any(
+                    getPendingRoleHolderRemovalAssociationsForUser(userId),
+                    ai -> packageName.equals(ai.getPackageName()));
+            // Do not remove the uid form the map since other associations with
+            // the same packageName still pending for role holder removal.
+            if (!shouldKeepUidForRemoval) {
+                mUidsPendingRoleHolderRemoval.remove(uid);
+            }
+
+            if (mUidsPendingRoleHolderRemoval.isEmpty()) {
+                // The set is empty now - can "turn off" the listener.
+                mOnPackageVisibilityChangeListener.stopListening();
+            }
+        }
+    }
+
+    /**
+     * @return a copy of the revoked associations set (safeguarding against
+     *         {@code ConcurrentModificationException}-s).
+     */
+    private @NonNull Set<AssociationInfo> getPendingRoleHolderRemovalAssociationsForUser(
+            @UserIdInt int userId) {
+        synchronized (mRevokedAssociationsPendingRoleHolderRemoval) {
+            // Return a copy.
+            return new ArraySet<>(mRevokedAssociationsPendingRoleHolderRemoval.forUser(userId));
+        }
+    }
+
+    private String getPackageNameByUid(int uid) {
+        synchronized (mRevokedAssociationsPendingRoleHolderRemoval) {
+            return mUidsPendingRoleHolderRemoval.get(uid);
+        }
+    }
+
     private void updateSpecialAccessPermissionForAssociatedPackage(AssociationInfo association) {
         final PackageInfo packageInfo =
                 getPackageInfo(getContext(), association.getUserId(), association.getPackageName());
@@ -1134,4 +1364,80 @@
             persistStateForUser(userId);
         }
     }
+
+    /**
+     * An OnUidImportanceListener class which watches the importance of the packages.
+     * In this class, we ONLY interested in the importance of the running process is greater than
+     * {@link RunningAppProcessInfo.IMPORTANCE_VISIBLE} for the uids have been added into the
+     * {@link mUidsPendingRoleHolderRemoval}. Lastly remove the role holder for the revoked
+     * associations for the same packages.
+     *
+     * @see #maybeRemoveRoleHolderForAssociation(AssociationInfo)
+     * @see #removeFromPendingRoleHolderRemoval(AssociationInfo)
+     * @see #getPendingRoleHolderRemovalAssociationsForUser(int)
+     */
+    private class OnPackageVisibilityChangeListener implements
+            ActivityManager.OnUidImportanceListener {
+        final @NonNull ActivityManager mAm;
+
+        OnPackageVisibilityChangeListener(@NonNull ActivityManager am) {
+            this.mAm = am;
+        }
+
+        void startListening() {
+            Binder.withCleanCallingIdentity(
+                    () -> mAm.addOnUidImportanceListener(
+                            /* listener */ OnPackageVisibilityChangeListener.this,
+                            RunningAppProcessInfo.IMPORTANCE_VISIBLE));
+        }
+
+        void stopListening() {
+            Binder.withCleanCallingIdentity(
+                    () -> mAm.removeOnUidImportanceListener(
+                            /* listener */ OnPackageVisibilityChangeListener.this));
+        }
+
+        @Override
+        public void onUidImportance(int uid, int importance) {
+            if (importance <= RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
+                // The lower the importance value the more "important" the process is.
+                // We are only interested when the process ceases to be visible.
+                return;
+            }
+
+            final String packageName = getPackageNameByUid(uid);
+            if (packageName == null) {
+                // Not interested in this uid.
+                return;
+            }
+
+            final int userId = UserHandle.getUserId(uid);
+
+            boolean needToPersistStateForUser = false;
+
+            for (AssociationInfo association :
+                    getPendingRoleHolderRemovalAssociationsForUser(userId)) {
+                if (!packageName.equals(association.getPackageName())) continue;
+
+                if (!maybeRemoveRoleHolderForAssociation(association)) {
+                    // Did not remove the role holder, will have to try again later.
+                    continue;
+                }
+
+                removeFromPendingRoleHolderRemoval(association);
+                needToPersistStateForUser = true;
+            }
+
+            if (needToPersistStateForUser) {
+                mUserPersistenceHandler.postPersistUserState(userId);
+            }
+        }
+    }
+
+    private static class PerUserAssociationSet extends PerUser<Set<AssociationInfo>> {
+        @Override
+        protected @NonNull Set<AssociationInfo> create(int userId) {
+            return new ArraySet<>();
+        }
+    }
 }
diff --git a/services/companion/java/com/android/server/companion/PersistentDataStore.java b/services/companion/java/com/android/server/companion/PersistentDataStore.java
index 3639389..4b56c1b 100644
--- a/services/companion/java/com/android/server/companion/PersistentDataStore.java
+++ b/services/companion/java/com/android/server/companion/PersistentDataStore.java
@@ -103,7 +103,7 @@
  * Since Android T the data is stored to "companion_device_manager.xml" file in
  * {@link Environment#getDataSystemDeDirectory(int) /data/system_de/}.
  *
- * See {@link #getBaseStorageFileForUser(int) getBaseStorageFileForUser()}
+ * See {@link DataStoreUtils#getBaseStorageFileForUser(int, String)}
  *
  * <p>
  * Since Android T the data is stored using the v1 schema.
@@ -120,7 +120,7 @@
  * <li> {@link #readPreviouslyUsedIdsV1(TypedXmlPullParser, Map) readPreviouslyUsedIdsV1()}
  * </ul>
  *
- * The following snippet is a sample of a file that is using v0 schema.
+ * The following snippet is a sample of a file that is using v1 schema.
  * <pre>{@code
  * <state persistence-version="1">
  *     <associations>
@@ -130,6 +130,8 @@
  *             mac_address="AA:BB:CC:DD:EE:00"
  *             self_managed="false"
  *             notify_device_nearby="false"
+ *             revoked="false"
+ *             last_time_connected="1634641160229"
  *             time_approved="1634389553216"/>
  *
  *         <association
@@ -139,6 +141,8 @@
  *             display_name="Jhon's Chromebook"
  *             self_managed="true"
  *             notify_device_nearby="false"
+ *             revoked="false"
+ *             last_time_connected="1634641160229"
  *             time_approved="1634641160229"/>
  *     </associations>
  *
@@ -178,6 +182,7 @@
     private static final String XML_ATTR_PROFILE = "profile";
     private static final String XML_ATTR_SELF_MANAGED = "self_managed";
     private static final String XML_ATTR_NOTIFY_DEVICE_NEARBY = "notify_device_nearby";
+    private static final String XML_ATTR_REVOKED = "revoked";
     private static final String XML_ATTR_TIME_APPROVED = "time_approved";
     private static final String XML_ATTR_LAST_TIME_CONNECTED = "last_time_connected";
 
@@ -415,7 +420,8 @@
 
         out.add(new AssociationInfo(associationId, userId, appPackage,
                 MacAddress.fromString(deviceAddress), null, profile,
-                /* managedByCompanionApp */false, notify, timeApproved, Long.MAX_VALUE));
+                /* managedByCompanionApp */ false, notify, /* revoked */ false, timeApproved,
+                Long.MAX_VALUE));
     }
 
     private static void readAssociationsV1(@NonNull TypedXmlPullParser parser,
@@ -444,13 +450,14 @@
         final String displayName = readStringAttribute(parser, XML_ATTR_DISPLAY_NAME);
         final boolean selfManaged = readBooleanAttribute(parser, XML_ATTR_SELF_MANAGED);
         final boolean notify = readBooleanAttribute(parser, XML_ATTR_NOTIFY_DEVICE_NEARBY);
+        final boolean revoked = readBooleanAttribute(parser, XML_ATTR_REVOKED, false);
         final long timeApproved = readLongAttribute(parser, XML_ATTR_TIME_APPROVED, 0L);
         final long lastTimeConnected = readLongAttribute(
                 parser, XML_ATTR_LAST_TIME_CONNECTED, Long.MAX_VALUE);
 
         final AssociationInfo associationInfo = createAssociationInfoNoThrow(associationId, userId,
-                appPackage, macAddress, displayName, profile, selfManaged, notify, timeApproved,
-                lastTimeConnected);
+                appPackage, macAddress, displayName, profile, selfManaged, notify, revoked,
+                timeApproved, lastTimeConnected);
         if (associationInfo != null) {
             out.add(associationInfo);
         }
@@ -503,6 +510,8 @@
         writeBooleanAttribute(serializer, XML_ATTR_SELF_MANAGED, a.isSelfManaged());
         writeBooleanAttribute(
                 serializer, XML_ATTR_NOTIFY_DEVICE_NEARBY, a.isNotifyOnDeviceNearby());
+        writeBooleanAttribute(
+                serializer, XML_ATTR_REVOKED, a.isRevoked());
         writeLongAttribute(serializer, XML_ATTR_TIME_APPROVED, a.getTimeApprovedMs());
         writeLongAttribute(
                 serializer, XML_ATTR_LAST_TIME_CONNECTED, a.getLastTimeConnectedMs());
@@ -544,11 +553,12 @@
     private static AssociationInfo createAssociationInfoNoThrow(int associationId,
             @UserIdInt int userId, @NonNull String appPackage, @Nullable MacAddress macAddress,
             @Nullable CharSequence displayName, @Nullable String profile, boolean selfManaged,
-            boolean notify, long timeApproved, long lastTimeConnected) {
+            boolean notify, boolean revoked, long timeApproved, long lastTimeConnected) {
         AssociationInfo associationInfo = null;
         try {
             associationInfo = new AssociationInfo(associationId, userId, appPackage, macAddress,
-                    displayName, profile, selfManaged, notify, timeApproved, lastTimeConnected);
+                    displayName, profile, selfManaged, notify, revoked, timeApproved,
+                    lastTimeConnected);
         } catch (Exception e) {
             if (DEBUG) Log.w(TAG, "Could not create AssociationInfo", e);
         }
diff --git a/services/companion/java/com/android/server/companion/RolesUtils.java b/services/companion/java/com/android/server/companion/RolesUtils.java
index 35488a8..0fff3f4 100644
--- a/services/companion/java/com/android/server/companion/RolesUtils.java
+++ b/services/companion/java/com/android/server/companion/RolesUtils.java
@@ -85,6 +85,8 @@
         final int userId = associationInfo.getUserId();
         final UserHandle userHandle = UserHandle.of(userId);
 
+        Slog.i(TAG, "Removing CDM role holder, role=" + deviceProfile
+                + ", package=u" + userId + "\\" + packageName);
         roleManager.removeRoleHolderAsUser(deviceProfile, packageName,
                 MANAGE_HOLDERS_FLAG_DONT_KILL_APP, userHandle, context.getMainExecutor(),
                 success -> {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index b059cc7..7d8c19f 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -168,8 +168,8 @@
         }
 
         @Override
-        public void onUserStopping(@NonNull TargetUser user) {
-            Slog.i(TAG, "onStopUser " + user);
+        public void onUserStopped(@NonNull TargetUser user) {
+            Slog.i(TAG, "onUserStopped " + user);
             mService.purgeUserData(user.getUserIdentifier());
         }
     }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a78c64b..00d728b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2297,13 +2297,9 @@
         return mAppOpsManager;
     }
 
-    /**
-     * Provides the basic functionality for activity task related tests when a handler thread is
-     * given to initialize the dependency members.
-     */
+    /** Provides the basic functionality for unit tests. */
     @VisibleForTesting
-    public ActivityManagerService(Injector injector, ServiceThread handlerThread) {
-        final boolean hasHandlerThread = handlerThread != null;
+    ActivityManagerService(Injector injector, @NonNull ServiceThread handlerThread) {
         mInjector = injector;
         mContext = mInjector.getContext();
         mUiContext = null;
@@ -2311,33 +2307,27 @@
         mPackageWatchdog = null;
         mAppOpsService = mInjector.getAppOpsService(null /* file */, null /* handler */);
         mBatteryStatsService = null;
-        mHandler = hasHandlerThread ? new MainHandler(handlerThread.getLooper()) : null;
+        mHandler = new MainHandler(handlerThread.getLooper());
         mHandlerThread = handlerThread;
-        mConstants = hasHandlerThread
-                ? new ActivityManagerConstants(mContext, this, mHandler) : null;
+        mConstants = new ActivityManagerConstants(mContext, this, mHandler);
         final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */);
         mPlatformCompat = null;
         mProcessList = injector.getProcessList(this);
         mProcessList.init(this, activeUids, mPlatformCompat);
         mAppProfiler = new AppProfiler(this, BackgroundThread.getHandler().getLooper(), null);
         mPhantomProcessList = new PhantomProcessList(this);
-        mOomAdjuster = hasHandlerThread
-                ? new OomAdjuster(this, mProcessList, activeUids, handlerThread) : null;
+        mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids, handlerThread);
 
-        mIntentFirewall = hasHandlerThread
-                ? new IntentFirewall(new IntentFirewallInterface(), mHandler) : null;
+        mIntentFirewall = null;
         mProcessStats = null;
         mCpHelper = new ContentProviderHelper(this, false);
-        // For the usage of {@link ActiveServices#cleanUpServices} that may be invoked from
-        // {@link ActivityTaskSupervisor#cleanUpRemovedTaskLocked}.
-        mServices = hasHandlerThread ? new ActiveServices(this) : null;
+        mServices = null;
         mSystemThread = null;
         mUiHandler = injector.getUiHandler(null /* service */);
         mUidObserverController = new UidObserverController(mUiHandler);
-        mUserController = hasHandlerThread ? new UserController(this) : null;
-        mPendingIntentController = hasHandlerThread
-                ? new PendingIntentController(handlerThread.getLooper(), mUserController,
-                        mConstants) : null;
+        mUserController = new UserController(this);
+        mPendingIntentController =
+                new PendingIntentController(handlerThread.getLooper(), mUserController, mConstants);
         mAppRestrictionController = new AppRestrictionController(mContext, this);
         mProcStartHandlerThread = null;
         mProcStartHandler = null;
@@ -2346,7 +2336,7 @@
         mFactoryTest = FACTORY_TEST_OFF;
         mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
         mInternal = new LocalService();
-        mPendingStartActivityUids = new PendingStartActivityUids(mContext);
+        mPendingStartActivityUids = new PendingStartActivityUids();
         mUseFifoUiScheduling = false;
         mEnableOffloadQueue = false;
         mFgBroadcastQueue = mBgBroadcastQueue = mBgOffloadBroadcastQueue =
@@ -2482,7 +2472,7 @@
         }
 
         mInternal = new LocalService();
-        mPendingStartActivityUids = new PendingStartActivityUids(mContext);
+        mPendingStartActivityUids = new PendingStartActivityUids();
         mTraceErrorLogger = new TraceErrorLogger();
         mComponentAliasResolver = new ComponentAliasResolver(this);
     }
@@ -17380,7 +17370,7 @@
             // next top activity on time. This race will fail the following binder transactions WM
             // sends to the activity. After this race issue between WM/ATMS and AMS is solved, this
             // workaround can be removed. (b/213288355)
-            if (isNewPending && mOomAdjuster != null) { // It can be null in unit test.
+            if (isNewPending) {
                 mOomAdjuster.mCachedAppOptimizer.unfreezeProcess(pid);
             }
             // We need to update the network rules for the app coming to the top state so that
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index 728792f..4533859 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -22,6 +22,9 @@
 import static android.os.Process.PROC_SPACE_TERM;
 import static android.os.Process.SYSTEM_UID;
 
+import static com.android.internal.util.FrameworkStatsLog.PROVIDER_ACQUISITION_EVENT_REPORTED;
+import static com.android.internal.util.FrameworkStatsLog.PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD;
+import static com.android.internal.util.FrameworkStatsLog.PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
 import static com.android.server.am.ActivityManagerService.TAG_MU;
 import static com.android.server.am.ProcessProfileRecord.HOSTING_COMPONENT_TYPE_PROVIDER;
@@ -73,6 +76,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.LocalServices;
 import com.android.server.RescueParty;
 import com.android.server.pm.UserManagerInternal;
@@ -241,6 +245,10 @@
                     ContentProviderHolder holder = cpr.newHolder(null, true);
                     // don't give caller the provider object, it needs to make its own.
                     holder.provider = null;
+                    FrameworkStatsLog.write(
+                            PROVIDER_ACQUISITION_EVENT_REPORTED,
+                            r.uid, callingUid,
+                            PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM);
                     return holder;
                 }
 
@@ -307,6 +315,10 @@
                         dyingProc = cpr.proc;
                     } else {
                         cpr.proc.mState.setVerifiedAdj(cpr.proc.mState.getSetAdj());
+                        FrameworkStatsLog.write(
+                                PROVIDER_ACQUISITION_EVENT_REPORTED,
+                                cpr.proc.uid, callingUid,
+                                PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM);
                     }
                 } finally {
                     Binder.restoreCallingIdentity(origId);
@@ -479,6 +491,10 @@
                                 } catch (RemoteException e) {
                                 }
                             }
+                            FrameworkStatsLog.write(
+                                    PROVIDER_ACQUISITION_EVENT_REPORTED,
+                                    proc.uid, callingUid,
+                                    PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM);
                         } else {
                             checkTime(startTime, "getContentProviderImpl: before start process");
                             proc = mService.startProcessLocked(
@@ -495,6 +511,10 @@
                                         + ": process is bad");
                                 return null;
                             }
+                            FrameworkStatsLog.write(
+                                    PROVIDER_ACQUISITION_EVENT_REPORTED,
+                                    proc.uid, callingUid,
+                                    PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD);
                         }
                         cpr.launchingApp = proc;
                         mLaunchingProviders.add(cpr);
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index e7fcc59..a61cbbf 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1554,14 +1554,22 @@
 
         boolean foregroundActivities = false;
         boolean hasVisibleActivities = false;
-        if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) {
+        if (app == topApp && (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP
+                || PROCESS_STATE_CUR_TOP == PROCESS_STATE_IMPORTANT_FOREGROUND)) {
             // The last app on the list is the foreground app.
             adj = ProcessList.FOREGROUND_APP_ADJ;
-            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
-            state.setAdjType("top-activity");
+            if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP) {
+                schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
+                state.setAdjType("top-activity");
+            } else {
+                // Demote the scheduling group to avoid CPU contention if there is another more
+                // important process which also uses top-app, such as if SystemUI is animating.
+                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+                state.setAdjType("intermediate-top-activity");
+            }
             foregroundActivities = true;
             hasVisibleActivities = true;
-            procState = PROCESS_STATE_CUR_TOP;
+            procState = PROCESS_STATE_TOP;
             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
             }
diff --git a/services/core/java/com/android/server/am/PendingStartActivityUids.java b/services/core/java/com/android/server/am/PendingStartActivityUids.java
index bd60057..da09317 100644
--- a/services/core/java/com/android/server/am/PendingStartActivityUids.java
+++ b/services/core/java/com/android/server/am/PendingStartActivityUids.java
@@ -16,7 +16,6 @@
 
 package com.android.server.am;
 
-import android.content.Context;
 import android.os.SystemClock;
 import android.util.Pair;
 import android.util.Slog;
@@ -40,11 +39,6 @@
     // Key is uid, value is Pair of pid and SystemClock.elapsedRealtime() when the
     // uid is added.
     private final SparseArray<Pair<Integer, Long>> mPendingUids = new SparseArray();
-    private Context mContext;
-
-    PendingStartActivityUids(Context context) {
-        mContext = context;
-    }
 
     /** Returns {@code true} if the uid is put to the pending array. Otherwise it existed. */
     synchronized boolean add(int uid, int pid) {
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 3a78974..dd73cbe 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -60,6 +60,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
@@ -68,6 +69,7 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
+import android.os.FileUtils;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -77,9 +79,12 @@
 import android.os.ResultReceiver;
 import android.os.ServiceManager;
 import android.os.ShellCallback;
+import android.os.UserManager;
 import android.provider.DeviceConfig;
 import android.provider.DeviceConfig.Properties;
+import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.AtomicFile;
 import android.util.AttributeSet;
 import android.util.KeyValueListParser;
 import android.util.Slog;
@@ -90,6 +95,7 @@
 import com.android.internal.compat.CompatibilityOverrideConfig;
 import com.android.internal.compat.IPlatformCompat;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
@@ -99,9 +105,17 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.BufferedWriter;
+import java.io.File;
 import java.io.FileDescriptor;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 
 /**
@@ -122,6 +136,7 @@
     static final int POPULATE_GAME_MODE_SETTINGS = 3;
     static final int SET_GAME_STATE = 4;
     static final int CANCEL_GAME_LOADING_MODE = 5;
+    static final int WRITE_GAME_MODE_INTERVENTION_LIST_FILE = 6;
     static final int WRITE_SETTINGS_DELAY = 10 * 1000;  // 10 seconds
     static final int LOADING_BOOST_MAX_DURATION = 5 * 1000;  // 5 seconds
 
@@ -131,6 +146,8 @@
             .build();
     private static final String PACKAGE_NAME_MSG_KEY = "packageName";
     private static final String USER_ID_MSG_KEY = "userId";
+    private static final String GAME_MODE_INTERVENTION_LIST_FILE_NAME =
+            "game_mode_intervention.list";
 
     private final Context mContext;
     private final Object mLock = new Object();
@@ -138,8 +155,12 @@
     private final Object mOverrideConfigLock = new Object();
     private final Handler mHandler;
     private final PackageManager mPackageManager;
+    private final UserManager mUserManager;
     private final IPlatformCompat mPlatformCompat;
     private final PowerManagerInternal mPowerManagerInternal;
+    private final File mSystemDir;
+    @VisibleForTesting
+    final AtomicFile mGameModeInterventionListFile;
     private DeviceConfigListener mDeviceConfigListener;
     @GuardedBy("mLock")
     private final ArrayMap<Integer, GameManagerSettings> mSettings = new ArrayMap<>();
@@ -158,9 +179,53 @@
         mContext = context;
         mHandler = new SettingsHandler(looper);
         mPackageManager = mContext.getPackageManager();
+        mUserManager = mContext.getSystemService(UserManager.class);
         mPlatformCompat = IPlatformCompat.Stub.asInterface(
                 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
+        mSystemDir = new File(Environment.getDataDirectory(), "system");
+        mSystemDir.mkdirs();
+        FileUtils.setPermissions(mSystemDir.toString(),
+                FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH,
+                -1, -1);
+        mGameModeInterventionListFile = new AtomicFile(new File(mSystemDir,
+                                                     GAME_MODE_INTERVENTION_LIST_FILE_NAME));
+        FileUtils.setPermissions(mGameModeInterventionListFile.getBaseFile().getAbsolutePath(),
+                FileUtils.S_IRUSR | FileUtils.S_IWUSR
+                        | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+                -1, -1);
+        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_GAME_SERVICE)) {
+            mGameServiceController = new GameServiceController(
+                    context, BackgroundThread.getExecutor(),
+                    new GameServiceProviderSelectorImpl(
+                            context.getResources(),
+                            context.getPackageManager()),
+                    new GameServiceProviderInstanceFactoryImpl(context));
+        } else {
+            mGameServiceController = null;
+        }
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    GameManagerService(Context context, Looper looper, File dataDir) {
+        mContext = context;
+        mHandler = new SettingsHandler(looper);
+        mPackageManager = mContext.getPackageManager();
+        mUserManager = mContext.getSystemService(UserManager.class);
+        mPlatformCompat = IPlatformCompat.Stub.asInterface(
+                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+        mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
+        mSystemDir = new File(dataDir, "system");
+        mSystemDir.mkdirs();
+        FileUtils.setPermissions(mSystemDir.toString(),
+                FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH,
+                -1, -1);
+        mGameModeInterventionListFile = new AtomicFile(new File(mSystemDir,
+                GAME_MODE_INTERVENTION_LIST_FILE_NAME));
+        FileUtils.setPermissions(mGameModeInterventionListFile.getBaseFile().getAbsolutePath(),
+                FileUtils.S_IRUSR | FileUtils.S_IWUSR
+                        | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+                -1, -1);
         if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_GAME_SERVICE)) {
             mGameServiceController = new GameServiceController(
                     context, BackgroundThread.getExecutor(),
@@ -306,6 +371,22 @@
                     mPowerManagerInternal.setPowerMode(Mode.GAME_LOADING, false);
                     break;
                 }
+                case WRITE_GAME_MODE_INTERVENTION_LIST_FILE: {
+                    final int userId = (int) msg.obj;
+                    if (userId < 0) {
+                        Slog.wtf(TAG, "Attempt to write setting for invalid user: " + userId);
+                        synchronized (mLock) {
+                            removeMessages(WRITE_GAME_MODE_INTERVENTION_LIST_FILE, null);
+                        }
+                        break;
+                    }
+
+                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
+                    removeMessages(WRITE_GAME_MODE_INTERVENTION_LIST_FILE, null);
+                    writeGameModeInterventionsToFile(userId);
+                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+                    break;
+                }
             }
         }
     }
@@ -955,6 +1036,11 @@
             }
         }
         updateInterventions(packageName, gameMode, userId);
+        final Message msg = mHandler.obtainMessage(WRITE_GAME_MODE_INTERVENTION_LIST_FILE);
+        msg.obj = userId;
+        if (!mHandler.hasEqualMessages(WRITE_GAME_MODE_INTERVENTION_LIST_FILE, userId)) {
+            mHandler.sendMessage(msg);
+        }
     }
 
     /**
@@ -1520,15 +1606,98 @@
                 final int newGameMode = getNewGameMode(gameMode, config);
                 if (newGameMode != gameMode) {
                     setGameMode(packageName, newGameMode, userId);
+                } else {
+                    // Make sure we handle the case when the interventions are changed while
+                    // the game mode remains the same. We call only updateInterventions() here.
+                    updateInterventions(packageName, gameMode, userId);
                 }
-                updateInterventions(packageName, gameMode, userId);
             }
         } catch (Exception e) {
             Slog.e(TAG, "Failed to update compat modes for user " + userId + ": " + e);
         }
+
+        final Message msg = mHandler.obtainMessage(WRITE_GAME_MODE_INTERVENTION_LIST_FILE);
+        msg.obj = userId;
+        if (!mHandler.hasEqualMessages(WRITE_GAME_MODE_INTERVENTION_LIST_FILE, userId)) {
+            mHandler.sendMessage(msg);
+        }
     }
 
-    private String[] getInstalledGamePackageNames(int userId) {
+    /*
+     Write the interventions and mode of each game to file /system/data/game_mode_intervention.list
+     Each line will contain the information of each game, separated by tab.
+     The format of the output is:
+     <package name> <UID> <current mode> <game mode 1> <interventions> <game mode 2> <interventions>
+     For example:
+     com.android.app1   1425    1   2   angle=0,scaling=1.0,fps=60  3   angle=1,scaling=0.5,fps=30
+     */
+    private void writeGameModeInterventionsToFile(@UserIdInt int userId) {
+        FileOutputStream fileOutputStream = null;
+        BufferedWriter bufferedWriter;
+        try {
+            fileOutputStream = mGameModeInterventionListFile.startWrite();
+            bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream,
+                    Charset.defaultCharset()));
+
+            final StringBuilder sb = new StringBuilder();
+            final List<String> installedGamesList = getInstalledGamePackageNamesByAllUsers(userId);
+            for (final String packageName : installedGamesList) {
+                GamePackageConfiguration packageConfig = getConfig(packageName);
+                if (packageConfig == null) {
+                    continue;
+                }
+                sb.append(packageName);
+                sb.append("\t");
+                sb.append(mPackageManager.getPackageUidAsUser(packageName, userId));
+                sb.append("\t");
+                sb.append(getGameMode(packageName, userId));
+                sb.append("\t");
+                final int[] modes = packageConfig.getAvailableGameModes();
+                for (int mode : modes) {
+                    final GamePackageConfiguration.GameModeConfiguration gameModeConfiguration =
+                            packageConfig.getGameModeConfiguration(mode);
+                    if (gameModeConfiguration == null) {
+                        continue;
+                    }
+                    sb.append(mode);
+                    sb.append("\t");
+                    final int useAngle = gameModeConfiguration.getUseAngle() ? 1 : 0;
+                    sb.append(TextUtils.formatSimple("angle=%d", useAngle));
+                    sb.append(",");
+                    final String scaling = gameModeConfiguration.getScaling();
+                    sb.append("scaling=");
+                    sb.append(scaling);
+                    sb.append(",");
+                    final int fps = gameModeConfiguration.getFps();
+                    sb.append(TextUtils.formatSimple("fps=%d", fps));
+                    sb.append("\t");
+                }
+                sb.append("\n");
+            }
+            bufferedWriter.append(sb);
+            bufferedWriter.flush();
+            FileUtils.sync(fileOutputStream);
+            mGameModeInterventionListFile.finishWrite(fileOutputStream);
+        } catch (Exception e) {
+            mGameModeInterventionListFile.failWrite(fileOutputStream);
+            Slog.wtf(TAG, "Failed to write game_mode_intervention.list, exception " + e);
+        }
+        return;
+    }
+
+    private int[] getAllUserIds(@UserIdInt int currentUserId) {
+        final List<UserInfo> users = mUserManager.getUsers();
+        int[] userIds = new int[users.size()];
+        for (int i = 0; i < userIds.length; ++i) {
+            userIds[i] = users.get(i).id;
+        }
+        if (currentUserId != -1) {
+            userIds = ArrayUtils.appendInt(userIds, currentUserId);
+        }
+        return userIds;
+    }
+
+    private String[] getInstalledGamePackageNames(@UserIdInt int userId) {
         final List<PackageInfo> packages =
                 mPackageManager.getInstalledPackagesAsUser(0, userId);
         return packages.stream().filter(e -> e.applicationInfo != null && e.applicationInfo.category
@@ -1537,6 +1706,17 @@
                 .toArray(String[]::new);
     }
 
+    private List<String> getInstalledGamePackageNamesByAllUsers(@UserIdInt int currentUserId) {
+        HashSet<String> packageSet = new HashSet<>();
+
+        final int[] userIds = getAllUserIds(currentUserId);
+        for (int userId : userIds) {
+            packageSet.addAll(Arrays.asList(getInstalledGamePackageNames(userId)));
+        }
+
+        return new ArrayList<>(packageSet);
+    }
+
     /**
      * @hide
      */
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 02648c4..43d77ab 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -275,6 +275,25 @@
     // indicates whether the system maps all streams to a single stream.
     private final boolean mIsSingleVolume;
 
+    /**
+     * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING
+     *     not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}.
+     */
+    private boolean mNotifAliasRing;
+
+    /**
+     * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING,
+     * volumes will be updated in case of a change.
+     * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING
+     */
+    /*package*/ void setNotifAliasRingForTest(boolean alias) {
+        boolean update = (mNotifAliasRing != alias);
+        mNotifAliasRing = alias;
+        if (update) {
+            updateStreamVolumeAlias(true, "AudioServiceTest");
+        }
+    }
+
     /*package*/ boolean isPlatformVoice() {
         return mPlatformType == AudioSystem.PLATFORM_VOICE;
     }
@@ -942,10 +961,25 @@
      */
     public AudioService(Context context, AudioSystemAdapter audioSystem,
             SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper) {
+        this (context, audioSystem, systemServer, settings, looper,
+                context.getSystemService(AppOpsManager.class));
+    }
+
+    /**
+     * @param context
+     * @param audioSystem Adapter for {@link AudioSystem}
+     * @param systemServer Adapter for privilieged functionality for system server components
+     * @param settings Adapter for {@link Settings}
+     * @param looper Looper to use for the service's message handler. If this is null, an
+     *               {@link AudioSystemThread} is created as the messaging thread instead.
+     */
+    public AudioService(Context context, AudioSystemAdapter audioSystem,
+            SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper,
+            AppOpsManager appOps) {
         sLifecycleLogger.log(new AudioEventLogger.StringEvent("AudioService()"));
         mContext = context;
         mContentResolver = context.getContentResolver();
-        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
+        mAppOps = appOps;
 
         mAudioSystem = audioSystem;
         mSystemServer = systemServer;
@@ -976,6 +1010,9 @@
         mUseVolumeGroupAliases = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups);
 
+        mNotifAliasRing = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_alias_ring_notif_stream_types);
+
         // Initialize volume
         // Priority 1 - Android Property
         // Priority 2 - Audio Policy Service
@@ -2008,7 +2045,13 @@
         pw.println("\nStream volumes (device: index)");
         int numStreamTypes = AudioSystem.getNumStreamTypes();
         for (int i = 0; i < numStreamTypes; i++) {
-            pw.println("- " + AudioSystem.STREAM_NAMES[i] + ":");
+            StringBuilder alias = new StringBuilder();
+            if (mStreamVolumeAlias[i] != i) {
+                alias.append(" (aliased to: ")
+                        .append(AudioSystem.STREAM_NAMES[mStreamVolumeAlias[i]])
+                        .append(")");
+            }
+            pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":");
             mStreamStates[i].dump(pw);
             pw.println("");
         }
@@ -2040,6 +2083,10 @@
                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT;
                     dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
             }
+            if (!mNotifAliasRing) {
+                mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] =
+                        AudioSystem.STREAM_NOTIFICATION;
+            }
         }
 
         if (mIsSingleVolume) {
@@ -9888,6 +9935,7 @@
         pw.print("  mBtScoOnByApp="); pw.println(mBtScoOnByApp);
         pw.print("  mIsSingleVolume="); pw.println(mIsSingleVolume);
         pw.print("  mUseFixedVolume="); pw.println(mUseFixedVolume);
+        pw.print("  mNotifAliasRing="); pw.println(mNotifAliasRing);
         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
         pw.print("  mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
         pw.print("  mAbsoluteVolumeDevices.keySet()="); pw.println(dumpDeviceTypes(
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 5b26672..dd44af1 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -280,18 +280,13 @@
             }
             // for both transaural / binaural, we are not forcing enablement as the init() method
             // could have been called another time after boot in case of audioserver restart
-            if (mTransauralSupported) {
-                // not force-enabling as this device might already be in the device list
-                addCompatibleAudioDevice(
-                        new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""),
-                                false /*forceEnable*/);
-            }
-            if (mBinauralSupported) {
-                // not force-enabling as this device might already be in the device list
-                addCompatibleAudioDevice(
-                        new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, ""),
-                                false /*forceEnable*/);
-            }
+            addCompatibleAudioDevice(
+                    new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""),
+                            false /*forceEnable*/);
+            // not force-enabling as this device might already be in the device list
+            addCompatibleAudioDevice(
+                    new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, ""),
+                            false /*forceEnable*/);
         } catch (RemoteException e) {
             resetCapabilities();
         } finally {
@@ -497,10 +492,9 @@
     synchronized @NonNull List<AudioDeviceAttributes> getCompatibleAudioDevices() {
         // build unionOf(mCompatibleAudioDevices, mEnabledDevice) - mDisabledAudioDevices
         ArrayList<AudioDeviceAttributes> compatList = new ArrayList<>();
-        for (SADeviceState dev : mSADevices) {
-            if (dev.mEnabled) {
-                compatList.add(new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
-                        dev.mDeviceType, dev.mDeviceAddress == null ? "" : dev.mDeviceAddress));
+        for (SADeviceState deviceState : mSADevices) {
+            if (deviceState.mEnabled) {
+                compatList.add(deviceState.getAudioDeviceAttributes());
             }
         }
         return compatList;
@@ -521,15 +515,15 @@
      */
     private void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada,
             boolean forceEnable) {
+        if (!isDeviceCompatibleWithSpatializationModes(ada)) {
+            return;
+        }
         loglogi("addCompatibleAudioDevice: dev=" + ada);
-        final int deviceType = ada.getType();
-        final boolean wireless = isWireless(deviceType);
         boolean isInList = false;
         SADeviceState deviceUpdated = null; // non-null on update.
 
         for (SADeviceState deviceState : mSADevices) {
-            if (deviceType == deviceState.mDeviceType
-                    && (!wireless || ada.getAddress().equals(deviceState.mDeviceAddress))) {
+            if (deviceState.matchesAudioDeviceAttributes(ada)) {
                 isInList = true;
                 if (forceEnable) {
                     deviceState.mEnabled = true;
@@ -539,11 +533,10 @@
             }
         }
         if (!isInList) {
-            final SADeviceState dev = new SADeviceState(deviceType,
-                    wireless ? ada.getAddress() : "");
-            dev.mEnabled = true;
-            mSADevices.add(dev);
-            deviceUpdated = dev;
+            final SADeviceState deviceState = new SADeviceState(ada.getType(), ada.getAddress());
+            deviceState.mEnabled = true;
+            mSADevices.add(deviceState);
+            deviceUpdated = deviceState;
         }
         if (deviceUpdated != null) {
             onRoutingUpdated();
@@ -574,13 +567,10 @@
 
     synchronized void removeCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
         loglogi("removeCompatibleAudioDevice: dev=" + ada);
-        final int deviceType = ada.getType();
-        final boolean wireless = isWireless(deviceType);
         SADeviceState deviceUpdated = null; // non-null on update.
 
         for (SADeviceState deviceState : mSADevices) {
-            if (deviceType == deviceState.mDeviceType
-                    && (!wireless || ada.getAddress().equals(deviceState.mDeviceAddress))) {
+            if (deviceState.matchesAudioDeviceAttributes(ada)) {
                 deviceState.mEnabled = false;
                 deviceUpdated = deviceState;
                 break;
@@ -602,10 +592,9 @@
         // if not a wireless device, this value will be overwritten to map the type
         // to TYPE_BUILTIN_SPEAKER or TYPE_WIRED_HEADPHONES
         @AudioDeviceInfo.AudioDeviceType int deviceType = ada.getType();
-        final boolean wireless = isWireless(deviceType);
 
         // if not a wireless device: find if media device is in the speaker, wired headphones
-        if (!wireless) {
+        if (!isWireless(deviceType)) {
             // is the device type capable of doing SA?
             if (!mSACapableDeviceTypes.contains(deviceType)) {
                 Log.i(TAG, "Device incompatible with Spatial Audio dev:" + ada);
@@ -640,9 +629,7 @@
         boolean enabled = false;
         boolean available = false;
         for (SADeviceState deviceState : mSADevices) {
-            if (deviceType == deviceState.mDeviceType
-                    && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
-                    || !wireless) {
+            if (deviceState.matchesAudioDeviceAttributes(ada)) {
                 available = true;
                 enabled = deviceState.mEnabled;
                 break;
@@ -652,11 +639,12 @@
     }
 
     private synchronized void addWirelessDeviceIfNew(@NonNull AudioDeviceAttributes ada) {
+        if (!isDeviceCompatibleWithSpatializationModes(ada)) {
+            return;
+        }
         boolean knownDevice = false;
         for (SADeviceState deviceState : mSADevices) {
-            // wireless device so always check address
-            if (ada.getType() == deviceState.mDeviceType
-                    && ada.getAddress().equals(deviceState.mDeviceAddress)) {
+            if (deviceState.matchesAudioDeviceAttributes(ada)) {
                 knownDevice = true;
                 break;
             }
@@ -704,13 +692,8 @@
         if (ada.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) {
             return false;
         }
-
-        final int deviceType = ada.getType();
-        final boolean wireless = isWireless(deviceType);
         for (SADeviceState deviceState : mSADevices) {
-            if (deviceType == deviceState.mDeviceType
-                    && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
-                    || !wireless) {
+            if (deviceState.matchesAudioDeviceAttributes(ada)) {
                 return true;
             }
         }
@@ -719,12 +702,19 @@
 
     private synchronized boolean canBeSpatializedOnDevice(@NonNull AudioAttributes attributes,
             @NonNull AudioFormat format, @NonNull AudioDeviceAttributes[] devices) {
-        final byte modeForDevice = (byte) SPAT_MODE_FOR_DEVICE_TYPE.get(devices[0].getType(),
+        if (isDeviceCompatibleWithSpatializationModes(devices[0])) {
+            return AudioSystem.canBeSpatialized(attributes, format, devices);
+        }
+        return false;
+    }
+
+    private boolean isDeviceCompatibleWithSpatializationModes(@NonNull AudioDeviceAttributes ada) {
+        final byte modeForDevice = (byte) SPAT_MODE_FOR_DEVICE_TYPE.get(ada.getType(),
                 /*default when type not found*/ SpatializationMode.SPATIALIZER_BINAURAL);
         if ((modeForDevice == SpatializationMode.SPATIALIZER_BINAURAL && mBinauralSupported)
                 || (modeForDevice == SpatializationMode.SPATIALIZER_TRANSAURAL
                         && mTransauralSupported)) {
-            return AudioSystem.canBeSpatialized(attributes, format, devices);
+            return true;
         }
         return false;
     }
@@ -1089,13 +1079,8 @@
             Log.v(TAG, "no headtracking support, ignoring setHeadTrackerEnabled to " + enabled
                     + " for " + ada);
         }
-        final int deviceType = ada.getType();
-        final boolean wireless = isWireless(deviceType);
-
         for (SADeviceState deviceState : mSADevices) {
-            if (deviceType == deviceState.mDeviceType
-                    && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
-                    || !wireless) {
+            if (deviceState.matchesAudioDeviceAttributes(ada)) {
                 if (!deviceState.mHasHeadTracker) {
                     Log.e(TAG, "Called setHeadTrackerEnabled enabled:" + enabled
                             + " device:" + ada + " on a device without headtracker");
@@ -1109,7 +1094,7 @@
             }
         }
         // check current routing to see if it affects the headtracking mode
-        if (ROUTING_DEVICES[0].getType() == deviceType
+        if (ROUTING_DEVICES[0].getType() == ada.getType()
                 && ROUTING_DEVICES[0].getAddress().equals(ada.getAddress())) {
             setDesiredHeadTrackingMode(enabled ? mDesiredHeadTrackingModeWhenEnabled
                     : Spatializer.HEAD_TRACKING_MODE_DISABLED);
@@ -1121,13 +1106,8 @@
             Log.v(TAG, "no headtracking support, hasHeadTracker always false for " + ada);
             return false;
         }
-        final int deviceType = ada.getType();
-        final boolean wireless = isWireless(deviceType);
-
         for (SADeviceState deviceState : mSADevices) {
-            if (deviceType == deviceState.mDeviceType
-                    && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
-                    || !wireless) {
+            if (deviceState.matchesAudioDeviceAttributes(ada)) {
                 return deviceState.mHasHeadTracker;
             }
         }
@@ -1144,13 +1124,8 @@
             Log.v(TAG, "no headtracking support, setHasHeadTracker always false for " + ada);
             return false;
         }
-        final int deviceType = ada.getType();
-        final boolean wireless = isWireless(deviceType);
-
         for (SADeviceState deviceState : mSADevices) {
-            if (deviceType == deviceState.mDeviceType
-                    && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
-                    || !wireless) {
+            if (deviceState.matchesAudioDeviceAttributes(ada)) {
                 if (!deviceState.mHasHeadTracker) {
                     deviceState.mHasHeadTracker = true;
                     mAudioService.persistSpatialAudioDeviceSettings();
@@ -1168,13 +1143,8 @@
             Log.v(TAG, "no headtracking support, isHeadTrackerEnabled always false for " + ada);
             return false;
         }
-        final int deviceType = ada.getType();
-        final boolean wireless = isWireless(deviceType);
-
         for (SADeviceState deviceState : mSADevices) {
-            if (deviceType == deviceState.mDeviceType
-                    && (wireless && ada.getAddress().equals(deviceState.mDeviceAddress))
-                    || !wireless) {
+            if (deviceState.matchesAudioDeviceAttributes(ada)) {
                 if (!deviceState.mHasHeadTracker) {
                     return false;
                 }
@@ -1531,7 +1501,7 @@
 
         SADeviceState(@AudioDeviceInfo.AudioDeviceType int deviceType, @NonNull String address) {
             mDeviceType = deviceType;
-            mDeviceAddress = Objects.requireNonNull(address);
+            mDeviceAddress = isWireless(deviceType) ? Objects.requireNonNull(address) : "";
         }
 
         @Override
@@ -1599,6 +1569,18 @@
                 return null;
             }
         }
+
+        public AudioDeviceAttributes getAudioDeviceAttributes() {
+            return new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
+                    mDeviceType, mDeviceAddress == null ? "" : mDeviceAddress);
+        }
+
+        public boolean matchesAudioDeviceAttributes(AudioDeviceAttributes ada) {
+            final int deviceType = ada.getType();
+            final boolean wireless = isWireless(deviceType);
+            return (deviceType == mDeviceType)
+                        && (!wireless || ada.getAddress().equals(mDeviceAddress));
+        }
     }
 
     /*package*/ synchronized String getSADeviceSettings() {
@@ -1619,7 +1601,9 @@
         // small list, not worth overhead of Arrays.stream(devSettings)
         for (String setting : devSettings) {
             SADeviceState devState = SADeviceState.fromPersistedString(setting);
-            if (devState != null) {
+            if (devState != null
+                    && isDeviceCompatibleWithSpatializationModes(
+                            devState.getAudioDeviceAttributes())) {
                 mSADevices.add(devState);
                 logDeviceState(devState, "setSADeviceSettings");
             }
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 77d3392..f526960 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -86,6 +86,8 @@
 import android.net.ipsec.ike.ChildSessionParams;
 import android.net.ipsec.ike.IkeSession;
 import android.net.ipsec.ike.IkeSessionCallback;
+import android.net.ipsec.ike.IkeSessionConfiguration;
+import android.net.ipsec.ike.IkeSessionConnectionInfo;
 import android.net.ipsec.ike.IkeSessionParams;
 import android.net.ipsec.ike.IkeTunnelConnectionParams;
 import android.net.ipsec.ike.exceptions.IkeNetworkLostException;
@@ -168,9 +170,10 @@
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -190,11 +193,19 @@
     private static final long VPN_LAUNCH_IDLE_ALLOWLIST_DURATION_MS = 60 * 1000;
 
     // Length of time (in milliseconds) that an app registered for VpnManager events is placed on
-    // the device idle allowlist each time the a VpnManager event is fired.
+    // the device idle allowlist each time the VpnManager event is fired.
     private static final long VPN_MANAGER_EVENT_ALLOWLIST_DURATION_MS = 30 * 1000;
 
     private static final String LOCKDOWN_ALLOWLIST_SETTING_NAME =
             Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST;
+
+    /**
+     * The retries for consecutive failures.
+     *
+     * <p>If retries have exceeded the length of this array, the last entry in the array will be
+     * used as a repeating interval.
+     */
+    private static final long[] IKEV2_VPN_RETRY_DELAYS_SEC = {1L, 2L, 5L, 30L, 60L, 300L, 900L};
     /**
      * Largest profile size allowable for Platform VPNs.
      *
@@ -473,6 +484,20 @@
                         "Cannot set tunnel's fd as blocking=" + blocking, e);
             }
         }
+
+        /**
+         * Retrieves the next retry delay
+         *
+         * <p>If retries have exceeded the IKEV2_VPN_RETRY_DELAYS_SEC, the last entry in
+         * the array will be used as a repeating interval.
+         */
+        public long getNextRetryDelaySeconds(int retryCount) {
+            if (retryCount >= IKEV2_VPN_RETRY_DELAYS_SEC.length) {
+                return IKEV2_VPN_RETRY_DELAYS_SEC[IKEV2_VPN_RETRY_DELAYS_SEC.length - 1];
+            } else {
+                return IKEV2_VPN_RETRY_DELAYS_SEC[retryCount];
+            }
+        }
     }
 
     public Vpn(Looper looper, Context context, INetworkManagementService netService, INetd netd,
@@ -2605,13 +2630,23 @@
 
         void onDefaultNetworkLinkPropertiesChanged(@NonNull LinkProperties lp);
 
-        void onChildOpened(
-                @NonNull Network network, @NonNull ChildSessionConfiguration childConfig);
+        void onDefaultNetworkLost(@NonNull Network network);
 
-        void onChildTransformCreated(
-                @NonNull Network network, @NonNull IpSecTransform transform, int direction);
+        void onIkeOpened(int token, @NonNull IkeSessionConfiguration ikeConfiguration);
 
-        void onSessionLost(@NonNull Network network, @Nullable Exception exception);
+        void onIkeConnectionInfoChanged(
+                int token, @NonNull IkeSessionConnectionInfo ikeConnectionInfo);
+
+        void onChildOpened(int token, @NonNull ChildSessionConfiguration childConfig);
+
+        void onChildTransformCreated(int token, @NonNull IpSecTransform transform, int direction);
+
+        void onChildMigrated(
+                int token,
+                @NonNull IpSecTransform inTransform,
+                @NonNull IpSecTransform outTransform);
+
+        void onSessionLost(int token, @Nullable Exception exception);
     }
 
     /**
@@ -2642,6 +2677,10 @@
     class IkeV2VpnRunner extends VpnRunner implements IkeV2VpnRunnerCallback {
         @NonNull private static final String TAG = "IkeV2VpnRunner";
 
+        // 5 seconds grace period before tearing down the IKE Session in case new default network
+        // will come up
+        private static final long NETWORK_LOST_TIMEOUT_MS = 5000L;
+
         @NonNull private final IpSecManager mIpSecManager;
         @NonNull private final Ikev2VpnProfile mProfile;
         @NonNull private final ConnectivityManager.NetworkCallback mNetworkCallback;
@@ -2653,24 +2692,60 @@
          * of the mutable Ikev2VpnRunner fields. The Ikev2VpnRunner is built mostly lock-free by
          * virtue of everything being serialized on this executor.
          */
-        @NonNull private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
+        @NonNull
+        private final ScheduledThreadPoolExecutor mExecutor = new ScheduledThreadPoolExecutor(1);
+
+        @Nullable private ScheduledFuture<?> mScheduledHandleNetworkLostTimeout;
+        @Nullable private ScheduledFuture<?> mScheduledHandleRetryIkeSessionTimeout;
 
         /** Signal to ensure shutdown is honored even if a new Network is connected. */
         private boolean mIsRunning = true;
 
+        /**
+         * The token used by the primary/current/active IKE session.
+         *
+         * <p>This token MUST be updated when the VPN switches to use a new IKE session.
+         */
+        private int mCurrentToken = -1;
+
         @Nullable private IpSecTunnelInterface mTunnelIface;
-        @Nullable private IkeSession mSession;
         @Nullable private Network mActiveNetwork;
         @Nullable private NetworkCapabilities mUnderlyingNetworkCapabilities;
         @Nullable private LinkProperties mUnderlyingLinkProperties;
         private final String mSessionKey;
 
+        @Nullable private IkeSession mSession;
+        @Nullable private IkeSessionConnectionInfo mIkeConnectionInfo;
+
+        // mMobikeEnabled can only be updated after IKE AUTH is finished.
+        private boolean mMobikeEnabled = false;
+
+        /**
+         * The number of attempts since the last successful connection.
+         *
+         * <p>This variable controls the retry delay, and is reset when a new IKE session is
+         * opened or when there is a new default network.
+         */
+        private int mRetryCount = 0;
+
         IkeV2VpnRunner(@NonNull Ikev2VpnProfile profile) {
             super(TAG);
             mProfile = profile;
             mIpSecManager = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
             mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this, mExecutor);
             mSessionKey = UUID.randomUUID().toString();
+
+            // Set the policy so that cancelled tasks will be removed from the work queue
+            mExecutor.setRemoveOnCancelPolicy(true);
+
+            // Set the policy so that all delayed tasks will not be executed
+            mExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+
+            // To avoid hitting RejectedExecutionException upon shutdown of the mExecutor */
+            mExecutor.setRejectedExecutionHandler(
+                    (r, executor) -> {
+                        Log.d(TAG, "Runnable " + r + " rejected by the mExecutor");
+                    });
         }
 
         @Override
@@ -2709,22 +2784,64 @@
             return Objects.equals(mActiveNetwork, network) && mIsRunning;
         }
 
+        private boolean isActiveToken(int token) {
+            return (mCurrentToken == token) && mIsRunning;
+        }
+
+        /**
+         * Called when an IKE session has been opened
+         *
+         * <p>This method is only ever called once per IkeSession, and MUST run on the mExecutor
+         * thread in order to ensure consistency of the Ikev2VpnRunner fields.
+         */
+        public void onIkeOpened(int token, @NonNull IkeSessionConfiguration ikeConfiguration) {
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "onIkeOpened called for obsolete token " + token);
+                return;
+            }
+
+            mMobikeEnabled =
+                    ikeConfiguration.isIkeExtensionEnabled(
+                            IkeSessionConfiguration.EXTENSION_TYPE_MOBIKE);
+            onIkeConnectionInfoChanged(token, ikeConfiguration.getIkeSessionConnectionInfo());
+            mRetryCount = 0;
+        }
+
+        /**
+         * Called when an IKE session's {@link IkeSessionConnectionInfo} is available or updated
+         *
+         * <p>This callback is usually fired when an IKE session has been opened or migrated.
+         *
+         * <p>This method is called multiple times over the lifetime of an IkeSession, and MUST run
+         * on the mExecutor thread in order to ensure consistency of the Ikev2VpnRunner fields.
+         */
+        public void onIkeConnectionInfoChanged(
+                int token, @NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "onIkeConnectionInfoChanged called for obsolete token " + token);
+                return;
+            }
+
+            // The update on VPN and the IPsec tunnel will be done when migration is fully complete
+            // in onChildMigrated
+            mIkeConnectionInfo = ikeConnectionInfo;
+        }
+
         /**
          * Called when an IKE Child session has been opened, signalling completion of the startup.
          *
          * <p>This method is only ever called once per IkeSession, and MUST run on the mExecutor
          * thread in order to ensure consistency of the Ikev2VpnRunner fields.
          */
-        public void onChildOpened(
-                @NonNull Network network, @NonNull ChildSessionConfiguration childConfig) {
-            if (!isActiveNetwork(network)) {
-                Log.d(TAG, "onOpened called for obsolete network " + network);
+        public void onChildOpened(int token, @NonNull ChildSessionConfiguration childConfig) {
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "onChildOpened called for obsolete token " + token);
 
                 // Do nothing; this signals that either: (1) a new/better Network was found,
-                // and the Ikev2VpnRunner has switched to it in onDefaultNetworkChanged, or (2) this
-                // IKE session was already shut down (exited, or an error was encountered somewhere
-                // else). In both cases, all resources and sessions are torn down via
-                // resetIkeState().
+                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
+                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
+                // or an error was encountered somewhere else). In both cases, all resources and
+                // sessions are torn down via resetIkeState().
                 return;
             }
 
@@ -2743,6 +2860,11 @@
                     dnsAddrStrings.add(addr.getHostAddress());
                 }
 
+                // The actual network of this IKE session has been set up with is
+                // mIkeConnectionInfo.getNetwork() instead of mActiveNetwork because
+                // mActiveNetwork might have been updated after the setup was triggered.
+                final Network network = mIkeConnectionInfo.getNetwork();
+
                 final NetworkAgent networkAgent;
                 final LinkProperties lp;
 
@@ -2785,8 +2907,8 @@
 
                 networkAgent.sendLinkProperties(lp);
             } catch (Exception e) {
-                Log.d(TAG, "Error in ChildOpened for network " + network, e);
-                onSessionLost(network, e);
+                Log.d(TAG, "Error in ChildOpened for token " + token, e);
+                onSessionLost(token, e);
             }
         }
 
@@ -2794,19 +2916,19 @@
          * Called when an IPsec transform has been created, and should be applied.
          *
          * <p>This method is called multiple times over the lifetime of an IkeSession (or default
-         * network), and is MUST always be called on the mExecutor thread in order to ensure
+         * network), and MUST always be called on the mExecutor thread in order to ensure
          * consistency of the Ikev2VpnRunner fields.
          */
         public void onChildTransformCreated(
-                @NonNull Network network, @NonNull IpSecTransform transform, int direction) {
-            if (!isActiveNetwork(network)) {
-                Log.d(TAG, "ChildTransformCreated for obsolete network " + network);
+                int token, @NonNull IpSecTransform transform, int direction) {
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "ChildTransformCreated for obsolete token " + token);
 
                 // Do nothing; this signals that either: (1) a new/better Network was found,
-                // and the Ikev2VpnRunner has switched to it in onDefaultNetworkChanged, or (2) this
-                // IKE session was already shut down (exited, or an error was encountered somewhere
-                // else). In both cases, all resources and sessions are torn down via
-                // resetIkeState().
+                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
+                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
+                // or an error was encountered somewhere else). In both cases, all resources and
+                // sessions are torn down via resetIkeState().
                 return;
             }
 
@@ -2815,36 +2937,127 @@
                 // them alive for us
                 mIpSecManager.applyTunnelModeTransform(mTunnelIface, direction, transform);
             } catch (IOException e) {
-                Log.d(TAG, "Transform application failed for network " + network, e);
-                onSessionLost(network, e);
+                Log.d(TAG, "Transform application failed for token " + token, e);
+                onSessionLost(token, e);
+            }
+        }
+
+        /**
+         * Called when an IPsec transform has been created, and should be re-applied.
+         *
+         * <p>This method is called multiple times over the lifetime of an IkeSession (or default
+         * network), and MUST always be called on the mExecutor thread in order to ensure
+         * consistency of the Ikev2VpnRunner fields.
+         */
+        public void onChildMigrated(
+                int token,
+                @NonNull IpSecTransform inTransform,
+                @NonNull IpSecTransform outTransform) {
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "onChildMigrated for obsolete token " + token);
+                return;
+            }
+
+            // The actual network of this IKE session has migrated to is
+            // mIkeConnectionInfo.getNetwork() instead of mActiveNetwork because mActiveNetwork
+            // might have been updated after the migration was triggered.
+            final Network network = mIkeConnectionInfo.getNetwork();
+
+            try {
+                synchronized (Vpn.this) {
+                    mConfig.underlyingNetworks = new Network[] {network};
+                    mNetworkCapabilities =
+                            new NetworkCapabilities.Builder(mNetworkCapabilities)
+                                    .setUnderlyingNetworks(Collections.singletonList(network))
+                                    .build();
+                    mNetworkAgent.setUnderlyingNetworks(Collections.singletonList(network));
+                }
+
+                mTunnelIface.setUnderlyingNetwork(network);
+
+                // Transforms do not need to be persisted; the IkeSession will keep them alive for
+                // us
+                mIpSecManager.applyTunnelModeTransform(
+                        mTunnelIface, IpSecManager.DIRECTION_IN, inTransform);
+                mIpSecManager.applyTunnelModeTransform(
+                        mTunnelIface, IpSecManager.DIRECTION_OUT, outTransform);
+            } catch (IOException e) {
+                Log.d(TAG, "Transform application failed for token " + token, e);
+                onSessionLost(token, e);
             }
         }
 
         /**
          * Called when a new default network is connected.
          *
-         * <p>The Ikev2VpnRunner will unconditionally switch to the new network, killing the old IKE
-         * state in the process, and starting a new IkeSession instance.
+         * <p>The Ikev2VpnRunner will unconditionally switch to the new network. If the IKE session
+         * has mobility, Ikev2VpnRunner will migrate the existing IkeSession to the new network.
+         * Otherwise, Ikev2VpnRunner will kill the old IKE state, and start a new IkeSession
+         * instance.
          *
          * <p>This method MUST always be called on the mExecutor thread in order to ensure
          * consistency of the Ikev2VpnRunner fields.
          */
         public void onDefaultNetworkChanged(@NonNull Network network) {
-            Log.d(TAG, "Starting IKEv2/IPsec session on new network: " + network);
+            Log.d(TAG, "onDefaultNetworkChanged: " + network);
+
+            // If there is a new default network brought up, cancel the retry task to prevent
+            // establishing an unnecessary IKE session.
+            cancelRetryNewIkeSessionFuture();
+
+            // If there is a new default network brought up, cancel the obsolete reset and retry
+            // task.
+            cancelHandleNetworkLostTimeout();
+
+            if (!mIsRunning) {
+                Log.d(TAG, "onDefaultNetworkChanged after exit");
+                return; // VPN has been shut down.
+            }
+
+            mActiveNetwork = network;
+            mRetryCount = 0;
+
+            startOrMigrateIkeSession(network);
+        }
+
+        /**
+         * Start a new IKE session.
+         *
+         * <p>This method MUST always be called on the mExecutor thread in order to ensure
+         * consistency of the Ikev2VpnRunner fields.
+         *
+         * @param underlyingNetwork if the value is {@code null}, which means there is no active
+         *              network can be used, do nothing and return immediately. Otherwise, use the
+         *              given network to start a new IKE session.
+         */
+        private void startOrMigrateIkeSession(@Nullable Network underlyingNetwork) {
+            if (underlyingNetwork == null) {
+                Log.d(TAG, "There is no active network for starting an IKE session");
+                return;
+            }
 
             try {
-                if (!mIsRunning) {
-                    Log.d(TAG, "onDefaultNetworkChanged after exit");
-                    return; // VPN has been shut down.
+                if (mSession != null && mMobikeEnabled) {
+                    // IKE session can schedule a migration event only when IKE AUTH is finished
+                    // and mMobikeEnabled is true.
+                    Log.d(
+                            TAG,
+                            "Migrate IKE Session with token "
+                                    + mCurrentToken
+                                    + " to network "
+                                    + underlyingNetwork);
+                    mSession.setNetwork(underlyingNetwork);
+                    return;
                 }
 
+                Log.d(TAG, "Start new IKE session on network " + underlyingNetwork);
+
                 // Clear mInterface to prevent Ikev2VpnRunner being cleared when
                 // interfaceRemoved() is called.
                 mInterface = null;
                 // Without MOBIKE, we have no way to seamlessly migrate. Close on old
                 // (non-default) network, and start the new one.
                 resetIkeState();
-                mActiveNetwork = network;
 
                 // Get Ike options from IkeTunnelConnectionParams if it's available in the
                 // profile.
@@ -2854,12 +3067,12 @@
                 final ChildSessionParams childSessionParams;
                 if (ikeTunConnParams != null) {
                     final IkeSessionParams.Builder builder = new IkeSessionParams.Builder(
-                            ikeTunConnParams.getIkeSessionParams()).setNetwork(network);
+                            ikeTunConnParams.getIkeSessionParams()).setNetwork(underlyingNetwork);
                     ikeSessionParams = builder.build();
                     childSessionParams = ikeTunConnParams.getTunnelModeChildSessionParams();
                 } else {
                     ikeSessionParams = VpnIkev2Utils.buildIkeSessionParams(
-                            mContext, mProfile, network);
+                            mContext, mProfile, underlyingNetwork);
                     childSessionParams = VpnIkev2Utils.buildChildSessionParams(
                             mProfile.getAllowedAlgorithms());
                 }
@@ -2867,29 +3080,50 @@
                 // TODO: Remove the need for adding two unused addresses with
                 // IPsec tunnels.
                 final InetAddress address = InetAddress.getLocalHost();
+
+                // When onChildOpened is called and transforms are applied, it is
+                // guaranteed that the underlying network is still "network", because the
+                // all the network switch events will be deferred before onChildOpened is
+                // called. Thus it is safe to build a mTunnelIface before IKE setup.
                 mTunnelIface =
                         mIpSecManager.createIpSecTunnelInterface(
-                                address /* unused */,
-                                address /* unused */,
-                                network);
+                                address /* unused */, address /* unused */, underlyingNetwork);
                 NetdUtils.setInterfaceUp(mNetd, mTunnelIface.getInterfaceName());
 
-                mSession = mIkev2SessionCreator.createIkeSession(
-                        mContext,
-                        ikeSessionParams,
-                        childSessionParams,
-                        mExecutor,
-                        new VpnIkev2Utils.IkeSessionCallbackImpl(
-                                TAG, IkeV2VpnRunner.this, network),
-                        new VpnIkev2Utils.ChildSessionCallbackImpl(
-                                TAG, IkeV2VpnRunner.this, network));
-                Log.d(TAG, "Ike Session started for network " + network);
+                final int token = ++mCurrentToken;
+                mSession =
+                        mIkev2SessionCreator.createIkeSession(
+                                mContext,
+                                ikeSessionParams,
+                                childSessionParams,
+                                mExecutor,
+                                new VpnIkev2Utils.IkeSessionCallbackImpl(
+                                        TAG, IkeV2VpnRunner.this, token),
+                                new VpnIkev2Utils.ChildSessionCallbackImpl(
+                                        TAG, IkeV2VpnRunner.this, token));
+                Log.d(TAG, "IKE session started for token " + token);
             } catch (Exception e) {
-                Log.i(TAG, "Setup failed for network " + network + ". Aborting", e);
-                onSessionLost(network, e);
+                Log.i(TAG, "Setup failed for token " + mCurrentToken + ". Aborting", e);
+                onSessionLost(mCurrentToken, e);
             }
         }
 
+        private void scheduleRetryNewIkeSession() {
+            final long retryDelay = mDeps.getNextRetryDelaySeconds(mRetryCount++);
+            Log.d(TAG, "Retry new IKE session after " + retryDelay + " seconds.");
+            // If the default network is lost during the retry delay, the mActiveNetwork will be
+            // null, and the new IKE session won't be established until there is a new default
+            // network bringing up.
+            mScheduledHandleRetryIkeSessionTimeout =
+                    mExecutor.schedule(() -> {
+                        startOrMigrateIkeSession(mActiveNetwork);
+
+                        // Reset mScheduledHandleRetryIkeSessionTimeout since it's already run on
+                        // executor thread.
+                        mScheduledHandleRetryIkeSessionTimeout = null;
+                    }, retryDelay, TimeUnit.SECONDS);
+        }
+
         /** Called when the NetworkCapabilities of underlying network is changed */
         public void onDefaultNetworkCapabilitiesChanged(@NonNull NetworkCapabilities nc) {
             mUnderlyingNetworkCapabilities = nc;
@@ -2900,6 +3134,99 @@
             mUnderlyingLinkProperties = lp;
         }
 
+        /**
+         * Handles loss of the default underlying network
+         *
+         * <p>If the IKE Session has mobility, Ikev2VpnRunner will schedule a teardown event with a
+         * delay so that the IKE Session can migrate if a new network is available soon. Otherwise,
+         * Ikev2VpnRunner will kill the IKE session and reset the VPN.
+         *
+         * <p>This method MUST always be called on the mExecutor thread in order to ensure
+         * consistency of the Ikev2VpnRunner fields.
+         */
+        public void onDefaultNetworkLost(@NonNull Network network) {
+            // If the default network is torn down, there is no need to call
+            // startOrMigrateIkeSession() since it will always check if there is an active network
+            // can be used or not.
+            cancelRetryNewIkeSessionFuture();
+
+            if (!isActiveNetwork(network)) {
+                Log.d(TAG, "onDefaultNetworkLost called for obsolete network " + network);
+
+                // Do nothing; this signals that either: (1) a new/better Network was found,
+                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
+                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
+                // or an error was encountered somewhere else). In both cases, all resources and
+                // sessions are torn down via resetIkeState().
+                return;
+            } else {
+                mActiveNetwork = null;
+            }
+
+            if (mScheduledHandleNetworkLostTimeout != null
+                    && !mScheduledHandleNetworkLostTimeout.isCancelled()
+                    && !mScheduledHandleNetworkLostTimeout.isDone()) {
+                final IllegalStateException exception =
+                        new IllegalStateException(
+                                "Found a pending mScheduledHandleNetworkLostTimeout");
+                Log.i(
+                        TAG,
+                        "Unexpected error in onDefaultNetworkLost. Tear down session",
+                        exception);
+                handleSessionLost(exception, network);
+                return;
+            }
+
+            if (mSession != null && mMobikeEnabled) {
+                Log.d(
+                        TAG,
+                        "IKE Session has mobility. Delay handleSessionLost for losing network "
+                                + network
+                                + " on session with token "
+                                + mCurrentToken);
+
+                // Delay the teardown in case a new network will be available soon. For example,
+                // during handover between two WiFi networks, Android will disconnect from the
+                // first WiFi and then connects to the second WiFi.
+                mScheduledHandleNetworkLostTimeout =
+                        mExecutor.schedule(
+                                () -> {
+                                    handleSessionLost(null, network);
+                                },
+                                NETWORK_LOST_TIMEOUT_MS,
+                                TimeUnit.MILLISECONDS);
+            } else {
+                Log.d(TAG, "Call handleSessionLost for losing network " + network);
+                handleSessionLost(null, network);
+            }
+        }
+
+        private void cancelHandleNetworkLostTimeout() {
+            if (mScheduledHandleNetworkLostTimeout != null
+                    && !mScheduledHandleNetworkLostTimeout.isDone()) {
+                // It does not matter what to put in #cancel(boolean), because it is impossible
+                // that the task tracked by mScheduledHandleNetworkLostTimeout is
+                // in-progress since both that task and onDefaultNetworkChanged are submitted to
+                // mExecutor who has only one thread.
+                Log.d(TAG, "Cancel the task for handling network lost timeout");
+                mScheduledHandleNetworkLostTimeout.cancel(false /* mayInterruptIfRunning */);
+                mScheduledHandleNetworkLostTimeout = null;
+            }
+        }
+
+        private void cancelRetryNewIkeSessionFuture() {
+            if (mScheduledHandleRetryIkeSessionTimeout != null
+                    && !mScheduledHandleRetryIkeSessionTimeout.isDone()) {
+                // It does not matter what to put in #cancel(boolean), because it is impossible
+                // that the task tracked by mScheduledHandleRetryIkeSessionTimeout is
+                // in-progress since both that task and onDefaultNetworkChanged are submitted to
+                // mExecutor who has only one thread.
+                Log.d(TAG, "Cancel the task for handling new ike session timeout");
+                mScheduledHandleRetryIkeSessionTimeout.cancel(false /* mayInterruptIfRunning */);
+                mScheduledHandleRetryIkeSessionTimeout = null;
+            }
+        }
+
         /** Marks the state as FAILED, and disconnects. */
         private void markFailedAndDisconnect(Exception exception) {
             synchronized (Vpn.this) {
@@ -2918,18 +3245,28 @@
          * <p>This method MUST always be called on the mExecutor thread in order to ensure
          * consistency of the Ikev2VpnRunner fields.
          */
-        public void onSessionLost(@NonNull Network network, @Nullable Exception exception) {
-            if (!isActiveNetwork(network)) {
-                Log.d(TAG, "onSessionLost() called for obsolete network " + network);
+        public void onSessionLost(int token, @Nullable Exception exception) {
+            Log.d(TAG, "onSessionLost() called for token " + token);
+
+            if (!isActiveToken(token)) {
+                Log.d(TAG, "onSessionLost() called for obsolete token " + token);
 
                 // Do nothing; this signals that either: (1) a new/better Network was found,
-                // and the Ikev2VpnRunner has switched to it in onDefaultNetworkChanged, or (2) this
-                // IKE session was already shut down (exited, or an error was encountered somewhere
-                // else). In both cases, all resources and sessions are torn down via
-                // onSessionLost() and resetIkeState().
+                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
+                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
+                // or an error was encountered somewhere else). In both cases, all resources and
+                // sessions are torn down via resetIkeState().
                 return;
             }
 
+            handleSessionLost(exception, mActiveNetwork);
+        }
+
+        private void handleSessionLost(@Nullable Exception exception, @Nullable Network network) {
+            // Cancel mScheduledHandleNetworkLostTimeout if the session it is going to terminate is
+            // already terminated due to other failures.
+            cancelHandleNetworkLostTimeout();
+
             synchronized (Vpn.this) {
                 if (exception instanceof IkeProtocolException) {
                     final IkeProtocolException ikeException = (IkeProtocolException) exception;
@@ -2949,7 +3286,7 @@
                                         VpnManager.ERROR_CLASS_NOT_RECOVERABLE,
                                         ikeException.getErrorType(),
                                         getPackage(), mSessionKey, makeVpnProfileStateLocked(),
-                                        mActiveNetwork,
+                                        network,
                                         getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
                                                 mUnderlyingNetworkCapabilities),
                                         getRedactedLinkPropertiesOfUnderlyingNetwork(
@@ -2967,7 +3304,7 @@
                                         VpnManager.ERROR_CLASS_RECOVERABLE,
                                         ikeException.getErrorType(),
                                         getPackage(), mSessionKey, makeVpnProfileStateLocked(),
-                                        mActiveNetwork,
+                                        network,
                                         getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
                                                 mUnderlyingNetworkCapabilities),
                                         getRedactedLinkPropertiesOfUnderlyingNetwork(
@@ -2986,7 +3323,7 @@
                                 VpnManager.ERROR_CLASS_RECOVERABLE,
                                 VpnManager.ERROR_CODE_NETWORK_LOST,
                                 getPackage(), mSessionKey, makeVpnProfileStateLocked(),
-                                mActiveNetwork,
+                                network,
                                 getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
                                         mUnderlyingNetworkCapabilities),
                                 getRedactedLinkPropertiesOfUnderlyingNetwork(
@@ -3001,7 +3338,7 @@
                                     VpnManager.ERROR_CLASS_RECOVERABLE,
                                     VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST,
                                     getPackage(), mSessionKey, makeVpnProfileStateLocked(),
-                                    mActiveNetwork,
+                                    network,
                                     getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
                                             mUnderlyingNetworkCapabilities),
                                     getRedactedLinkPropertiesOfUnderlyingNetwork(
@@ -3015,7 +3352,7 @@
                                     VpnManager.ERROR_CLASS_RECOVERABLE,
                                     VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT,
                                     getPackage(), mSessionKey, makeVpnProfileStateLocked(),
-                                    mActiveNetwork,
+                                    network,
                                     getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
                                             mUnderlyingNetworkCapabilities),
                                     getRedactedLinkPropertiesOfUnderlyingNetwork(
@@ -3029,7 +3366,7 @@
                                     VpnManager.ERROR_CLASS_RECOVERABLE,
                                     VpnManager.ERROR_CODE_NETWORK_IO,
                                     getPackage(), mSessionKey, makeVpnProfileStateLocked(),
-                                    mActiveNetwork,
+                                    network,
                                     getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
                                             mUnderlyingNetworkCapabilities),
                                     getRedactedLinkPropertiesOfUnderlyingNetwork(
@@ -3039,15 +3376,16 @@
                 } else if (exception != null) {
                     Log.wtf(TAG, "onSessionLost: exception = " + exception);
                 }
+
+                scheduleRetryNewIkeSession();
             }
 
-            mActiveNetwork = null;
             mUnderlyingNetworkCapabilities = null;
             mUnderlyingLinkProperties = null;
 
             // Close all obsolete state, but keep VPN alive incase a usable network comes up.
             // (Mirrors VpnService behavior)
-            Log.d(TAG, "Resetting state for network: " + network);
+            Log.d(TAG, "Resetting state for token: " + mCurrentToken);
 
             synchronized (Vpn.this) {
                 // Since this method handles non-fatal errors only, set mInterface to null to
@@ -3092,6 +3430,8 @@
                 mSession.kill(); // Kill here to make sure all resources are released immediately
                 mSession = null;
             }
+            mIkeConnectionInfo = null;
+            mMobikeEnabled = false;
         }
 
         /**
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index 1705828..857c86d 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -68,6 +68,7 @@
 import android.net.ipsec.ike.IkeSaProposal;
 import android.net.ipsec.ike.IkeSessionCallback;
 import android.net.ipsec.ike.IkeSessionConfiguration;
+import android.net.ipsec.ike.IkeSessionConnectionInfo;
 import android.net.ipsec.ike.IkeSessionParams;
 import android.net.ipsec.ike.IkeTrafficSelector;
 import android.net.ipsec.ike.TunnelModeChildSessionParams;
@@ -107,6 +108,7 @@
                 new IkeSessionParams.Builder(context)
                         .setServerHostname(profile.getServerAddr())
                         .setNetwork(network)
+                        .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
                         .setLocalIdentification(localId)
                         .setRemoteIdentification(remoteId);
         setIkeAuth(profile, ikeOptionsBuilder);
@@ -298,72 +300,79 @@
     static class IkeSessionCallbackImpl implements IkeSessionCallback {
         private final String mTag;
         private final Vpn.IkeV2VpnRunnerCallback mCallback;
-        private final Network mNetwork;
+        private final int mToken;
 
-        IkeSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, Network network) {
+        IkeSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, int token) {
             mTag = tag;
             mCallback = callback;
-            mNetwork = network;
+            mToken = token;
         }
 
         @Override
         public void onOpened(@NonNull IkeSessionConfiguration ikeSessionConfig) {
-            Log.d(mTag, "IkeOpened for network " + mNetwork);
-            // Nothing to do here.
+            Log.d(mTag, "IkeOpened for token " + mToken);
+            mCallback.onIkeOpened(mToken, ikeSessionConfig);
         }
 
         @Override
         public void onClosed() {
-            Log.d(mTag, "IkeClosed for network " + mNetwork);
-            mCallback.onSessionLost(mNetwork, null); // Server requested session closure. Retry?
+            Log.d(mTag, "IkeClosed for token " + mToken);
+            mCallback.onSessionLost(mToken, null); // Server requested session closure. Retry?
         }
 
         @Override
         public void onClosedExceptionally(@NonNull IkeException exception) {
-            Log.d(mTag, "IkeClosedExceptionally for network " + mNetwork, exception);
-            mCallback.onSessionLost(mNetwork, exception);
+            Log.d(mTag, "IkeClosedExceptionally for token " + mToken, exception);
+            mCallback.onSessionLost(mToken, exception);
         }
 
         @Override
         public void onError(@NonNull IkeProtocolException exception) {
-            Log.d(mTag, "IkeError for network " + mNetwork, exception);
+            Log.d(mTag, "IkeError for token " + mToken, exception);
             // Non-fatal, log and continue.
         }
+
+        @Override
+        public void onIkeSessionConnectionInfoChanged(
+                @NonNull IkeSessionConnectionInfo connectionInfo) {
+            Log.d(mTag, "onIkeSessionConnectionInfoChanged for token " + mToken);
+            mCallback.onIkeConnectionInfoChanged(mToken, connectionInfo);
+        }
     }
 
     static class ChildSessionCallbackImpl implements ChildSessionCallback {
         private final String mTag;
         private final Vpn.IkeV2VpnRunnerCallback mCallback;
-        private final Network mNetwork;
+        private final int mToken;
 
-        ChildSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, Network network) {
+        ChildSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, int token) {
             mTag = tag;
             mCallback = callback;
-            mNetwork = network;
+            mToken = token;
         }
 
         @Override
         public void onOpened(@NonNull ChildSessionConfiguration childConfig) {
-            Log.d(mTag, "ChildOpened for network " + mNetwork);
-            mCallback.onChildOpened(mNetwork, childConfig);
+            Log.d(mTag, "ChildOpened for token " + mToken);
+            mCallback.onChildOpened(mToken, childConfig);
         }
 
         @Override
         public void onClosed() {
-            Log.d(mTag, "ChildClosed for network " + mNetwork);
-            mCallback.onSessionLost(mNetwork, null);
+            Log.d(mTag, "ChildClosed for token " + mToken);
+            mCallback.onSessionLost(mToken, null);
         }
 
         @Override
         public void onClosedExceptionally(@NonNull IkeException exception) {
-            Log.d(mTag, "ChildClosedExceptionally for network " + mNetwork, exception);
-            mCallback.onSessionLost(mNetwork, exception);
+            Log.d(mTag, "ChildClosedExceptionally for token " + mToken, exception);
+            mCallback.onSessionLost(mToken, exception);
         }
 
         @Override
         public void onIpSecTransformCreated(@NonNull IpSecTransform transform, int direction) {
-            Log.d(mTag, "ChildTransformCreated; Direction: " + direction + "; network " + mNetwork);
-            mCallback.onChildTransformCreated(mNetwork, transform, direction);
+            Log.d(mTag, "ChildTransformCreated; Direction: " + direction + "; token " + mToken);
+            mCallback.onChildTransformCreated(mToken, transform, direction);
         }
 
         @Override
@@ -371,8 +380,15 @@
             // Nothing to be done; no references to the IpSecTransform are held by the
             // Ikev2VpnRunner (or this callback class), and this transform will be closed by the
             // IKE library.
-            Log.d(mTag,
-                    "ChildTransformDeleted; Direction: " + direction + "; for network " + mNetwork);
+            Log.d(mTag, "ChildTransformDeleted; Direction: " + direction + "; for token " + mToken);
+        }
+
+        @Override
+        public void onIpSecTransformsMigrated(
+                @NonNull IpSecTransform inIpSecTransform,
+                @NonNull IpSecTransform outIpSecTransform) {
+            Log.d(mTag, "ChildTransformsMigrated; token " + mToken);
+            mCallback.onChildMigrated(mToken, inIpSecTransform, outIpSecTransform);
         }
     }
 
@@ -390,7 +406,7 @@
 
         @Override
         public void onAvailable(@NonNull Network network) {
-            Log.d(mTag, "Starting IKEv2/IPsec session on new network: " + network);
+            Log.d(mTag, "onAvailable called for network: " + network);
             mExecutor.execute(() -> mCallback.onDefaultNetworkChanged(network));
         }
 
@@ -412,8 +428,8 @@
 
         @Override
         public void onLost(@NonNull Network network) {
-            Log.d(mTag, "Tearing down; lost network: " + network);
-            mExecutor.execute(() -> mCallback.onSessionLost(network, null));
+            Log.d(mTag, "onLost called for network: " + network);
+            mExecutor.execute(() -> mCallback.onDefaultNetworkLost(network));
         }
     }
 
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index 03e18a0..8e00ccf 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -40,6 +40,8 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
+import android.os.SystemProperties;
+import android.os.Trace;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -144,15 +146,30 @@
 
     private Set<Integer> mDeviceStatesAvailableForAppRequests;
 
+    @VisibleForTesting
+    interface SystemPropertySetter {
+        void setDebugTracingDeviceStateProperty(String value);
+    }
+    @NonNull
+    private final SystemPropertySetter mSystemPropertySetter;
+
     public DeviceStateManagerService(@NonNull Context context) {
         this(context, DeviceStatePolicy.Provider
                 .fromResources(context.getResources())
                 .instantiate(context));
     }
 
+    private DeviceStateManagerService(@NonNull Context context, @NonNull DeviceStatePolicy policy) {
+        this(context, policy, (value) -> {
+            SystemProperties.set("debug.tracing.device_state", value);
+        });
+    }
+
     @VisibleForTesting
-    DeviceStateManagerService(@NonNull Context context, @NonNull DeviceStatePolicy policy) {
+    DeviceStateManagerService(@NonNull Context context, @NonNull DeviceStatePolicy policy,
+                @NonNull SystemPropertySetter systemPropertySetter) {
         super(context);
+        mSystemPropertySetter = systemPropertySetter;
         // We use the DisplayThread because this service indirectly drives
         // display (on/off) and window (position) events through its callbacks.
         DisplayThread displayThread = DisplayThread.get();
@@ -462,6 +479,10 @@
 
             FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_STATE_CHANGED,
                     newState.getIdentifier(), !mCommittedState.isPresent());
+            String traceString = newState.getIdentifier() + ":" + newState.getName();
+            Trace.instantForTrack(
+                    Trace.TRACE_TAG_SYSTEM_SERVER, "DeviceStateChanged", traceString);
+            mSystemPropertySetter.setDebugTracingDeviceStateProperty(traceString);
 
             mCommittedState = Optional.of(newState);
             mPendingState = Optional.empty();
diff --git a/services/core/java/com/android/server/display/BrightnessThrottler.java b/services/core/java/com/android/server/display/BrightnessThrottler.java
index 767b2d1..eccee52 100644
--- a/services/core/java/com/android/server/display/BrightnessThrottler.java
+++ b/services/core/java/com/android/server/display/BrightnessThrottler.java
@@ -16,21 +16,31 @@
 
 package com.android.server.display;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.hardware.display.BrightnessInfo;
+import android.hardware.display.DisplayManager;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.IThermalEventListener;
 import android.os.IThermalService;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.Temperature;
+import android.provider.DeviceConfig;
+import android.provider.DeviceConfigInterface;
 import android.util.Slog;
 
-import com.android.server.display.DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.display.DisplayDeviceConfig.BrightnessThrottlingData;
+import com.android.server.display.DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.Executor;
 
 /**
  * This class monitors various conditions, such as skin temperature throttling status, and limits
@@ -44,28 +54,54 @@
 
     private final Injector mInjector;
     private final Handler mHandler;
-    private BrightnessThrottlingData mThrottlingData;
+    // We need a separate handler for unit testing. These two handlers are the same throughout the
+    // non-test code.
+    private final Handler mDeviceConfigHandler;
     private final Runnable mThrottlingChangeCallback;
     private final SkinThermalStatusObserver mSkinThermalStatusObserver;
+    private final DeviceConfigListener mDeviceConfigListener;
+    private final DeviceConfigInterface mDeviceConfig;
+
     private int mThrottlingStatus;
+    private BrightnessThrottlingData mThrottlingData;
+    private BrightnessThrottlingData mDdcThrottlingData;
     private float mBrightnessCap = PowerManager.BRIGHTNESS_MAX;
     private @BrightnessInfo.BrightnessMaxReason int mBrightnessMaxReason =
         BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
+    private String mUniqueDisplayId;
+
+    // The most recent string that has been set from DeviceConfig
+    private String mBrightnessThrottlingDataString;
+
+    // This is a collection of brightness throttling data that has been written as overrides from
+    // the DeviceConfig. This will always take priority over the display device config data.
+    private HashMap<String, BrightnessThrottlingData> mBrightnessThrottlingDataOverride =
+            new HashMap<>(1);
 
     BrightnessThrottler(Handler handler, BrightnessThrottlingData throttlingData,
-            Runnable throttlingChangeCallback) {
-        this(new Injector(), handler, throttlingData, throttlingChangeCallback);
+            Runnable throttlingChangeCallback, String uniqueDisplayId) {
+        this(new Injector(), handler, handler, throttlingData, throttlingChangeCallback,
+                uniqueDisplayId);
     }
 
-    BrightnessThrottler(Injector injector, Handler handler, BrightnessThrottlingData throttlingData,
-            Runnable throttlingChangeCallback) {
+    @VisibleForTesting
+    BrightnessThrottler(Injector injector, Handler handler, Handler deviceConfigHandler,
+            BrightnessThrottlingData throttlingData, Runnable throttlingChangeCallback,
+            String uniqueDisplayId) {
         mInjector = injector;
+
         mHandler = handler;
+        mDeviceConfigHandler = deviceConfigHandler;
         mThrottlingData = throttlingData;
+        mDdcThrottlingData = throttlingData;
         mThrottlingChangeCallback = throttlingChangeCallback;
         mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler);
 
-        resetThrottlingData(mThrottlingData);
+        mUniqueDisplayId = uniqueDisplayId;
+        mDeviceConfig = injector.getDeviceConfig();
+        mDeviceConfigListener = new DeviceConfigListener();
+
+        resetThrottlingData(mThrottlingData, mUniqueDisplayId);
     }
 
     boolean deviceSupportsThrottling() {
@@ -86,7 +122,7 @@
 
     void stop() {
         mSkinThermalStatusObserver.stopObserving();
-
+        mDeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigListener);
         // We're asked to stop throttling, so reset brightness restrictions.
         mBrightnessCap = PowerManager.BRIGHTNESS_MAX;
         mBrightnessMaxReason = BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
@@ -97,9 +133,19 @@
         mThrottlingStatus = THROTTLING_INVALID;
     }
 
-    void resetThrottlingData(BrightnessThrottlingData throttlingData) {
+    private void resetThrottlingData() {
+        resetThrottlingData(mDdcThrottlingData, mUniqueDisplayId);
+    }
+
+    void resetThrottlingData(BrightnessThrottlingData throttlingData, String displayId) {
         stop();
-        mThrottlingData = throttlingData;
+
+        mUniqueDisplayId = displayId;
+        mDdcThrottlingData = throttlingData;
+        mDeviceConfigListener.startListening();
+        reloadBrightnessThrottlingDataOverride();
+        mThrottlingData = mBrightnessThrottlingDataOverride.getOrDefault(mUniqueDisplayId,
+                throttlingData);
 
         if (deviceSupportsThrottling()) {
             mSkinThermalStatusObserver.startObserving();
@@ -173,14 +219,148 @@
     private void dumpLocal(PrintWriter pw) {
         pw.println("BrightnessThrottler:");
         pw.println("  mThrottlingData=" + mThrottlingData);
+        pw.println("  mDdcThrottlingData=" + mDdcThrottlingData);
+        pw.println("  mUniqueDisplayId=" + mUniqueDisplayId);
         pw.println("  mThrottlingStatus=" + mThrottlingStatus);
         pw.println("  mBrightnessCap=" + mBrightnessCap);
         pw.println("  mBrightnessMaxReason=" +
             BrightnessInfo.briMaxReasonToString(mBrightnessMaxReason));
+        pw.println("  mBrightnessThrottlingDataOverride=" + mBrightnessThrottlingDataOverride);
+        pw.println("  mBrightnessThrottlingDataString=" + mBrightnessThrottlingDataString);
 
         mSkinThermalStatusObserver.dump(pw);
     }
 
+    private String getBrightnessThrottlingDataString() {
+        return mDeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
+                DisplayManager.DeviceConfig.KEY_BRIGHTNESS_THROTTLING_DATA,
+                /* defaultValue= */ null);
+    }
+
+    private boolean parseAndSaveData(@NonNull String strArray,
+            @NonNull HashMap<String, BrightnessThrottlingData> tempBrightnessThrottlingData) {
+        boolean validConfig = true;
+        String[] items = strArray.split(",");
+        int i = 0;
+
+        try {
+            String uniqueDisplayId = items[i++];
+
+            // number of throttling points
+            int noOfThrottlingPoints = Integer.parseInt(items[i++]);
+            List<ThrottlingLevel> throttlingLevels = new ArrayList<>(noOfThrottlingPoints);
+
+            // throttling level and point
+            for (int j = 0; j < noOfThrottlingPoints; j++) {
+                String severity = items[i++];
+                int status = parseThermalStatus(severity);
+
+                float brightnessPoint = parseBrightness(items[i++]);
+
+                throttlingLevels.add(new ThrottlingLevel(status, brightnessPoint));
+            }
+            BrightnessThrottlingData toSave =
+                    DisplayDeviceConfig.BrightnessThrottlingData.create(throttlingLevels);
+            tempBrightnessThrottlingData.put(uniqueDisplayId, toSave);
+        } catch (NumberFormatException | IndexOutOfBoundsException
+                | UnknownThermalStatusException e) {
+            validConfig = false;
+            Slog.e(TAG, "Throttling data is invalid array: '" + strArray + "'", e);
+        }
+
+        if (i != items.length) {
+            validConfig = false;
+        }
+
+        return validConfig;
+    }
+
+    public void reloadBrightnessThrottlingDataOverride() {
+        HashMap<String, BrightnessThrottlingData> tempBrightnessThrottlingData =
+                new HashMap<>(1);
+        mBrightnessThrottlingDataString = getBrightnessThrottlingDataString();
+        boolean validConfig = true;
+        mBrightnessThrottlingDataOverride.clear();
+        if (mBrightnessThrottlingDataString != null) {
+            String[] throttlingDataSplits = mBrightnessThrottlingDataString.split(";");
+            for (String s : throttlingDataSplits) {
+                if (!parseAndSaveData(s, tempBrightnessThrottlingData)) {
+                    validConfig = false;
+                    break;
+                }
+            }
+
+            if (validConfig) {
+                mBrightnessThrottlingDataOverride.putAll(tempBrightnessThrottlingData);
+                tempBrightnessThrottlingData.clear();
+            }
+
+        } else {
+            Slog.w(TAG, "DeviceConfig BrightnessThrottlingData is null");
+        }
+    }
+
+    /**
+     * Listens to config data change and updates the brightness throttling data using
+     * DisplayManager#KEY_BRIGHTNESS_THROTTLING_DATA.
+     * The format should be a string similar to: "local:4619827677550801152,2,moderate,0.5,severe,
+     * 0.379518072;local:4619827677550801151,1,moderate,0.75"
+     * In this order:
+     * <displayId>,<no of throttling levels>,[<severity as string>,<brightness cap>]
+     * Where the latter part is repeated for each throttling level, and the entirety is repeated
+     * for each display, separated by a semicolon.
+     */
+    public class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener {
+        public Executor mExecutor = new HandlerExecutor(mDeviceConfigHandler);
+
+        public void startListening() {
+            mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
+                    mExecutor, this);
+        }
+
+        @Override
+        public void onPropertiesChanged(DeviceConfig.Properties properties) {
+            reloadBrightnessThrottlingDataOverride();
+            resetThrottlingData();
+        }
+    }
+
+    private float parseBrightness(String intVal) throws NumberFormatException {
+        float value = Float.parseFloat(intVal);
+        if (value < PowerManager.BRIGHTNESS_MIN || value > PowerManager.BRIGHTNESS_MAX) {
+            throw new NumberFormatException("Brightness constraint value out of bounds.");
+        }
+        return value;
+    }
+
+    @PowerManager.ThermalStatus private int parseThermalStatus(@NonNull String value)
+            throws UnknownThermalStatusException {
+        switch (value) {
+            case "none":
+                return PowerManager.THERMAL_STATUS_NONE;
+            case "light":
+                return PowerManager.THERMAL_STATUS_LIGHT;
+            case "moderate":
+                return PowerManager.THERMAL_STATUS_MODERATE;
+            case "severe":
+                return PowerManager.THERMAL_STATUS_SEVERE;
+            case "critical":
+                return PowerManager.THERMAL_STATUS_CRITICAL;
+            case "emergency":
+                return PowerManager.THERMAL_STATUS_EMERGENCY;
+            case "shutdown":
+                return PowerManager.THERMAL_STATUS_SHUTDOWN;
+            default:
+                throw new UnknownThermalStatusException("Invalid Thermal Status: " + value);
+        }
+    }
+
+    private static class UnknownThermalStatusException extends Exception {
+        UnknownThermalStatusException(String message) {
+            super(message);
+        }
+    }
+
     private final class SkinThermalStatusObserver extends IThermalEventListener.Stub {
         private final Injector mInjector;
         private final Handler mHandler;
@@ -258,5 +438,10 @@
             return IThermalService.Stub.asInterface(
                     ServiceManager.getService(Context.THERMAL_SERVICE));
         }
+
+        @NonNull
+        public DeviceConfigInterface getDeviceConfig() {
+            return DeviceConfigInterface.REAL;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index a25ac21..2322280d 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -279,10 +279,14 @@
     private HighBrightnessModeData mHbmData;
     private DensityMapping mDensityMapping;
     private String mLoadedFrom = null;
-
-    private BrightnessThrottlingData mBrightnessThrottlingData;
     private Spline mSdrToHdrRatioSpline;
 
+    // Brightness Throttling data may be updated via the DeviceConfig. Here we store the original
+    // data, which comes from the ddc, and the current one, which may be the DeviceConfig
+    // overwritten value.
+    private BrightnessThrottlingData mBrightnessThrottlingData;
+    private BrightnessThrottlingData mOriginalBrightnessThrottlingData;
+
     private DisplayDeviceConfig(Context context) {
         mContext = context;
     }
@@ -422,6 +426,10 @@
         return config;
     }
 
+    void setBrightnessThrottlingData(BrightnessThrottlingData brightnessThrottlingData) {
+        mBrightnessThrottlingData = brightnessThrottlingData;
+    }
+
     /**
      * Return the brightness mapping nits array.
      *
@@ -637,6 +645,7 @@
                 + ", mHbmData=" + mHbmData
                 + ", mSdrToHdrRatioSpline=" + mSdrToHdrRatioSpline
                 + ", mBrightnessThrottlingData=" + mBrightnessThrottlingData
+                + ", mOriginalBrightnessThrottlingData=" + mOriginalBrightnessThrottlingData
                 + ", mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease
                 + ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
                 + ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
@@ -932,6 +941,7 @@
 
         if (!badConfig) {
             mBrightnessThrottlingData = BrightnessThrottlingData.create(throttlingLevels);
+            mOriginalBrightnessThrottlingData = mBrightnessThrottlingData;
         }
     }
 
@@ -1407,7 +1417,9 @@
     /**
      * Container for brightness throttling data.
      */
-    static class BrightnessThrottlingData {
+    public static class BrightnessThrottlingData {
+        public List<ThrottlingLevel> throttlingLevels;
+
         static class ThrottlingLevel {
             public @PowerManager.ThermalStatus int thermalStatus;
             public float brightness;
@@ -1421,9 +1433,25 @@
             public String toString() {
                 return "[" + thermalStatus + "," + brightness + "]";
             }
-        }
 
-        public List<ThrottlingLevel> throttlingLevels;
+            @Override
+            public boolean equals(Object obj) {
+                if (!(obj instanceof ThrottlingLevel)) {
+                    return false;
+                }
+                ThrottlingLevel otherThrottlingLevel = (ThrottlingLevel) obj;
+
+                return otherThrottlingLevel.thermalStatus == this.thermalStatus
+                        && otherThrottlingLevel.brightness == this.brightness;
+            }
+            @Override
+            public int hashCode() {
+                int result = 1;
+                result = 31 * result + thermalStatus;
+                result = 31 * result + Float.hashCode(brightness);
+                return result;
+            }
+        }
 
         static public BrightnessThrottlingData create(List<ThrottlingLevel> throttlingLevels)
         {
@@ -1482,12 +1510,30 @@
                 + "} ";
         }
 
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+
+            if (!(obj instanceof BrightnessThrottlingData)) {
+                return false;
+            }
+
+            BrightnessThrottlingData otherBrightnessThrottlingData = (BrightnessThrottlingData) obj;
+            return throttlingLevels.equals(otherBrightnessThrottlingData.throttlingLevels);
+        }
+
+        @Override
+        public int hashCode() {
+            return throttlingLevels.hashCode();
+        }
+
         private BrightnessThrottlingData(List<ThrottlingLevel> inLevels) {
             throttlingLevels = new ArrayList<>(inLevels.size());
             for (ThrottlingLevel level : inLevels) {
                 throttlingLevels.add(new ThrottlingLevel(level.thermalStatus, level.brightness));
             }
         }
-
     }
 }
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index d3e2966..6285ef1 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -485,7 +485,7 @@
         mUiHandler = UiThread.getHandler();
         mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
         mLogicalDisplayMapper = new LogicalDisplayMapper(mContext, mDisplayDeviceRepo,
-                new LogicalDisplayListener(), mSyncRoot, mHandler, new DeviceStateToLayoutMap());
+                new LogicalDisplayListener(), mSyncRoot, mHandler);
         mDisplayModeDirector = new DisplayModeDirector(context, mHandler);
         mBrightnessSynchronizer = new BrightnessSynchronizer(mContext);
         Resources resources = mContext.getResources();
@@ -945,8 +945,7 @@
 
     private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
         synchronized (mSyncRoot) {
-            final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId,
-                    /* includeDisabledDisplays= */ true);
+            final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
             if (display != null) {
                 final DisplayInfo info =
                         getDisplayInfoForFrameRateOverride(display.getFrameRateOverrides(),
@@ -2129,18 +2128,16 @@
     }
 
     void resetBrightnessConfigurations() {
-        synchronized (mSyncRoot) {
-            mPersistentDataStore.setBrightnessConfigurationForUser(null, mContext.getUserId(),
+        mPersistentDataStore.setBrightnessConfigurationForUser(null, mContext.getUserId(),
+                mContext.getPackageName());
+        mLogicalDisplayMapper.forEachLocked((logicalDisplay -> {
+            if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
+                return;
+            }
+            final String uniqueId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
+            setBrightnessConfigurationForDisplayInternal(null, uniqueId, mContext.getUserId(),
                     mContext.getPackageName());
-            mLogicalDisplayMapper.forEachLocked((logicalDisplay -> {
-                if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
-                    return;
-                }
-                String uniqueId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
-                setBrightnessConfigurationForDisplayInternal(null, uniqueId, mContext.getUserId(),
-                        mContext.getPackageName());
-            }));
-        }
+        }));
     }
 
     void setAutoBrightnessLoggingEnabled(boolean enabled) {
@@ -2817,16 +2814,15 @@
         }
 
         /**
-         * Returns the list of all enabled display ids, and disabled ones if specified.
+         * Returns the list of all display ids.
          */
         @Override // Binder call
-        public int[] getDisplayIds(boolean includeDisabledDisplays) {
+        public int[] getDisplayIds() {
             final int callingUid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mSyncRoot) {
-                    return mLogicalDisplayMapper.getDisplayIdsLocked(callingUid,
-                            includeDisabledDisplays);
+                    return mLogicalDisplayMapper.getDisplayIdsLocked(callingUid);
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 6a57e40..95c8fef 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -873,7 +873,7 @@
                     }
                 });
         mBrightnessThrottler.resetThrottlingData(
-                mDisplayDeviceConfig.getBrightnessThrottlingData());
+                mDisplayDeviceConfig.getBrightnessThrottlingData(), mUniqueDisplayId);
     }
 
     private void sendUpdatePowerState() {
@@ -1842,7 +1842,7 @@
                 () -> {
                     sendUpdatePowerStateLocked();
                     postBrightnessChangeRunnable();
-                });
+                }, mUniqueDisplayId);
     }
 
     private void blockScreenOn() {
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index 34e8e75..70c9e23 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -79,12 +79,8 @@
     private static final int MSG_TRANSITION_TO_PENDING_DEVICE_STATE = 1;
 
     private static final int UPDATE_STATE_NEW = 0;
-    private static final int UPDATE_STATE_UPDATED = 1;
-    private static final int UPDATE_STATE_DISABLED = 2;
-
-    private static final int UPDATE_STATE_MASK = 0x3;
-
-    private static final int UPDATE_STATE_FLAG_TRANSITION = 0x100;
+    private static final int UPDATE_STATE_TRANSITION = 1;
+    private static final int UPDATE_STATE_UPDATED = 2;
 
     /**
      * Temporary display info, used for comparing display configurations.
@@ -170,7 +166,7 @@
 
     LogicalDisplayMapper(@NonNull Context context, @NonNull DisplayDeviceRepository repo,
             @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot,
-            @NonNull Handler handler, @NonNull DeviceStateToLayoutMap deviceStateToLayoutMap) {
+            @NonNull Handler handler) {
         mSyncRoot = syncRoot;
         mPowerManager = context.getSystemService(PowerManager.class);
         mInteractive = mPowerManager.isInteractive();
@@ -185,7 +181,7 @@
         mDeviceStatesOnWhichToSleep = toSparseBooleanArray(context.getResources().getIntArray(
                 com.android.internal.R.array.config_deviceStatesOnWhichToSleep));
         mDisplayDeviceRepo.addListener(this);
-        mDeviceStateToLayoutMap = deviceStateToLayoutMap;
+        mDeviceStateToLayoutMap = new DeviceStateToLayoutMap();
     }
 
     @Override
@@ -222,29 +218,10 @@
     }
 
     public LogicalDisplay getDisplayLocked(int displayId) {
-        return getDisplayLocked(displayId, /* includeDisabled= */ false);
-    }
-
-    LogicalDisplay getDisplayLocked(int displayId, boolean includeDisabled) {
-        LogicalDisplay display = mLogicalDisplays.get(displayId);
-        if (display != null && (display.isEnabled() || includeDisabled)) {
-            return display;
-        }
-        return null;
+        return mLogicalDisplays.get(displayId);
     }
 
     public LogicalDisplay getDisplayLocked(DisplayDevice device) {
-        return getDisplayLocked(device, /* includeDisabled= */ false);
-    }
-
-    /**
-     * Loops through the existing list of displays and returns one that is associated with the
-     * specified display device.
-     *
-     * @param device The display device that should be associated with the LogicalDisplay.
-     * @param includeDisabled True if this method should return disabled displays as well.
-     */
-    private LogicalDisplay getDisplayLocked(DisplayDevice device, boolean includeDisabled) {
         if (device == null) {
             return null;
         }
@@ -252,32 +229,18 @@
         for (int i = 0; i < count; i++) {
             final LogicalDisplay display = mLogicalDisplays.valueAt(i);
             if (display.getPrimaryDisplayDeviceLocked() == device) {
-                if (display.isEnabled() || includeDisabled) {
-                    return display;
-                } else {
-                    return null;
-                }
+                return display;
             }
         }
         return null;
     }
 
-    // Returns display Ids, defaults to enabled only.
     public int[] getDisplayIdsLocked(int callingUid) {
-        return getDisplayIdsLocked(callingUid, /* includeDisabledDisplays= */ false);
-    }
-
-    // Returns display Ids, specified whether enabled only, or all displays.
-    public int[] getDisplayIdsLocked(int callingUid, boolean includeDisabledDisplays) {
         final int count = mLogicalDisplays.size();
         int[] displayIds = new int[count];
         int n = 0;
         for (int i = 0; i < count; i++) {
             LogicalDisplay display = mLogicalDisplays.valueAt(i);
-            if (!includeDisabledDisplays && !display.isEnabled()) {
-                continue; // Ignore disabled displays.
-            }
-
             DisplayInfo info = display.getDisplayInfoLocked();
             if (info.hasAccess(callingUid)) {
                 displayIds[n++] = mLogicalDisplays.keyAt(i);
@@ -292,10 +255,7 @@
     public void forEachLocked(Consumer<LogicalDisplay> consumer) {
         final int count = mLogicalDisplays.size();
         for (int i = 0; i < count; i++) {
-            LogicalDisplay display = mLogicalDisplays.valueAt(i);
-            if (display.isEnabled()) {
-                consumer.accept(display);
-            }
+            consumer.accept(mLogicalDisplays.valueAt(i));
         }
     }
 
@@ -356,8 +316,7 @@
 
             // Find or create the LogicalDisplay to map the DisplayDevice to.
             final int logicalDisplayId = displayLayout.getLogicalDisplayId();
-            final LogicalDisplay logicalDisplay =
-                    getDisplayLocked(logicalDisplayId, /* includeDisabled= */ true);
+            final LogicalDisplay logicalDisplay = getDisplayLocked(logicalDisplayId);
             if (logicalDisplay == null) {
                 Slog.w(TAG, "The logical display (" + address + "), is not available"
                         + " for the display state " + deviceState);
@@ -493,7 +452,7 @@
     }
 
     /**
-     * Returns true if the device should be put to sleep or not.
+     * Returns if the device should be put to sleep or not.
      *
      * Includes a check to verify that the device state that we are moving to, {@code pendingState},
      * is the same as the physical state of the device, {@code baseState}. Different values for
@@ -639,12 +598,9 @@
             display.getNonOverrideDisplayInfoLocked(mTempNonOverrideDisplayInfo);
 
             display.updateLocked(mDisplayDeviceRepo);
-            DisplayInfo newDisplayInfo = display.getDisplayInfoLocked();
-
-            final int storedState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW);
-            final int updateState = storedState & UPDATE_STATE_MASK;
-            final boolean isTransitioning = (storedState & UPDATE_STATE_FLAG_TRANSITION) != 0;
-            final boolean wasPreviouslyUpdated = updateState == UPDATE_STATE_UPDATED;
+            final DisplayInfo newDisplayInfo = display.getDisplayInfoLocked();
+            final int updateState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW);
+            final boolean wasPreviouslyUpdated = updateState != UPDATE_STATE_NEW;
 
             // The display is no longer valid and needs to be removed.
             if (!display.isValidLocked()) {
@@ -668,35 +624,6 @@
                 }
                 continue;
 
-            // The display has been newly disabled, we report this as a removed display but
-            // don't actually remove it from our internal list in LogicalDisplayMapper. The reason
-            // is that LogicalDisplayMapper assumes and relies on the fact that every DisplayDevice
-            // has a LogicalDisplay wrapper, but certain displays that are unusable (like the inner
-            // display on a folded foldable device) are not available for use by the system and
-            // we keep them hidden. To do this, we mark those LogicalDisplays as "disabled".
-            // Also, if the display is in TRANSITION but was previously reported as disabled
-            // then keep it unreported.
-            } else if (!display.isEnabled()
-                    || (display.getPhase() == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION
-                        && updateState == UPDATE_STATE_DISABLED)) {
-                mUpdatedLogicalDisplays.put(displayId, UPDATE_STATE_DISABLED);
-
-                // If we never told anyone about this display, nothing to do
-                if (!wasPreviouslyUpdated) {
-                    continue;
-                }
-
-                // Remove from group
-                final DisplayGroup displayGroup = getDisplayGroupLocked(
-                        getDisplayGroupIdFromDisplayIdLocked(displayId));
-                if (displayGroup != null) {
-                    displayGroup.removeDisplayLocked(display);
-                }
-
-                Slog.i(TAG, "Removing (disabled) display: " + displayId);
-                mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_REMOVED);
-                continue;
-
             // The display is new.
             } else if (!wasPreviouslyUpdated) {
                 Slog.i(TAG, "Adding new display: " + displayId + ": " + newDisplayInfo);
@@ -716,7 +643,7 @@
                 mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CHANGED);
 
             // The display is involved in a display layout transition
-            } else if (isTransitioning) {
+            } else if (updateState == UPDATE_STATE_TRANSITION) {
                 mLogicalDisplaysToUpdate.put(displayId,
                         LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION);
 
@@ -790,7 +717,7 @@
             }
 
             final int id = mLogicalDisplaysToUpdate.keyAt(i);
-            final LogicalDisplay display = getDisplayLocked(id, /* includeDisabled= */ true);
+            final LogicalDisplay display = getDisplayLocked(id);
             if (DEBUG) {
                 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
                 final String uniqueId = device == null ? "null" : device.getUniqueId();
@@ -798,7 +725,7 @@
                         + " with device=" + uniqueId);
             }
             mListener.onLogicalDisplayEventLocked(display, msg);
-            if (msg == LOGICAL_DISPLAY_EVENT_REMOVED && !display.isValidLocked()) {
+            if (msg == LOGICAL_DISPLAY_EVENT_REMOVED) {
                 // We wait until we sent the EVENT_REMOVED event before actually removing the
                 // display.
                 mLogicalDisplays.delete(id);
@@ -918,8 +845,7 @@
             if (isTransitioning) {
                 setDisplayPhase(logicalDisplay, phase);
                 if (phase == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION) {
-                    int oldState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW);
-                    mUpdatedLogicalDisplays.put(displayId, oldState | UPDATE_STATE_FLAG_TRANSITION);
+                    mUpdatedLogicalDisplays.put(displayId, UPDATE_STATE_TRANSITION);
                 }
             }
         }
@@ -953,15 +879,14 @@
             // Now that we have a display-device, we need a LogicalDisplay to map it to. Find the
             // right one, if it doesn't exist, create a new one.
             final int logicalDisplayId = displayLayout.getLogicalDisplayId();
-            LogicalDisplay newDisplay =
-                    getDisplayLocked(logicalDisplayId, /* includeDisabled= */ true);
+            LogicalDisplay newDisplay = getDisplayLocked(logicalDisplayId);
             if (newDisplay == null) {
                 newDisplay = createNewLogicalDisplayLocked(
-                        /* displayDevice= */ null, logicalDisplayId);
+                        null /*displayDevice*/, logicalDisplayId);
             }
 
             // Now swap the underlying display devices between the old display and the new display
-            final LogicalDisplay oldDisplay = getDisplayLocked(device, /* includeDisabled= */ true);
+            final LogicalDisplay oldDisplay = getDisplayLocked(device);
             if (newDisplay != oldDisplay) {
                 newDisplay.swapDisplaysLocked(oldDisplay);
             }
@@ -978,14 +903,13 @@
      * Creates a new logical display for the specified device and display Id and adds it to the list
      * of logical displays.
      *
-     * @param displayDevice The displayDevice to associate with the LogicalDisplay.
+     * @param device The device to associate with the LogicalDisplay.
      * @param displayId The display ID to give the new display. If invalid, a new ID is assigned.
      * @return The new logical display if created, null otherwise.
      */
-    private LogicalDisplay createNewLogicalDisplayLocked(DisplayDevice displayDevice,
-            int displayId) {
+    private LogicalDisplay createNewLogicalDisplayLocked(DisplayDevice device, int displayId) {
         final int layerStack = assignLayerStackLocked(displayId);
-        final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, displayDevice);
+        final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
         display.updateLocked(mDisplayDeviceRepo);
         mLogicalDisplays.put(displayId, display);
         setDisplayPhase(display, LogicalDisplay.DISPLAY_PHASE_ENABLED);
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 8de150a..223b8c1 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -956,6 +956,8 @@
                         R.array.config_availableColorModes);
                 if (availableColorModes.length > 0) {
                     colorMode = availableColorModes[0];
+                } else {
+                    colorMode = NOT_SET;
                 }
             }
         }
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 098e8f7..7d12ede 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -46,7 +46,6 @@
 import android.util.ArrayMap;
 import android.util.Slog;
 import android.view.ContentRecordingSession;
-import android.window.WindowContainerToken;
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
@@ -433,7 +432,7 @@
         private IBinder mToken;
         private IBinder.DeathRecipient mDeathEater;
         private boolean mRestoreSystemAlertWindow;
-        private WindowContainerToken mTaskRecordingWindowContainerToken = null;
+        private IBinder mLaunchCookie = null;
 
         MediaProjection(int type, int uid, String packageName, int targetSdkVersion,
                 boolean isPrivileged) {
@@ -609,14 +608,13 @@
         }
 
         @Override // Binder call
-        public void setTaskRecordingWindowContainerToken(WindowContainerToken token) {
-            // TODO(b/221417940) set the task id to record from sysui, for the package chosen.
-            mTaskRecordingWindowContainerToken = token;
+        public void setLaunchCookie(IBinder launchCookie) {
+            mLaunchCookie = launchCookie;
         }
 
         @Override // Binder call
-        public WindowContainerToken getTaskRecordingWindowContainerToken() {
-            return mTaskRecordingWindowContainerToken;
+        public IBinder getLaunchCookie() {
+            return mLaunchCookie;
         }
 
         public MediaProjectionInfo getProjectionInfo() {
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index e6bc796..5a40b30 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -1447,6 +1447,16 @@
         }
     }
 
+    @VisibleForTesting
+    void reregisterService(final ComponentName cn, final int userId) {
+        // If rebinding a package that died, ensure it still has permission
+        // after the rebind delay
+        if (isPackageOrComponentAllowed(cn.getPackageName(), userId)
+                || isPackageOrComponentAllowed(cn.flattenToString(), userId)) {
+            registerService(cn, userId);
+        }
+    }
+
     /**
      * Inject a system service into the management list.
      */
@@ -1545,12 +1555,9 @@
                         unbindService(this, name, userid);
                         if (!mServicesRebinding.contains(servicesBindingTag)) {
                             mServicesRebinding.add(servicesBindingTag);
-                            mHandler.postDelayed(new Runnable() {
-                                    @Override
-                                    public void run() {
-                                        registerService(name, userid);
-                                    }
-                               }, ON_BINDING_DIED_REBIND_DELAY_MS);
+                            mHandler.postDelayed(() ->
+                                    reregisterService(name, userid),
+                                    ON_BINDING_DIED_REBIND_DELAY_MS);
                         } else {
                             Slog.v(TAG, getCaption() + " not rebinding in user " + userid
                                     + " as a previous rebind attempt was made: " + name);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d1e0b04..fdb31b2e 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -517,7 +517,7 @@
     private ActivityManagerInternal mAmi;
     private IPackageManager mPackageManager;
     private PackageManager mPackageManagerClient;
-    private PackageManagerInternal mPackageManagerInternal;
+    PackageManagerInternal mPackageManagerInternal;
     private PermissionPolicyInternal mPermissionPolicyInternal;
     AudioManager mAudioManager;
     AudioManagerInternal mAudioManagerInternal;
@@ -9798,7 +9798,7 @@
      * notifications visible to the given listener.
      */
     @GuardedBy("mNotificationLock")
-    private NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
+    NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
         final int N = mNotificationList.size();
         final ArrayList<NotificationListenerService.Ranking> rankings = new ArrayList<>();
 
@@ -10913,7 +10913,7 @@
                 TrimCache trimCache = new TrimCache(sbn);
 
                 for (final ManagedServiceInfo info : getServices()) {
-                    boolean sbnVisible = isVisibleToListener(sbn, r. getNotificationType(), info);
+                    boolean sbnVisible = isVisibleToListener(sbn, r.getNotificationType(), info);
                     boolean oldSbnVisible = (oldSbn != null)
                             && isVisibleToListener(oldSbn, old.getNotificationType(), info);
                     // This notification hasn't been and still isn't visible -> ignore.
@@ -10943,12 +10943,17 @@
                                 info, oldSbnLightClone, update, null, REASON_USER_STOPPED));
                         continue;
                     }
-
                     // Grant access before listener is notified
                     final int targetUserId = (info.userid == UserHandle.USER_ALL)
                             ? UserHandle.USER_SYSTEM : info.userid;
                     updateUriPermissions(r, old, info.component.getPackageName(), targetUserId);
 
+                    mPackageManagerInternal.grantImplicitAccess(
+                            targetUserId, null /* intent */,
+                            UserHandle.getAppId(info.uid),
+                            sbn.getUid(),
+                            false /* direct */, false /* retainOnUpdate */);
+
                     final StatusBarNotification sbnToPost = trimCache.ForListener(info);
                     mHandler.post(() -> notifyPosted(info, sbnToPost, update));
                 }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 9e0c975..6135fe8 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -121,6 +121,7 @@
     protected final RingerModeDelegate mRingerModeDelegate = new
             RingerModeDelegate();
     @VisibleForTesting protected final ZenModeConditions mConditions;
+    Object mConfigsLock = new Object();
     @VisibleForTesting final SparseArray<ZenModeConfig> mConfigs = new SparseArray<>();
     private final Metrics mMetrics = new Metrics();
     private final ConditionProviders.Config mServiceConfig;
@@ -153,7 +154,9 @@
         mDefaultConfig = readDefaultConfig(mContext.getResources());
         updateDefaultAutomaticRuleNames();
         mConfig = mDefaultConfig.copy();
-        mConfigs.put(UserHandle.USER_SYSTEM, mConfig);
+        synchronized (mConfigsLock) {
+            mConfigs.put(UserHandle.USER_SYSTEM, mConfig);
+        }
         mConsolidatedPolicy = mConfig.toNotificationPolicy();
 
         mSettingsObserver = new SettingsObserver(mHandler);
@@ -233,7 +236,9 @@
     public void onUserRemoved(int user) {
         if (user < UserHandle.USER_SYSTEM) return;
         if (DEBUG) Log.d(TAG, "onUserRemoved u=" + user);
-        mConfigs.remove(user);
+        synchronized (mConfigsLock) {
+            mConfigs.remove(user);
+        }
     }
 
     public void onUserUnlocked(int user) {
@@ -248,7 +253,12 @@
         if (mUser == user || user < UserHandle.USER_SYSTEM) return;
         mUser = user;
         if (DEBUG) Log.d(TAG, reason + " u=" + user);
-        ZenModeConfig config = mConfigs.get(user);
+        ZenModeConfig config = null;
+        synchronized (mConfigsLock) {
+            if (mConfigs.get(user) != null) {
+                config = mConfigs.get(user).copy();
+            }
+        }
         if (config == null) {
             if (DEBUG) Log.d(TAG, reason + " generating default config for user " + user);
             config = mDefaultConfig.copy();
@@ -330,7 +340,8 @@
             int newRuleInstanceCount = getCurrentInstanceCount(automaticZenRule.getOwner())
                     + getCurrentInstanceCount(automaticZenRule.getConfigurationActivity())
                     + 1;
-            if (newRuleInstanceCount > RULE_LIMIT_PER_PACKAGE
+            int newPackageRuleCount = getPackageRuleCount(pkg) + 1;
+            if (newPackageRuleCount > RULE_LIMIT_PER_PACKAGE
                     || (ruleInstanceLimit > 0 && ruleInstanceLimit < newRuleInstanceCount)) {
                 throw new IllegalArgumentException("Rule instance limit exceeded");
             }
@@ -511,6 +522,23 @@
         return count;
     }
 
+    // Equivalent method to getCurrentInstanceCount, but for all rules associated with a specific
+    // package rather than a condition provider service or activity.
+    private int getPackageRuleCount(String pkg) {
+        if (pkg == null) {
+            return 0;
+        }
+        int count = 0;
+        synchronized (mConfig) {
+            for (ZenRule rule : mConfig.automaticRules.values()) {
+                if (pkg.equals(rule.getPkg())) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+
     public boolean canManageAutomaticZenRule(ZenRule rule) {
         final int callingUid = Binder.getCallingUid();
         if (callingUid == 0 || callingUid == Process.SYSTEM_UID) {
@@ -685,9 +713,11 @@
         pw.println(Global.zenModeToString(mZenMode));
         pw.print(prefix);
         pw.println("mConsolidatedPolicy=" + mConsolidatedPolicy.toString());
-        final int N = mConfigs.size();
-        for (int i = 0; i < N; i++) {
-            dump(pw, prefix, "mConfigs[u=" + mConfigs.keyAt(i) + "]", mConfigs.valueAt(i));
+        synchronized(mConfigsLock) {
+            final int N = mConfigs.size();
+            for (int i = 0; i < N; i++) {
+                dump(pw, prefix, "mConfigs[u=" + mConfigs.keyAt(i) + "]", mConfigs.valueAt(i));
+            }
         }
         pw.print(prefix); pw.print("mUser="); pw.println(mUser);
         synchronized (mConfig) {
@@ -787,7 +817,7 @@
 
     public void writeXml(TypedXmlSerializer out, boolean forBackup, Integer version, int userId)
             throws IOException {
-        synchronized (mConfigs) {
+        synchronized (mConfigsLock) {
             final int n = mConfigs.size();
             for (int i = 0; i < n; i++) {
                 if (forBackup && mConfigs.keyAt(i) != userId) {
@@ -883,14 +913,18 @@
             }
             if (config.user != mUser) {
                 // simply store away for background users
-                mConfigs.put(config.user, config);
+                synchronized (mConfigsLock) {
+                    mConfigs.put(config.user, config);
+                }
                 if (DEBUG) Log.d(TAG, "setConfigLocked: store config for user " + config.user);
                 return true;
             }
             // handle CPS backed conditions - danger! may modify config
             mConditions.evaluateConfig(config, null, false /*processSubscriptions*/);
 
-            mConfigs.put(config.user, config);
+            synchronized (mConfigsLock) {
+                mConfigs.put(config.user, config);
+            }
             if (DEBUG) Log.d(TAG, "setConfigLocked reason=" + reason, new Throwable());
             ZenLog.traceConfig(reason, mConfig, config);
 
@@ -1211,7 +1245,7 @@
      * Generate pulled atoms about do not disturb configurations.
      */
     public void pullRules(List<StatsEvent> events) {
-        synchronized (mConfig) {
+        synchronized (mConfigsLock) {
             final int numConfigs = mConfigs.size();
             for (int i = 0; i < numConfigs; i++) {
                 final int user = mConfigs.keyAt(i);
diff --git a/services/core/java/com/android/server/pm/ShortcutLauncher.java b/services/core/java/com/android/server/pm/ShortcutLauncher.java
index c0c2349..c6a7dd7 100644
--- a/services/core/java/com/android/server/pm/ShortcutLauncher.java
+++ b/services/core/java/com/android/server/pm/ShortcutLauncher.java
@@ -144,8 +144,8 @@
             final ArraySet<String> prevSet = mPinnedShortcuts.get(pu);
 
             // Actually pin shortcuts.
-            // This logic here is to make sure a launcher cannot pin a shortcut that is floating
-            // (i.e. not dynamic nor manifest but is pinned) and pinned by another launcher.
+            // This logic here is to make sure a launcher cannot pin a shortcut that is not dynamic
+            // nor long-lived nor manifest but is pinned.
             // In this case, technically the shortcut doesn't exist to this launcher, so it can't
             // pin it.
             // (Maybe unnecessarily strict...)
@@ -158,7 +158,7 @@
                 if (si == null) {
                     continue;
                 }
-                if (si.isDynamic()
+                if (si.isDynamic() || si.isLongLived()
                         || si.isManifestShortcut()
                         || (prevSet != null && prevSet.contains(id))
                         || forPinRequest) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 9de485b..409ca03 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1878,6 +1878,44 @@
     }
 
     @Override
+    public boolean setUserEphemeral(@UserIdInt int userId, boolean enableEphemeral) {
+        checkCreateUsersPermission("update ephemeral user flag");
+        UserData userToUpdate = null;
+        synchronized (mPackagesLock) {
+            synchronized (mUsersLock) {
+                final UserData userData = mUsers.get(userId);
+                if (userData == null) {
+                    Slog.e(LOG_TAG, "User not found for setting ephemeral mode: u" + userId);
+                    return false;
+                }
+                boolean isEphemeralUser = (userData.info.flags & UserInfo.FLAG_EPHEMERAL) != 0;
+                boolean isEphemeralOnCreateUser =
+                        (userData.info.flags & UserInfo.FLAG_EPHEMERAL_ON_CREATE) != 0;
+                // when user is created in ephemeral mode via FLAG_EPHEMERAL
+                // its state cannot be changed to non ephemeral.
+                // FLAG_EPHEMERAL_ON_CREATE is used to keep track of this state
+                if (isEphemeralOnCreateUser && !enableEphemeral) {
+                    Slog.e(LOG_TAG, "Failed to change user state to non-ephemeral for user "
+                            + userId);
+                    return false;
+                }
+                if (isEphemeralUser != enableEphemeral) {
+                    if (enableEphemeral) {
+                        userData.info.flags |= UserInfo.FLAG_EPHEMERAL;
+                    } else {
+                        userData.info.flags &= ~UserInfo.FLAG_EPHEMERAL;
+                    }
+                    userToUpdate = userData;
+                }
+            }
+            if (userToUpdate != null) {
+                writeUserLP(userToUpdate);
+            }
+        }
+        return true;
+    }
+
+    @Override
     public void setUserIcon(@UserIdInt int userId, Bitmap bitmap) {
         try {
             checkManageUsersPermission("update users");
@@ -3984,6 +4022,10 @@
                         flags &= ~UserInfo.FLAG_EPHEMERAL;
                     }
 
+                    if ((flags & UserInfo.FLAG_EPHEMERAL) != 0) {
+                        flags |= UserInfo.FLAG_EPHEMERAL_ON_CREATE;
+                    }
+
                     userInfo = new UserInfo(userId, name, null, flags, userType);
                     userInfo.serialNumber = mNextSerialNumber++;
                     userInfo.creationTime = getCreationTime();
diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
index 88b4a94..03e568c 100644
--- a/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionManagerService.java
@@ -413,8 +413,8 @@
                 return result;
             }
             mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(
-                    AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, uid, packageName,
-                    attributionTag, reason);
+                    AppOpsManager.OP_RECORD_AUDIO_HOTWORD, uid, packageName, attributionTag,
+                    reason);
             return result;
         }
     }
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index a6d148c..ebd9126 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -202,9 +202,8 @@
     }
 
     private static boolean isHotwordDetectionServiceRequired(PackageManager pm) {
-        // The HotwordDetectionService APIs aren't ready yet for Auto or TV.
-        return !(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
-                || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
+        // Usage of the HotwordDetectionService won't be enforced until a later release.
+        return false;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d8e7fbe..d88949b 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -169,7 +169,6 @@
 import android.view.Display;
 import android.view.HapticFeedbackConstants;
 import android.view.IDisplayFoldListener;
-import android.view.IWindowManager;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyCharacterMap.FallbackAction;
@@ -381,7 +380,6 @@
     private final SparseArray<ScreenOnListener> mScreenOnListeners = new SparseArray<>();
 
     Context mContext;
-    IWindowManager mWindowManager;
     WindowManagerFuncs mWindowManagerFuncs;
     WindowManagerInternal mWindowManagerInternal;
     PowerManager mPowerManager;
@@ -1870,10 +1868,8 @@
 
     /** {@inheritDoc} */
     @Override
-    public void init(Context context, IWindowManager windowManager,
-            WindowManagerFuncs windowManagerFuncs) {
+    public void init(Context context, WindowManagerFuncs windowManagerFuncs) {
         mContext = context;
-        mWindowManager = windowManager;
         mWindowManagerFuncs = windowManagerFuncs;
         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
@@ -4534,7 +4530,6 @@
                                     pmWakeReason)) + ")");
         }
 
-        mActivityTaskManagerInternal.notifyWakingUp();
         mDefaultDisplayPolicy.setAwake(true);
 
         // Since goToSleep performs these functions synchronously, we must
@@ -4802,10 +4797,7 @@
         }
 
         if (enableScreen) {
-            try {
-                mWindowManager.enableScreenIfNeeded();
-            } catch (RemoteException unhandled) {
-            }
+            mWindowManagerFuncs.enableScreenIfNeeded();
         }
     }
 
@@ -5262,12 +5254,7 @@
     }
 
     void updateRotation(boolean alwaysSendConfiguration) {
-        try {
-            // Set orientation on WindowManager.
-            mWindowManager.updateRotation(alwaysSendConfiguration, false /* forceRelayout */);
-        } catch (RemoteException e) {
-            // Ignore
-        }
+        mWindowManagerFuncs.updateRotation(alwaysSendConfiguration, false /* forceRelayout */);
     }
 
     /**
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 8917813..9bc0553 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -78,7 +78,6 @@
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
 import android.view.IDisplayFoldListener;
-import android.view.IWindowManager;
 import android.view.KeyEvent;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
@@ -347,6 +346,22 @@
          * @return {@code true} if app transition state is idle on the default display.
          */
         boolean isAppTransitionStateIdle();
+
+        /**
+         * Enables the screen if all conditions are met.
+         */
+        void enableScreenIfNeeded();
+
+        /**
+         * Updates the current screen rotation based on the current state of the world.
+         *
+         * @param alwaysSendConfiguration Flag to force a new configuration to be evaluated.
+         *                                This can be used when there are other parameters in
+         *                                configuration that are changing.
+         * @param forceRelayout If true, the window manager will always do a relayout of its
+         *                      windows even if the rotation hasn't changed.
+         */
+        void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout);
     }
 
     /**
@@ -395,8 +410,7 @@
      *
      * @param context The system context we are running in.
      */
-    public void init(Context context, IWindowManager windowManager,
-            WindowManagerFuncs windowManagerFuncs);
+    void init(Context context, WindowManagerFuncs windowManagerFuncs);
 
     /**
      * Check permissions when adding a window.
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 8c52717..50d1bd6 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -112,6 +112,7 @@
 import com.android.internal.display.BrightnessSynchronizer;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.DumpUtils;
+import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.util.Preconditions;
 import com.android.server.EventLogTags;
@@ -4960,6 +4961,7 @@
                 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
                         Intent.EXTRA_DOCK_STATE_UNDOCKED);
                 if (mDockState != dockState) {
+                    FrameworkStatsLog.write(FrameworkStatsLog.DOCK_STATE_CHANGED, dockState);
                     mDockState = dockState;
                     mDirty |= DIRTY_DOCK_STATE;
                     updatePowerStateLocked();
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
index 13fe14c..6318a99 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java
@@ -21,6 +21,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.PermissionChecker;
 import android.media.permission.Identity;
@@ -115,8 +116,10 @@
      * originator temporarily doesn't have the right permissions to use this service.
      */
     private void enforcePermissionsForPreflight(@NonNull Identity identity) {
-        enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO);
-        enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD);
+        enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO,
+                /* allowSoftDenial= */ true);
+        enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD,
+                /* allowSoftDenial= */ true);
     }
 
     /**
@@ -124,8 +127,7 @@
      */
     void enforcePermissionsForDataDelivery(@NonNull Identity identity, @NonNull String reason) {
         enforceSoundTriggerRecordAudioPermissionForDataDelivery(identity, reason);
-        enforcePermissionForDataDelivery(mContext, identity, CAPTURE_AUDIO_HOTWORD,
-                reason);
+        enforcePermissionForDataDelivery(mContext, identity, CAPTURE_AUDIO_HOTWORD, reason);
     }
 
     /**
@@ -165,20 +167,25 @@
     /**
      * Throws a {@link SecurityException} if originator permanently doesn't have the given
      * permission.
-     * Soft (temporary) denials are considered OK for preflight purposes.
      *
-     * @param context    A {@link Context}, used for permission checks.
-     * @param identity   The identity to check.
-     * @param permission The identifier of the permission we want to check.
+     * @param context         A {@link Context}, used for permission checks.
+     * @param identity        The identity to check.
+     * @param permission      The identifier of the permission we want to check.
+     * @param allowSoftDenial If true, the operation succeeds even for soft (temporary) denials.
      */
+    // TODO: Consider splitting up this method instead of using `allowSoftDenial`, to make it
+    // clearer when soft denials are not allowed.
     private static void enforcePermissionForPreflight(@NonNull Context context,
-            @NonNull Identity identity, @NonNull String permission) {
+            @NonNull Identity identity, @NonNull String permission, boolean allowSoftDenial) {
         final int status = PermissionUtil.checkPermissionForPreflight(context, identity,
                 permission);
         switch (status) {
             case PermissionChecker.PERMISSION_GRANTED:
-            case PermissionChecker.PERMISSION_SOFT_DENIED:
                 return;
+            case PermissionChecker.PERMISSION_SOFT_DENIED:
+                if (allowSoftDenial) {
+                    return;
+                } // else fall through
             case PermissionChecker.PERMISSION_HARD_DENIED:
                 throw new SecurityException(
                         String.format("Failed to obtain permission %s for identity %s", permission,
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index 78b1c20..d79837b 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -61,12 +61,11 @@
         IGNORED_BACKGROUND,
         IGNORED_UNKNOWN_VIBRATION,
         IGNORED_UNSUPPORTED,
-        IGNORED_FOR_ALARM,
         IGNORED_FOR_EXTERNAL,
+        IGNORED_FOR_HIGHER_IMPORTANCE,
         IGNORED_FOR_ONGOING,
         IGNORED_FOR_POWER,
         IGNORED_FOR_RINGER_MODE,
-        IGNORED_FOR_RINGTONE,
         IGNORED_FOR_SETTINGS,
         IGNORED_SUPERSEDED,
     }
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index f0911ca..5ac2f4f 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -713,16 +713,17 @@
             case IGNORED_ERROR_APP_OPS:
                 Slog.w(TAG, "Would be an error: vibrate from uid " + uid);
                 break;
-            case IGNORED_FOR_ALARM:
-                if (DEBUG) {
-                    Slog.d(TAG, "Ignoring incoming vibration in favor of alarm vibration");
-                }
-                break;
             case IGNORED_FOR_EXTERNAL:
                 if (DEBUG) {
                     Slog.d(TAG, "Ignoring incoming vibration for current external vibration");
                 }
                 break;
+            case IGNORED_FOR_HIGHER_IMPORTANCE:
+                if (DEBUG) {
+                    Slog.d(TAG, "Ignoring incoming vibration in favor of ongoing vibration"
+                            + " with higher importance");
+                }
+                break;
             case IGNORED_FOR_ONGOING:
                 if (DEBUG) {
                     Slog.d(TAG, "Ignoring incoming vibration in favor of repeating vibration");
@@ -734,12 +735,6 @@
                             + attrs);
                 }
                 break;
-            case IGNORED_FOR_RINGTONE:
-                if (DEBUG) {
-                    Slog.d(TAG, "Ignoring incoming vibration in favor of ringtone vibration");
-                }
-                break;
-
             default:
                 if (DEBUG) {
                     Slog.d(TAG, "Vibration for uid=" + uid + " and with attrs=" + attrs
@@ -812,20 +807,43 @@
             return null;
         }
 
-        if (currentVibration.attrs.getUsage() == VibrationAttributes.USAGE_ALARM) {
-            return Vibration.Status.IGNORED_FOR_ALARM;
-        }
-
-        if (currentVibration.attrs.getUsage() == VibrationAttributes.USAGE_RINGTONE) {
-            return Vibration.Status.IGNORED_FOR_RINGTONE;
+        int currentUsage = currentVibration.attrs.getUsage();
+        int newUsage = vib.attrs.getUsage();
+        if (getVibrationImportance(currentUsage) > getVibrationImportance(newUsage)) {
+            // Current vibration has higher importance than this one and should not be cancelled.
+            return Vibration.Status.IGNORED_FOR_HIGHER_IMPORTANCE;
         }
 
         if (currentVibration.isRepeating()) {
+            // Current vibration is repeating, assume it's more important.
             return Vibration.Status.IGNORED_FOR_ONGOING;
         }
+
         return null;
     }
 
+    private static int getVibrationImportance(@VibrationAttributes.Usage int usage) {
+        switch (usage) {
+            case VibrationAttributes.USAGE_RINGTONE:
+                return 5;
+            case VibrationAttributes.USAGE_ALARM:
+                return 4;
+            case VibrationAttributes.USAGE_NOTIFICATION:
+                return 3;
+            case VibrationAttributes.USAGE_COMMUNICATION_REQUEST:
+            case VibrationAttributes.USAGE_ACCESSIBILITY:
+                return 2;
+            case VibrationAttributes.USAGE_HARDWARE_FEEDBACK:
+            case VibrationAttributes.USAGE_PHYSICAL_EMULATION:
+                return 1;
+            case VibrationAttributes.USAGE_MEDIA:
+            case VibrationAttributes.USAGE_TOUCH:
+            case VibrationAttributes.USAGE_UNKNOWN:
+            default:
+                return 0;
+        }
+    }
+
     /**
      * Check if given vibration should be ignored by this service.
      *
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index f6748de..1ccdaf7 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -43,6 +43,7 @@
 import static com.android.server.wm.ActivityTaskManagerService.TAG_SWITCH;
 import static com.android.server.wm.ActivityTaskManagerService.enforceNotIsolatedCaller;
 
+import android.Manifest;
 import android.annotation.ColorInt;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -462,8 +463,8 @@
                     // Explicitly dismissing the activity so reset its relaunch flag.
                     r.mRelaunchReason = RELAUNCH_REASON_NONE;
                 } else {
-                    r.finishIfPossible(resultCode, resultData, resultGrants,
-                            "app-request", true /* oomAdj */);
+                    r.finishIfPossible(resultCode, resultData, resultGrants, "app-request",
+                            true /* oomAdj */);
                     res = r.finishing;
                     if (!res) {
                         Slog.i(TAG, "Failed to finish by app-request");
@@ -525,6 +526,23 @@
     }
 
     @Override
+    public void setForceSendResultForMediaProjection(IBinder token) {
+        // Require that this is invoked only during MediaProjection setup.
+        mService.mAmInternal.enforceCallingPermission(
+                Manifest.permission.MANAGE_MEDIA_PROJECTION,
+                "setForceSendResultForMediaProjection");
+
+        final ActivityRecord r;
+        synchronized (mGlobalLock) {
+            r = ActivityRecord.isInRootTaskLocked(token);
+            if (r == null || !r.isInHistory()) {
+                return;
+            }
+            r.setForceSendResultForMediaProjection();
+        }
+    }
+
+    @Override
     public boolean isTopOfTask(IBinder token) {
         synchronized (mGlobalLock) {
             final ActivityRecord r = ActivityRecord.isInRootTaskLocked(token);
@@ -737,7 +755,7 @@
             synchronized (mGlobalLock) {
                 final ActivityRecord r = ensureValidPictureInPictureActivityParams(
                         "enterPictureInPictureMode", token, params);
-                return mService.enterPictureInPictureMode(r, params);
+                return mService.enterPictureInPictureMode(r, params, true /* fromClient */);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -853,22 +871,23 @@
     /**
      * Requests that an activity should enter picture-in-picture mode if possible. This method may
      * be used by the implementation of non-phone form factors.
+     *
+     * @return false if the activity cannot enter PIP mode.
      */
-    void requestPictureInPictureMode(@NonNull ActivityRecord r) {
+    boolean requestPictureInPictureMode(@NonNull ActivityRecord r) {
         if (r.inPinnedWindowingMode()) {
-            throw new IllegalStateException("Activity is already in PIP mode");
+            return false;
         }
 
         final boolean canEnterPictureInPicture = r.checkEnterPictureInPictureState(
                 "requestPictureInPictureMode", /* beforeStopping */ false);
         if (!canEnterPictureInPicture) {
-            throw new IllegalStateException(
-                    "Requested PIP on an activity that doesn't support it");
+            return false;
         }
 
         if (r.pictureInPictureArgs.isAutoEnterEnabled()) {
-            mService.enterPictureInPictureMode(r, r.pictureInPictureArgs);
-            return;
+            return mService.enterPictureInPictureMode(r, r.pictureInPictureArgs,
+                    false /* fromClient */);
         }
 
         try {
@@ -876,9 +895,11 @@
                     r.app.getThread(), r.token);
             transaction.addCallback(EnterPipRequestedItem.obtain());
             mService.getLifecycleManager().scheduleTransaction(transaction);
+            return true;
         } catch (Exception e) {
             Slog.w(TAG, "Failed to send enter pip requested item: "
                     + r.intent.getComponent(), e);
+            return false;
         }
     }
 
@@ -928,6 +949,7 @@
 
                 if (rootTask.inFreeformWindowingMode()) {
                     rootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+                    rootTask.setBounds(null);
                 } else if (!r.supportsFreeform()) {
                     throw new IllegalStateException(
                             "This activity is currently not freeform-enabled");
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index d6c0ab6..270891f 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -56,6 +56,10 @@
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_WARM_LAUNCH;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__NOT_LETTERBOXED_POSITION;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_ASPECT_RATIO;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_FIXED_ORIENTATION;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE;
 import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__NOT_LETTERBOXED;
 import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE;
 import static com.android.internal.util.FrameworkStatsLog.CAMERA_COMPAT_CONTROL_EVENT_REPORTED__EVENT__APPEARED_APPLY_TREATMENT;
@@ -68,6 +72,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
 import static com.android.server.wm.EventLogTags.WM_ACTIVITY_LAUNCH_TIME;
 
@@ -101,6 +106,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.util.FrameworkStatsLog;
+import com.android.internal.util.LatencyTracker;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
@@ -780,6 +786,12 @@
             info.mReason = activityToReason.valueAt(index);
             info.mLoggedTransitionStarting = true;
             if (info.mIsDrawn) {
+                if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
+                    final LatencyTracker latencyTracker = r.mWmService.mLatencyTracker;
+                    final int duration = info.mSourceEventDelayMs + info.mCurrentTransitionDelayMs;
+                    mLoggerHandler.post(() -> latencyTracker.logAction(
+                            LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration));
+                }
                 done(false /* abort */, info, "notifyTransitionStarting drawn", timestampNs);
             }
         }
@@ -1368,7 +1380,7 @@
             return;
         }
 
-        logAppCompatStateInternal(activity, state, packageUid, compatStateInfo);
+        logAppCompatStateInternal(activity, state, compatStateInfo);
     }
 
     /**
@@ -1408,18 +1420,61 @@
             }
         }
         if (activityToLog != null && stateToLog != APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE) {
-            logAppCompatStateInternal(activityToLog, stateToLog, packageUid, compatStateInfo);
+            logAppCompatStateInternal(activityToLog, stateToLog, compatStateInfo);
         }
     }
 
+    private static boolean isAppCompateStateChangedToLetterboxed(int state) {
+        return state == APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_ASPECT_RATIO
+                || state == APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_FIXED_ORIENTATION
+                || state == APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE;
+    }
+
     private void logAppCompatStateInternal(@NonNull ActivityRecord activity, int state,
-            int packageUid, PackageCompatStateInfo compatStateInfo) {
+             PackageCompatStateInfo compatStateInfo) {
         compatStateInfo.mLastLoggedState = state;
         compatStateInfo.mLastLoggedActivity = activity;
-        FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPAT_STATE_CHANGED, packageUid, state);
+        int packageUid = activity.info.applicationInfo.uid;
+
+        int positionToLog = APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__NOT_LETTERBOXED_POSITION;
+        if (isAppCompateStateChangedToLetterboxed(state)) {
+            positionToLog = activity.mLetterboxUiController.getLetterboxPositionForLogging();
+        }
+        FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPAT_STATE_CHANGED,
+                packageUid, state, positionToLog);
 
         if (DEBUG_METRICS) {
-            Slog.i(TAG, String.format("APP_COMPAT_STATE_CHANGED(%s, %s)", packageUid, state));
+            Slog.i(TAG, String.format("APP_COMPAT_STATE_CHANGED(%s, %s, %s)",
+                    packageUid, state, positionToLog));
+        }
+    }
+
+    /**
+     * Logs the changing of the letterbox position along with its package UID
+     */
+    void logLetterboxPositionChange(@NonNull ActivityRecord activity, int position) {
+        int packageUid = activity.info.applicationInfo.uid;
+        FrameworkStatsLog.write(FrameworkStatsLog.LETTERBOX_POSITION_CHANGED, packageUid, position);
+
+        if (!mPackageUidToCompatStateInfo.contains(packageUid)) {
+            // There is no last logged activity for this packageUid so we should not log the
+            // position change as we can only log the position change for the current activity
+            return;
+        }
+        final PackageCompatStateInfo compatStateInfo = mPackageUidToCompatStateInfo.get(packageUid);
+        final ActivityRecord lastLoggedActivity = compatStateInfo.mLastLoggedActivity;
+        if (activity != lastLoggedActivity) {
+            // Only log the position change for the current activity to be consistent with
+            // findAppCompatStateToLog and ensure that metrics for the state changes are computed
+            // correctly
+            return;
+        }
+        int state = activity.getAppCompatState();
+        logAppCompatStateInternal(activity, state, compatStateInfo);
+
+        if (DEBUG_METRICS) {
+            Slog.i(TAG, String.format("LETTERBOX_POSITION_CHANGED(%s, %s)",
+                    packageUid, position));
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 4f222a4..62427e1 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -595,6 +595,8 @@
     // pre-NYC apps that don't have a sense of being resized.
     int mRelaunchReason = RELAUNCH_REASON_NONE;
 
+    private boolean mForceSendResultForMediaProjection = false;
+
     TaskDescription taskDescription; // the recents information for this activity
 
     // The locusId associated with this activity, if set.
@@ -925,7 +927,7 @@
     // SystemUi sets the pinned mode on activity after transition is done.
     boolean mWaitForEnteringPinnedMode;
 
-    private final ActivityRecordInputSink mActivityRecordInputSink;
+    final ActivityRecordInputSink mActivityRecordInputSink;
 
     // Activities with this uid are allowed to not create an input sink while being in the same
     // task and directly above this ActivityRecord. This field is updated whenever a new activity
@@ -2066,6 +2068,12 @@
 
         launchMode = aInfo.launchMode;
 
+        // Don't move below setActivityType since it triggers onConfigurationChange ->
+        // resolveOverrideConfiguration that requires having mLetterboxUiController initialised.
+        mLetterboxUiController = new LetterboxUiController(mWmService, this);
+        mCameraCompatControlEnabled = mWmService.mContext.getResources()
+                .getBoolean(R.bool.config_isCameraCompatControlForStretchedIssuesEnabled);
+
         setActivityType(_componentSpecified, _launchedFromUid, _intent, options, sourceRecord);
 
         immersive = (aInfo.flags & FLAG_IMMERSIVE) != 0;
@@ -2094,9 +2102,6 @@
         mPersistentState = persistentState;
         taskDescription = _taskDescription;
 
-        mLetterboxUiController = new LetterboxUiController(mWmService, this);
-        mCameraCompatControlEnabled = mWmService.mContext.getResources()
-                .getBoolean(R.bool.config_isCameraCompatControlForStretchedIssuesEnabled);
         shouldDockBigOverlays = mWmService.mContext.getResources()
                 .getBoolean(R.bool.config_dockBigOverlayWindows);
 
@@ -2795,7 +2800,7 @@
 
     @VisibleForTesting
     boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
-        if (uid == Process.myUid() || uid == 0) {
+        if (uid == SYSTEM_UID || uid == 0) {
             // System process can launch home activity.
             return true;
         }
@@ -3014,25 +3019,6 @@
                 && info.supportsPictureInPicture();
     }
 
-    /**
-     * @return whether this activity supports split-screen multi-window and can be put in
-     *         split-screen.
-     */
-    @Override
-    public boolean supportsSplitScreenWindowingMode() {
-        return supportsSplitScreenWindowingModeInDisplayArea(getDisplayArea());
-    }
-
-    /**
-     * @return whether this activity supports split-screen multi-window and can be put in
-     *         split-screen if it is in the given {@link TaskDisplayArea}.
-     */
-    boolean supportsSplitScreenWindowingModeInDisplayArea(@Nullable TaskDisplayArea tda) {
-        return super.supportsSplitScreenWindowingMode()
-                && mAtmService.mSupportsSplitScreenMultiWindow
-                && supportsMultiWindowInDisplayArea(tda);
-    }
-
     boolean supportsFreeform() {
         return supportsFreeformInDisplayArea(getDisplayArea());
     }
@@ -3229,12 +3215,29 @@
             return false;
         }
 
-        if (mRootWindowContainer.getTopResumedActivity() == this
-                && getDisplayContent().mFocusedApp == this) {
-            ProtoLog.d(WM_DEBUG_FOCUS, "moveFocusableActivityToTop: already on top, "
-                    + "activity=%s", this);
-            return !isState(RESUMED);
+        // If this activity already positions on the top focused task, moving the task to front
+        // is not needed. But we still need to ensure this activity is focused because the
+        // current focused activity could be another activity in the same Task if activities are
+        // displayed on adjacent TaskFragments.
+        final ActivityRecord currentFocusedApp = mDisplayContent.mFocusedApp;
+        if (currentFocusedApp != null && currentFocusedApp.task == task) {
+            final Task topFocusableTask = mDisplayContent.getTask(
+                    (t) -> t.isLeafTask() && t.isFocusable(), true /*  traverseTopToBottom */);
+            if (task == topFocusableTask) {
+                if (currentFocusedApp == this) {
+                    ProtoLog.d(WM_DEBUG_FOCUS, "moveFocusableActivityToTop: already on top "
+                            + "and focused, activity=%s", this);
+                } else {
+                    ProtoLog.d(WM_DEBUG_FOCUS, "moveFocusableActivityToTop: set focused, "
+                            + "activity=%s", this);
+                    mDisplayContent.setFocusedApp(this);
+                    mAtmService.mWindowManager.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
+                            true /* updateInputWindows */);
+                }
+                return !isState(RESUMED);
+            }
         }
+
         ProtoLog.d(WM_DEBUG_FOCUS, "moveFocusableActivityToTop: activity=%s", this);
 
         rootTask.moveToFront(reason, task);
@@ -3284,7 +3287,12 @@
                 mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(resultGrants,
                         resultTo.getUriPermissionsLocked());
             }
-            resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData);
+            if (mForceSendResultForMediaProjection) {
+                resultTo.sendResult(this.getUid(), resultWho, requestCode, resultCode,
+                        resultData, resultGrants, true /* forceSendForMediaProjection */);
+            } else {
+                resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData);
+            }
             resultTo = null;
         } else if (DEBUG_RESULTS) {
             Slog.v(TAG_RESULTS, "No result destination from " + this);
@@ -3478,6 +3486,10 @@
         }
     }
 
+    void setForceSendResultForMediaProjection() {
+        mForceSendResultForMediaProjection = true;
+    }
+
     private void prepareActivityHideTransitionAnimationIfOvarlay() {
         if (mTaskOverlay) {
             prepareActivityHideTransitionAnimation();
@@ -4489,12 +4501,17 @@
 
     /**
      * @return Whether we are allowed to show non-starting windows at the moment. We disallow
-     *         showing windows during transitions in case we have windows that have wide-color-gamut
-     *         color mode set to avoid jank in the middle of the transition.
+     *         showing windows while the transition animation is playing in case we have windows
+     *         that have wide-color-gamut color mode set to avoid jank in the middle of the
+     *         animation.
      */
     boolean canShowWindows() {
-        return allDrawn && !(isAnimating(PARENTS, ANIMATION_TYPE_APP_TRANSITION)
-                && hasNonDefaultColorWindow());
+        final boolean drawn = mTransitionController.isShellTransitionsEnabled()
+                ? mSyncState != SYNC_STATE_WAITING_FOR_DRAW : allDrawn;
+        final boolean animating = mTransitionController.isShellTransitionsEnabled()
+                ? mTransitionController.inPlayingTransition(this)
+                : isAnimating(PARENTS, ANIMATION_TYPE_APP_TRANSITION);
+        return drawn && !(animating && hasNonDefaultColorWindow());
     }
 
     /**
@@ -4569,6 +4586,12 @@
 
     void sendResult(int callingUid, String resultWho, int requestCode, int resultCode,
             Intent data, NeededUriGrants dataGrants) {
+        sendResult(callingUid, resultWho, requestCode, resultCode, data, dataGrants,
+                false /* forceSendForMediaProjection */);
+    }
+
+    private void sendResult(int callingUid, String resultWho, int requestCode, int resultCode,
+            Intent data, NeededUriGrants dataGrants, boolean forceSendForMediaProjection) {
         if (callingUid > 0) {
             mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(dataGrants,
                     getUriPermissionsLocked());
@@ -4577,8 +4600,10 @@
         if (DEBUG_RESULTS) {
             Slog.v(TAG, "Send activity result to " + this
                     + " : who=" + resultWho + " req=" + requestCode
-                    + " res=" + resultCode + " data=" + data);
+                    + " res=" + resultCode + " data=" + data
+                    + " forceSendForMediaProjection=" + forceSendForMediaProjection);
         }
+
         if (isState(RESUMED) && attachedToProcess()) {
             try {
                 final ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
@@ -4591,9 +4616,63 @@
             }
         }
 
+        // Schedule sending results now for Media Projection setup.
+        if (forceSendForMediaProjection && attachedToProcess() && isState(STARTED, PAUSING, PAUSED,
+                STOPPING, STOPPED)) {
+            final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), token);
+            // Build result to be returned immediately.
+            transaction.addCallback(ActivityResultItem.obtain(
+                    List.of(new ResultInfo(resultWho, requestCode, resultCode, data))));
+            // When the activity result is delivered, the activity will transition to RESUMED.
+            // Since the activity is only resumed so the result can be immediately delivered,
+            // return it to its original lifecycle state.
+            ActivityLifecycleItem lifecycleItem = getLifecycleItemForCurrentStateForResult();
+            if (lifecycleItem != null) {
+                transaction.setLifecycleStateRequest(lifecycleItem);
+            } else {
+                Slog.w(TAG, "Unable to get the lifecycle item for state " + mState
+                        + " so couldn't immediately send result");
+            }
+            try {
+                mAtmService.getLifecycleManager().scheduleTransaction(transaction);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Exception thrown sending result to " + this, e);
+            }
+        }
+
         addResultLocked(null /* from */, resultWho, requestCode, resultCode, data);
     }
 
+    /**
+     * Provides a lifecycle item for the current stat. Only to be used when force sending an
+     * activity result (as part of MeidaProjection setup). Does not support the following states:
+     * {@link State#INITIALIZING}, {@link State#RESTARTING_PROCESS},
+     * {@link State#FINISHING}, {@link State#DESTROYING}, {@link State#DESTROYED}. It does not make
+     * sense to force send a result to an activity in these states. Does not support
+     * {@link State#RESUMED} since a resumed activity will end in the resumed state after handling
+     * the result.
+     *
+     * @return an {@link ActivityLifecycleItem} for the current state, or {@code null} if the
+     * state is not valid.
+     */
+    @Nullable
+    private ActivityLifecycleItem getLifecycleItemForCurrentStateForResult() {
+        switch (mState) {
+            case STARTED:
+                return StartActivityItem.obtain(null);
+            case PAUSING:
+            case PAUSED:
+                return PauseActivityItem.obtain();
+            case STOPPING:
+            case STOPPED:
+                return StopActivityItem.obtain(configChangeFlags);
+            default:
+                // Do not send a result immediately if the activity is in state INITIALIZING,
+                // RESTARTING_PROCESS, FINISHING, DESTROYING, or DESTROYED.
+                return null;
+        }
+    }
+
     private void addNewIntentLocked(ReferrerIntent intent) {
         if (newIntents == null) {
             newIntents = new ArrayList<>();
@@ -5256,17 +5335,22 @@
         final boolean delayed = isAnimating(PARENTS | CHILDREN,
                 ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_WINDOW_ANIMATION
                         | ANIMATION_TYPE_RECENTS);
-        if (!delayed && !usingShellTransitions) {
+        if (!delayed) {
             // We aren't delayed anything, but exiting windows rely on the animation finished
             // callback being called in case the ActivityRecord was pretending to be delayed,
             // which we might have done because we were in closing/opening apps list.
-            onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, null /* AnimationAdapter */);
-            if (visible) {
-                // The token was made immediately visible, there will be no entrance animation.
-                // We need to inform the client the enter animation was finished.
-                mEnteringAnimation = true;
-                mWmService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(
-                        token);
+            if (!usingShellTransitions) {
+                onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION, null /* AnimationAdapter */);
+                if (visible) {
+                    // The token was made immediately visible, there will be no entrance animation.
+                    // We need to inform the client the enter animation was finished.
+                    mEnteringAnimation = true;
+                    mWmService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(
+                            token);
+                }
+            } else {
+                // update wallpaper target
+                setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER, "ActivityRecord");
             }
         }
 
@@ -5550,7 +5634,10 @@
                 wasStopped, this);
         mAppStopped = false;
         // Allow the window to turn the screen on once the app is resumed again.
-        setCurrentLaunchCanTurnScreenOn(true);
+        if (mAtmService.getActivityStartController().isInExecution()) {
+            setCurrentLaunchCanTurnScreenOn(true);
+        }
+
         if (!wasStopped) {
             destroySurfaces(true /*cleanupOnResume*/);
         }
@@ -7726,11 +7813,15 @@
                 newParentConfiguration.windowConfiguration.getWindowingMode();
         final boolean isFixedOrientationLetterboxAllowed =
                 parentWindowingMode == WINDOWING_MODE_MULTI_WINDOW
-                        || parentWindowingMode == WINDOWING_MODE_FULLSCREEN;
+                        || parentWindowingMode == WINDOWING_MODE_FULLSCREEN
+                        // Switching from PiP to fullscreen.
+                        || (parentWindowingMode == WINDOWING_MODE_PINNED
+                                && resolvedConfig.windowConfiguration.getWindowingMode()
+                                        == WINDOWING_MODE_FULLSCREEN);
         // TODO(b/181207944): Consider removing the if condition and always run
         // resolveFixedOrientationConfiguration() since this should be applied for all cases.
         if (isFixedOrientationLetterboxAllowed) {
-            resolveFixedOrientationConfiguration(newParentConfiguration, parentWindowingMode);
+            resolveFixedOrientationConfiguration(newParentConfiguration);
         }
 
         if (mCompatDisplayInsets != null) {
@@ -7754,7 +7845,7 @@
         if (isFixedOrientationLetterboxAllowed || mCompatDisplayInsets != null
                 // In fullscreen, can be letterboxed for aspect ratio.
                 || !inMultiWindowMode()) {
-            updateResolvedBoundsHorizontalPosition(newParentConfiguration);
+            updateResolvedBoundsPosition(newParentConfiguration);
         }
 
         if (mVisibleRequested) {
@@ -7857,39 +7948,60 @@
     }
 
     /**
-     * Adjusts horizontal position of resolved bounds if they doesn't fill the parent using gravity
+     * Adjusts position of resolved bounds if they doesn't fill the parent using gravity
      * requested in the config or via an ADB command. For more context see {@link
-     * LetterboxUiController#getHorizontalPositionMultiplier(Configuration)}.
+     * LetterboxUiController#getHorizontalPositionMultiplier(Configuration)} and
+     * {@link LetterboxUiController#getVerticalPositionMultiplier(Configuration)}
      */
-    private void updateResolvedBoundsHorizontalPosition(Configuration newParentConfiguration) {
+    private void updateResolvedBoundsPosition(Configuration newParentConfiguration) {
         final Configuration resolvedConfig = getResolvedOverrideConfiguration();
         final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
         final Rect screenResolvedBounds =
                 mSizeCompatBounds != null ? mSizeCompatBounds : resolvedBounds;
         final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds();
         final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds();
-        if (resolvedBounds.isEmpty() || parentBounds.width() == screenResolvedBounds.width()) {
+        if (resolvedBounds.isEmpty()) {
             return;
         }
-
+        // Horizontal position
         int offsetX = 0;
-        if (screenResolvedBounds.width() >= parentAppBounds.width()) {
-            // If resolved bounds overlap with insets, center within app bounds.
-            offsetX = getHorizontalCenterOffset(
-                    parentAppBounds.width(), screenResolvedBounds.width());
-        } else {
-            float positionMultiplier =
-                    mLetterboxUiController.getHorizontalPositionMultiplier(newParentConfiguration);
-            offsetX = (int) Math.ceil((parentAppBounds.width() - screenResolvedBounds.width())
-                    * positionMultiplier);
+        if (parentBounds.width() != screenResolvedBounds.width()) {
+            if (screenResolvedBounds.width() >= parentAppBounds.width()) {
+                // If resolved bounds overlap with insets, center within app bounds.
+                offsetX = getCenterOffset(
+                        parentAppBounds.width(), screenResolvedBounds.width());
+            } else {
+                float positionMultiplier =
+                        mLetterboxUiController.getHorizontalPositionMultiplier(
+                                newParentConfiguration);
+                offsetX = (int) Math.ceil((parentAppBounds.width() - screenResolvedBounds.width())
+                        * positionMultiplier);
+            }
+        }
+
+        // Vertical position
+        int offsetY = 0;
+        if (parentBounds.height() != screenResolvedBounds.height()) {
+            if (screenResolvedBounds.height() >= parentAppBounds.height()) {
+                // If resolved bounds overlap with insets, center within app bounds.
+                offsetY = getCenterOffset(
+                        parentAppBounds.height(), screenResolvedBounds.height());
+            } else {
+                float positionMultiplier =
+                        mLetterboxUiController.getVerticalPositionMultiplier(
+                                newParentConfiguration);
+                offsetY = (int) Math.ceil((parentAppBounds.height() - screenResolvedBounds.height())
+                        * positionMultiplier);
+            }
         }
 
         if (mSizeCompatBounds != null) {
-            mSizeCompatBounds.offset(offsetX, 0 /* offsetY */);
+            mSizeCompatBounds.offset(offsetX , offsetY);
+            final int dy = mSizeCompatBounds.top - resolvedBounds.top;
             final int dx = mSizeCompatBounds.left - resolvedBounds.left;
-            offsetBounds(resolvedConfig, dx,  0 /* offsetY */);
+            offsetBounds(resolvedConfig, dx, dy);
         } else {
-            offsetBounds(resolvedConfig, offsetX, 0 /* offsetY */);
+            offsetBounds(resolvedConfig, offsetX, offsetY);
         }
 
         // Since bounds has changed, the configuration needs to be computed accordingly.
@@ -7901,8 +8013,7 @@
     }
 
     boolean isInTransition() {
-        return mTransitionController.inTransition() // Shell transitions.
-                || isAnimating(PARENTS | TRANSITION); // Legacy transitions.
+        return inTransitionSelfOrParent();
     }
 
     /**
@@ -7917,6 +8028,10 @@
         return mLetterboxBoundsForFixedOrientationAndAspectRatio != null;
     }
 
+    boolean isAspectRatioApplied() {
+        return mIsAspectRatioApplied;
+    }
+
     /**
      * Whether this activity is eligible for letterbox eduction.
      *
@@ -7998,8 +8113,7 @@
      * <p>If letterboxed due to fixed orientation then aspect ratio restrictions are also applied
      * in this method.
      */
-    private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig,
-            int windowingMode) {
+    private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig) {
         mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
         mIsEligibleForFixedOrientationLetterbox = false;
         final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
@@ -8019,11 +8133,6 @@
         if (organizedTf != null && !organizedTf.fillsParent()) {
             return;
         }
-        if (windowingMode == WINDOWING_MODE_PINNED) {
-            // PiP bounds have higher priority than the requested orientation. Otherwise the
-            // activity may be squeezed into a small piece.
-            return;
-        }
 
         final Rect resolvedBounds =
                 getResolvedOverrideConfiguration().windowConfiguration.getBounds();
@@ -8088,21 +8197,13 @@
         resolvedBounds.set(containingBounds);
 
         final float letterboxAspectRatioOverride =
-                mLetterboxUiController.getFixedOrientationLetterboxAspectRatio(newParentConfig);
+                mLetterboxUiController.getFixedOrientationLetterboxAspectRatio();
         final float desiredAspectRatio =
                 letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
                         ? letterboxAspectRatioOverride : computeAspectRatio(parentBounds);
         // Apply aspect ratio to resolved bounds
         mIsAspectRatioApplied = applyAspectRatio(resolvedBounds, containingBoundsWithInsets,
-                containingBounds, desiredAspectRatio, true);
-
-        // Vertically center if orientation is landscape. Center within parent bounds with insets
-        // to ensure that insets do not trim height. Bounds will later be horizontally centered in
-        // {@link updateResolvedBoundsHorizontalPosition()} regardless of orientation.
-        if (forcedOrientation == ORIENTATION_LANDSCAPE) {
-            final int offsetY = parentBoundsWithInsets.centerY() - resolvedBounds.centerY();
-            resolvedBounds.offset(0, offsetY);
-        }
+                containingBounds, desiredAspectRatio);
 
         if (mCompatDisplayInsets != null) {
             mCompatDisplayInsets.getBoundsByRotation(
@@ -8126,10 +8227,9 @@
 
     /**
      * Resolves aspect ratio restrictions for an activity. If the bounds are restricted by
-     * aspect ratio, the position will be adjusted later in {@link
-     * updateResolvedBoundsHorizontalPosition} within parent's app bounds to balance the visual
-     * appearance. The policy of aspect ratio has higher priority than the requested override
-     * bounds.
+     * aspect ratio, the position will be adjusted later in {@link #updateResolvedBoundsPosition
+     * within parent's app bounds to balance the visual appearance. The policy of aspect ratio has
+     * higher priority than the requested override bounds.
      */
     private void resolveAspectRatioRestriction(Configuration newParentConfiguration) {
         final Configuration resolvedConfig = getResolvedOverrideConfiguration();
@@ -8141,7 +8241,7 @@
         mTmpBounds.setEmpty();
         mIsAspectRatioApplied = applyAspectRatio(mTmpBounds, parentAppBounds, parentBounds);
         // If the out bounds is not empty, it means the activity cannot fill parent's app bounds,
-        // then they should be aligned later in #updateResolvedBoundsHorizontalPosition().
+        // then they should be aligned later in #updateResolvedBoundsPosition()
         if (!mTmpBounds.isEmpty()) {
             resolvedBounds.set(mTmpBounds);
         }
@@ -8275,22 +8375,11 @@
             forAllWindows(WindowState::updateGlobalScale, false /* traverseTopToBottom */);
         }
 
-        // Vertically center within parent (bounds) - this is a UX choice and exclude the horizontal
-        // decor if needed. Horizontal position is adjusted in
-        // updateResolvedBoundsHorizontalPosition.
+        // The position will be later adjusted in updateResolvedBoundsPosition.
         // Above coordinates are in "@" space, now place "*" and "#" to screen space.
         final boolean fillContainer = resolvedBounds.equals(containingBounds);
         final int screenPosX = fillContainer ? containerBounds.left : containerAppBounds.left;
-        // If the activity is not in size compat mode, calculate vertical centering
-        //     from the container and resolved bounds.
-        // If the activity is in size compat mode, calculate vertical centering
-        //     from the container and size compat bounds.
-        // The container bounds contain the parent bounds offset in the display, for
-        // example when an activity is in the lower split of split screen.
-        final int screenPosY = (mSizeCompatBounds == null
-                ? (containerBounds.height() - resolvedBounds.height()) / 2
-                : (containerBounds.height() - mSizeCompatBounds.height()) / 2)
-                + containerBounds.top;
+        final int screenPosY  = fillContainer ? containerBounds.top : containerAppBounds.top;
 
         if (screenPosX != 0 || screenPosY != 0) {
             if (mSizeCompatBounds != null) {
@@ -8350,9 +8439,9 @@
         return true;
     }
 
-    /** @return The horizontal offset of putting the content in the center of viewport. */
-    private static int getHorizontalCenterOffset(int viewportW, int contentW) {
-        return (int) ((viewportW - contentW + 1) * 0.5f);
+    /** @return The horizontal / vertical offset of putting the content in the center of viewport.*/
+    private static int getCenterOffset(int viewportDim, int contentDim) {
+        return (int) ((viewportDim - contentDim + 1) * 0.5f);
     }
 
     private static void offsetBounds(Configuration inOutConfig, int offsetX, int offsetY) {
@@ -8540,7 +8629,7 @@
     private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
             Rect containingBounds) {
         return applyAspectRatio(outBounds, containingAppBounds, containingBounds,
-                0 /* desiredAspectRatio */, false /* fixedOrientationLetterboxed */);
+                0 /* desiredAspectRatio */);
     }
 
     /**
@@ -8551,23 +8640,18 @@
      */
     // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
     private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
-            Rect containingBounds, float desiredAspectRatio, boolean fixedOrientationLetterboxed) {
+            Rect containingBounds, float desiredAspectRatio) {
         final float maxAspectRatio = info.getMaxAspectRatio();
         final Task rootTask = getRootTask();
         final float minAspectRatio = getMinAspectRatio();
-        // Not using ActivityRecord#isResizeable() directly because app compatibility testing
-        // showed that android:supportsPictureInPicture="true" alone is not sufficient signal for
-        // not letterboxing an app.
-        // TODO(214602463): Remove multi-window check since orientation and aspect ratio
-        // restrictions should always be applied in multi-window.
+        final TaskFragment organizedTf = getOrganizedTaskFragment();
         if (task == null || rootTask == null
-                || (inMultiWindowMode() && isResizeable(/* checkPictureInPictureSupport */ false)
-                && !fixedOrientationLetterboxed)
                 || (maxAspectRatio < 1 && minAspectRatio < 1 && desiredAspectRatio < 1)
-                || isInVrUiMode(getConfiguration())) {
-            // We don't enforce aspect ratio if the activity task is in multiwindow unless it is in
-            // size-compat mode or is letterboxed from fixed orientation. We also don't set it if we
-            // are in VR mode.
+                // Don't set aspect ratio if we are in VR mode.
+                || isInVrUiMode(getConfiguration())
+                // TODO(b/232898850): Always respect aspect ratio requests.
+                // Don't set aspect ratio for activity in ActivityEmbedding split.
+                || (organizedTf != null && !organizedTf.fillsParent())) {
             return false;
         }
 
@@ -9615,7 +9699,7 @@
                     outBounds.bottom = dH;
                     outBounds.right = (int) ((float) dH * dH / dW);
                 }
-                outBounds.offset(getHorizontalCenterOffset(mWidth, outBounds.width()), 0 /* dy */);
+                outBounds.offset(getCenterOffset(mWidth, outBounds.width()), 0 /* dy */);
             }
             outAppBounds.set(outBounds);
 
@@ -9663,6 +9747,7 @@
                 false /*isNotInRecents*/,
                 record.mThumbnailAdapter != null ? record.mThumbnailAdapter.mCapturedLeash : null,
                 record.mStartBounds, task.getTaskInfo(), checkEnterPictureInPictureAppOpsState());
+        target.setShowBackdrop(record.mShowBackdrop);
         target.hasAnimatingParent = record.hasAnimatingParent();
         return target;
     }
@@ -9695,6 +9780,10 @@
     @Override
     boolean isSyncFinished() {
         if (!super.isSyncFinished()) return false;
+        if (mDisplayContent != null && mDisplayContent.mUnknownAppVisibilityController
+                .isVisibilityUnknown(this)) {
+            return false;
+        }
         if (!isVisibleRequested()) return true;
         // Wait for attach. That is the earliest time where we know if there will be an associated
         // display rotation. If we don't wait, the starting-window can finishDrawing first and
diff --git a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
index fc22e2d..5d038dc 100644
--- a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
+++ b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
@@ -19,7 +19,6 @@
 import android.app.compat.CompatChanges;
 import android.compat.annotation.ChangeId;
 import android.os.InputConfig;
-import android.os.Process;
 import android.view.InputWindowHandle;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
@@ -82,8 +81,8 @@
         // Don't block touches from passing through to an activity below us in the same task, if
         // that activity is either from the same uid or if that activity has launched an activity
         // in our uid.
-        final ActivityRecord activityBelowInTask =
-                mActivityRecord.getTask().getActivityBelow(mActivityRecord);
+        final ActivityRecord activityBelowInTask = mActivityRecord.getTask() != null
+                ? mActivityRecord.getTask().getActivityBelow(mActivityRecord) : null;
         final boolean allowPassthrough = activityBelowInTask != null && (
                 activityBelowInTask.mAllowedTouchUid == mActivityRecord.getUid()
                         || activityBelowInTask.isUid(mActivityRecord.getUid()));
@@ -102,8 +101,8 @@
         inputWindowHandle.replaceTouchableRegionWithCrop = true;
         inputWindowHandle.name = mName;
         inputWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
-        inputWindowHandle.ownerUid = Process.myUid();
-        inputWindowHandle.ownerPid = Process.myPid();
+        inputWindowHandle.ownerPid = WindowManagerService.MY_PID;
+        inputWindowHandle.ownerUid = WindowManagerService.MY_UID;
         inputWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.NO_INPUT_CHANNEL;
         return inputWindowHandle;
     }
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 32ed472..a78dbd6 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -90,6 +90,8 @@
 
     boolean mCheckedForSetup = false;
 
+    private boolean mInExecution = false;
+
     /**
      * TODO(b/64750076): Capture information necessary for dump and
      * {@link #postStartActivityProcessingForLastStarter} rather than keeping the entire object
@@ -123,7 +125,15 @@
         return mFactory.obtain().setIntent(intent).setReason(reason);
     }
 
+    void onExecutionStarted(ActivityStarter starter) {
+        mInExecution = true;
+    }
+
+    boolean isInExecution() {
+        return mInExecution;
+    }
     void onExecutionComplete(ActivityStarter starter) {
+        mInExecution = false;
         if (mLastStarter == null) {
             mLastStarter = mFactory.obtain();
         }
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 84cd634..960b1bc 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -51,6 +51,7 @@
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE_PER_TASK;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
+import static android.content.pm.ActivityInfo.launchModeToString;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Process.INVALID_UID;
 import static android.view.Display.DEFAULT_DISPLAY;
@@ -211,6 +212,7 @@
     // The task which was above the targetTask before starting this activity. null if the targetTask
     // was already on top or if the activity is in a new task.
     private Task mPriorAboveTask;
+    private boolean mDisplayLockAndOccluded;
 
     // We must track when we deliver the new intent since multiple code paths invoke
     // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
@@ -642,6 +644,8 @@
      */
     int execute() {
         try {
+            onExecutionStarted();
+
             // Refuse possible leaked file descriptors
             if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
                 throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -1256,6 +1260,10 @@
         mController.onExecutionComplete(this);
     }
 
+    private void onExecutionStarted() {
+        mController.onExecutionStarted(this);
+    }
+
     private boolean isHomeApp(int uid, @Nullable String packageName) {
         if (mService.mHomeProcess != null) {
             // Fast check
@@ -1652,14 +1660,17 @@
         transitionController.collect(r);
         try {
             mService.deferWindowLayout();
-            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
-            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
-                    startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
-                    intentGrants);
+            try {
+                Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
+                result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
+                        startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
+                        intentGrants);
+            } finally {
+                Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+                startedActivityRootTask = handleStartResult(r, options, result, newTransition,
+                        remoteTransition);
+            }
         } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
-            startedActivityRootTask = handleStartResult(r, options, result, newTransition,
-                    remoteTransition);
             mService.continueWindowLayout();
         }
         postStartActivityProcessing(r, result, startedActivityRootTask);
@@ -1676,6 +1687,7 @@
     private @Nullable Task handleStartResult(@NonNull ActivityRecord started,
             ActivityOptions options, int result, Transition newTransition,
             RemoteTransition remoteTransition) {
+        final boolean userLeaving = mSupervisor.mUserLeaving;
         mSupervisor.mUserLeaving = false;
         final Task currentRootTask = started.getRootTask();
         final Task startedActivityRootTask =
@@ -1694,7 +1706,8 @@
             // Root task should also be detached from display and be removed if it's empty.
             if (startedActivityRootTask != null && startedActivityRootTask.isAttached()
                     && !startedActivityRootTask.hasActivity()
-                    && !startedActivityRootTask.isActivityTypeHome()) {
+                    && !startedActivityRootTask.isActivityTypeHome()
+                    && !startedActivityRootTask.mCreatedByOrganizer) {
                 startedActivityRootTask.removeIfPossible("handleStartResult");
             }
             if (newTransition != null) {
@@ -1735,19 +1748,42 @@
         // Transition housekeeping.
         final TransitionController transitionController = started.mTransitionController;
         final boolean isStarted = result == START_SUCCESS || result == START_TASK_TO_FRONT;
+        final boolean isTransientLaunch = options != null && options.getTransientLaunch();
+        // Start transient launch while keyguard locked and occluded by other app, for this
+        // condition we would like to play the remote transition without modify any visible state
+        // for the hierarchy in core, so here will force execute this transition.
+        final boolean forceTransientTransition = isTransientLaunch && mPriorAboveTask != null
+                && mDisplayLockAndOccluded;
         if (isStarted) {
             // The activity is started new rather than just brought forward, so record it as an
             // existence change.
             transitionController.collectExistenceChange(started);
         } else if (result == START_DELIVERED_TO_TOP && newTransition != null) {
             // We just delivered to top, so there isn't an actual transition here.
-            newTransition.abort();
-            newTransition = null;
+            if (!forceTransientTransition) {
+                newTransition.abort();
+                newTransition = null;
+            }
         }
-        if (options != null && options.getTransientLaunch()) {
+        if (isTransientLaunch) {
+            if (forceTransientTransition && newTransition != null) {
+                newTransition.collect(mLastStartActivityRecord);
+                newTransition.collect(mPriorAboveTask);
+            }
             // `started` isn't guaranteed to be the actual relevant activity, so we must wait
             // until after we launched to identify the relevant activity.
             transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask);
+            if (forceTransientTransition && newTransition != null) {
+                final DisplayContent dc = mLastStartActivityRecord.getDisplayContent();
+                // update wallpaper target to TransientHide
+                dc.mWallpaperController.adjustWallpaperWindows();
+                // execute transition because there is no change
+                newTransition.setReady(dc, true /* ready */);
+            }
+        }
+        if (!userLeaving) {
+            // no-user-leaving implies not entering PiP.
+            transitionController.setCanPipOnFinish(false /* canPipOnFinish */);
         }
         if (newTransition != null) {
             transitionController.requestStartTransition(newTransition,
@@ -2039,8 +2075,20 @@
         }
 
         if (mInTaskFragment != null && !canEmbedActivity(mInTaskFragment, r, newTask, targetTask)) {
-            Slog.e(TAG, "Permission denied: Cannot embed " + r + " to " + mInTaskFragment.getTask()
-                    + " targetTask= " + targetTask);
+            final StringBuilder errorMsg = new StringBuilder("Permission denied: Cannot embed " + r
+                    + " to " + mInTaskFragment.getTask() + ". newTask=" + newTask + ", targetTask= "
+                    + targetTask);
+            if (newTask && isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE,
+                    LAUNCH_SINGLE_INSTANCE_PER_TASK, LAUNCH_SINGLE_TASK)) {
+                errorMsg.append("\nActivity tries to launch on a new task because the launch mode"
+                        + " is " + launchModeToString(mLaunchMode));
+            } else if (newTask && (mLaunchFlags & (FLAG_ACTIVITY_NEW_DOCUMENT
+                    | FLAG_ACTIVITY_NEW_TASK)) != 0) {
+                errorMsg.append("\nActivity tries to launch on a new task because the launch flags"
+                        + " contains FLAG_ACTIVITY_NEW_DOCUMENT or FLAG_ACTIVITY_NEW_TASK. "
+                        + "mLaunchFlag=" + mLaunchFlags);
+            }
+            Slog.e(TAG, errorMsg.toString());
             return START_PERMISSION_DENIED;
         }
 
@@ -2388,6 +2436,7 @@
         mAvoidMoveToFront = false;
         mFrozeTaskList = false;
         mTransientLaunch = false;
+        mDisplayLockAndOccluded = false;
 
         mVoiceSession = null;
         mVoiceInteractor = null;
@@ -2491,6 +2540,16 @@
                 mAvoidMoveToFront = true;
             }
             mTransientLaunch = mOptions.getTransientLaunch();
+            final KeyguardController kc = mSupervisor.getKeyguardController();
+            final int displayId = mPreferredTaskDisplayArea.getDisplayId();
+            mDisplayLockAndOccluded = kc.isKeyguardLocked(displayId)
+                    && kc.isDisplayOccluded(displayId);
+            // Recents animation on lock screen, do not resume & move launcher to top.
+            if (mTransientLaunch && mDisplayLockAndOccluded
+                    && mService.getTransitionController().isShellTransitionsEnabled()) {
+                mDoResume = false;
+                mAvoidMoveToFront = true;
+            }
             mTargetRootTask = Task.fromWindowContainerToken(mOptions.getLaunchRootTask());
 
             if (inTaskFragment == null) {
@@ -2517,6 +2576,7 @@
             mInTask = null;
         }
         mInTaskFragment = inTaskFragment;
+        sendNewTaskFragmentResultRequestIfNeeded();
 
         mStartFlags = startFlags;
         // If the onlyIfNeeded flag is set, then we can do this if the activity being launched
@@ -2559,6 +2619,18 @@
         }
     }
 
+    private void sendNewTaskFragmentResultRequestIfNeeded() {
+        if (mStartActivity.resultTo != null && mInTaskFragment != null
+                && mInTaskFragment != mStartActivity.resultTo.getTaskFragment()) {
+            Slog.w(TAG,
+                    "Activity is launching as a new TaskFragment, so cancelling activity result.");
+            mStartActivity.resultTo.sendResult(INVALID_UID, mStartActivity.resultWho,
+                    mStartActivity.requestCode, RESULT_CANCELED,
+                    null /* data */, null /* dataGrants */);
+            mStartActivity.resultTo = null;
+        }
+    }
+
     private void computeLaunchingTaskFlags() {
         // If the caller is not coming from another activity, but has given us an explicit task into
         // which they would like us to launch the new activity, then let's see about doing that.
@@ -2639,6 +2711,12 @@
                 mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
             }
         }
+
+        if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0
+                && ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 || mSourceRecord == null)) {
+            // ignore the flag if there is no the sourceRecord or without new_task flag
+            mLaunchFlags &= ~FLAG_ACTIVITY_LAUNCH_ADJACENT;
+        }
     }
 
     private void computeSourceRootTask() {
@@ -2758,17 +2836,15 @@
                 mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, intentTask,
                         mOptions);
             }
-        } else {
-            // If a launch target indicated, and the matching task is already in the adjacent task
-            // of the launch target. Adjust to use the adjacent task as its launch target. So the
-            // existing task will be launched into the closer one and won't be reparent redundantly.
-            // TODO(b/231541706): Migrate the logic to wm-shell after having proper APIs to help
-            //  resolve target task without actually starting the activity.
-            final Task adjacentTargetTask = mTargetRootTask.getAdjacentTaskFragment() != null
-                    ? mTargetRootTask.getAdjacentTaskFragment().asTask() : null;
-            if (adjacentTargetTask != null && intentActivity.isDescendantOf(adjacentTargetTask)) {
-                mTargetRootTask = adjacentTargetTask;
-            }
+        }
+
+        // If the matching task is already in the adjacent task of the launch target. Adjust to use
+        // the adjacent task as its launch target. So the existing task will be launched into the
+        // closer one and won't be reparent redundantly.
+        final Task adjacentTargetTask = mTargetRootTask.getAdjacentTaskFragment() != null
+                ? mTargetRootTask.getAdjacentTaskFragment().asTask() : null;
+        if (adjacentTargetTask != null && intentActivity.isDescendantOf(adjacentTargetTask)) {
+            mTargetRootTask = adjacentTargetTask;
         }
 
         // If the target task is not in the front, then we need to bring it to the front...
@@ -3255,12 +3331,8 @@
             pw.println(mOptions);
         }
         pw.print(prefix);
-        pw.print("mLaunchSingleTop=");
-        pw.print(LAUNCH_SINGLE_TOP == mLaunchMode);
-        pw.print(" mLaunchSingleInstance=");
-        pw.print(LAUNCH_SINGLE_INSTANCE == mLaunchMode);
-        pw.print(" mLaunchSingleTask=");
-        pw.println(LAUNCH_SINGLE_TASK == mLaunchMode);
+        pw.print("mLaunchMode=");
+        pw.print(launchModeToString(mLaunchMode));
         pw.print(prefix);
         pw.print("mLaunchFlags=0x");
         pw.print(Integer.toHexString(mLaunchFlags));
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 8e7dde2..e7b62b0 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -675,9 +675,6 @@
     public abstract boolean hasSystemAlertWindowPermission(int callingUid, int callingPid,
             String callingPackage);
 
-    /** Called when the device is waking up */
-    public abstract void notifyWakingUp();
-
     /**
      * Registers a callback which can intercept activity starts.
      * @throws IllegalArgumentException if duplicate ids are provided
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index aa15429..b76582f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -64,8 +64,8 @@
 import static android.provider.Settings.System.FONT_SCALE;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
-import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT;
-import static android.view.WindowManager.TRANSIT_WAKE;
+import static android.view.WindowManager.TRANSIT_PIP;
+import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
@@ -73,7 +73,6 @@
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
 import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
-import static com.android.server.am.ActivityManagerService.MY_PID;
 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
 import static com.android.server.am.ActivityManagerService.dumpStackTraces;
 import static com.android.server.am.ActivityManagerServiceDumpActivitiesProto.ROOT_WINDOW_CONTAINER;
@@ -95,6 +94,7 @@
 import static com.android.server.am.EventLogTags.writeConfigurationChanged;
 import static com.android.server.wm.ActivityInterceptorCallback.FIRST_ORDERED_ID;
 import static com.android.server.wm.ActivityInterceptorCallback.LAST_ORDERED_ID;
+import static com.android.server.wm.ActivityRecord.State.PAUSING;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ROOT_TASK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
@@ -116,6 +116,7 @@
 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_ONLY;
 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
 import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT;
+import static com.android.server.wm.WindowManagerService.MY_PID;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 
 import android.Manifest;
@@ -238,6 +239,7 @@
 import com.android.internal.os.TransferPipe;
 import com.android.internal.policy.AttributeCache;
 import com.android.internal.policy.KeyguardDismissCallback;
+import com.android.internal.protolog.ProtoLogGroup;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
@@ -400,6 +402,26 @@
     /** The time at which the previous process was last visible. */
     private long mPreviousProcessVisibleTime;
 
+    /** It is set from keyguard-going-away to set-keyguard-shown. */
+    static final int DEMOTE_TOP_REASON_DURING_UNLOCKING = 1;
+    /** It is set if legacy recents animation is running. */
+    static final int DEMOTE_TOP_REASON_ANIMATING_RECENTS = 1 << 1;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            DEMOTE_TOP_REASON_DURING_UNLOCKING,
+            DEMOTE_TOP_REASON_ANIMATING_RECENTS,
+    })
+    @interface DemoteTopReason {}
+
+    /**
+     * If non-zero, getTopProcessState() will
+     * return {@link ActivityManager#PROCESS_STATE_IMPORTANT_FOREGROUND} to avoid top app from
+     * preempting CPU while another process is running an important animation.
+     */
+    @DemoteTopReason
+    volatile int mDemoteTopAppReasons;
+
     /** List of intents that were used to start the most recent tasks. */
     private RecentTasks mRecentTasks;
     /** State of external calls telling us if the device is awake or asleep. */
@@ -2157,14 +2179,6 @@
                     : null;
             mTaskSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
                     false /* forceNonResizable */);
-
-            final ActivityRecord topActivity = task.getTopNonFinishingActivity();
-            if (topActivity != null) {
-
-                // We are reshowing a task, use a starting window to hide the initial draw delay
-                // so the transition can start earlier.
-                topActivity.showStartingWindow(true /* taskSwitch */);
-            }
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
@@ -2830,12 +2844,24 @@
                         keyguardShowing);
                 mH.sendMessage(msg);
             }
+            // Always reset the state regardless of keyguard-showing change, because that means the
+            // unlock is either completed or canceled.
+            if ((mDemoteTopAppReasons & DEMOTE_TOP_REASON_DURING_UNLOCKING) != 0) {
+                mDemoteTopAppReasons &= ~DEMOTE_TOP_REASON_DURING_UNLOCKING;
+                // The scheduling group of top process was demoted by unlocking, so recompute
+                // to restore its real top priority if possible.
+                if (mTopApp != null) {
+                    mTopApp.scheduleUpdateOomAdj();
+                }
+            }
             try {
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "setLockScreenShown");
                 mRootWindowContainer.forAllDisplays(displayContent -> {
                     mKeyguardController.setKeyguardShown(displayContent.getDisplayId(),
                             keyguardShowing, aodShowing);
                 });
             } finally {
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                 Binder.restoreCallingIdentity(ident);
             }
         }
@@ -2862,6 +2888,7 @@
         // animation of system UI. Even if AOD is not enabled, it should be no harm.
         final WindowProcessController proc;
         synchronized (mGlobalLockWithoutBoost) {
+            mDemoteTopAppReasons &= ~DEMOTE_TOP_REASON_DURING_UNLOCKING;
             final WindowState notificationShade = mRootWindowContainer.getDefaultDisplay()
                     .getDisplayPolicy().getNotificationShade();
             proc = notificationShade != null
@@ -3399,8 +3426,11 @@
         try {
             synchronized (mGlobalLock) {
                 // Keyguard asked us to clear the home task snapshot before going away, so do that.
-                if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) {
+                if ((flags & KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) {
                     mActivityClientController.invalidateHomeTaskSnapshot(null /* token */);
+                } else if (mKeyguardShown) {
+                    // Only set if it is not unlocking to launcher which may also animate.
+                    mDemoteTopAppReasons |= DEMOTE_TOP_REASON_DURING_UNLOCKING;
                 }
 
                 mRootWindowContainer.forAllDisplays(displayContent -> {
@@ -3448,10 +3478,12 @@
     /**
      * Puts the given activity in picture in picture mode if possible.
      *
+     * @param fromClient true if this comes from a client call (eg. Activity.enterPip).
      * @return true if the activity is now in picture-in-picture mode, or false if it could not
      * enter picture-in-picture mode.
      */
-    boolean enterPictureInPictureMode(@NonNull ActivityRecord r, PictureInPictureParams params) {
+    boolean enterPictureInPictureMode(@NonNull ActivityRecord r,
+            @NonNull PictureInPictureParams params, boolean fromClient) {
         // If the activity is already in picture in picture mode, then just return early
         if (r.inPinnedWindowingMode()) {
             return true;
@@ -3464,6 +3496,21 @@
             return false;
         }
 
+        // If the app is using legacy-entry (not auto-enter), then we will get a client-request
+        // that was actually a server-request (via pause(userLeaving=true)). This happens when
+        // the app is PAUSING, so detect that case here.
+        boolean originallyFromClient = fromClient
+                && (!r.isState(PAUSING) || params.isAutoEnterEnabled());
+
+        // Create a transition only for this pip entry if it is coming from the app without the
+        // system requesting that the app enter-pip. If the system requested it, that means it
+        // should be part of that transition if possible.
+        final Transition transition =
+                (getTransitionController().isShellTransitionsEnabled() && originallyFromClient)
+                ? new Transition(TRANSIT_PIP, 0 /* flags */,
+                        getTransitionController(), mWindowManager.mSyncEngine)
+                : null;
+
         final Runnable enterPipRunnable = () -> {
             synchronized (mGlobalLock) {
                 if (r.getParent() == null) {
@@ -3472,7 +3519,8 @@
                 }
                 r.setPictureInPictureParams(params);
                 mRootWindowContainer.moveActivityToPinnedRootTask(r,
-                        null /* launchIntoPipHostActivity */, "enterPictureInPictureMode");
+                        null /* launchIntoPipHostActivity */, "enterPictureInPictureMode",
+                        transition);
                 final Task task = r.getTask();
                 // Continue the pausing process after entering pip.
                 if (task.getPausingActivity() == r) {
@@ -3489,12 +3537,36 @@
             mActivityClientController.dismissKeyguard(r.token, new KeyguardDismissCallback() {
                 @Override
                 public void onDismissSucceeded() {
-                    mH.post(enterPipRunnable);
+                    if (transition != null && mWindowManager.mSyncEngine.hasActiveSync()) {
+                        ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
+                                "Creating Pending Pip-Enter: %s", transition);
+                        mWindowManager.mSyncEngine.queueSyncSet(
+                                () -> getTransitionController().moveToCollecting(transition),
+                                enterPipRunnable);
+                    } else {
+                        // Move to collecting immediately to "claim" the sync-engine for this
+                        // transition.
+                        if (transition != null) {
+                            getTransitionController().moveToCollecting(transition);
+                        }
+                        mH.post(enterPipRunnable);
+                    }
                 }
             }, null /* message */);
         } else {
             // Enter picture in picture immediately otherwise
-            enterPipRunnable.run();
+            if (transition != null && mWindowManager.mSyncEngine.hasActiveSync()) {
+                ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
+                        "Creating Pending Pip-Enter: %s", transition);
+                mWindowManager.mSyncEngine.queueSyncSet(
+                        () -> getTransitionController().moveToCollecting(transition),
+                        enterPipRunnable);
+            } else {
+                if (transition != null) {
+                    getTransitionController().moveToCollecting(transition);
+                }
+                enterPipRunnable.run();
+            }
         }
         return true;
     }
@@ -3968,6 +4040,9 @@
             mTaskOrganizerController.dump(pw, "  ");
             mVisibleActivityProcessTracker.dump(pw, "  ");
             mActiveUids.dump(pw, "  ");
+            if (mDemoteTopAppReasons != 0) {
+                pw.println("  mDemoteTopAppReasons=" + mDemoteTopAppReasons);
+            }
         }
 
         if (!printedAnything) {
@@ -5595,12 +5670,17 @@
         @HotPath(caller = HotPath.OOM_ADJUSTMENT)
         @Override
         public int getTopProcessState() {
+            final int topState = mTopProcessState;
+            if (mDemoteTopAppReasons != 0 && topState == ActivityManager.PROCESS_STATE_TOP) {
+                // There may be a more important UI/animation than the top app.
+                return ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+            }
             if (mRetainPowerModeAndTopProcessState) {
                 // There is a launching app while device may be sleeping, force the top state so
                 // the launching process can have top-app scheduling group.
                 return ActivityManager.PROCESS_STATE_TOP;
             }
-            return mTopProcessState;
+            return topState;
         }
 
         @HotPath(caller = HotPath.PROCESS_CHANGE)
@@ -6626,15 +6706,6 @@
         }
 
         @Override
-        public void notifyWakingUp() {
-            synchronized (mGlobalLock) {
-                // Start a transition for waking. This is needed for showWhenLocked activities.
-                getTransitionController().requestTransitionIfNeeded(TRANSIT_WAKE, 0 /* flags */,
-                        null /* trigger */, mRootWindowContainer.getDefaultDisplay());
-            }
-        }
-
-        @Override
         public void registerActivityStartInterceptor(
                 @ActivityInterceptorCallback.OrderedId int id,
                 ActivityInterceptorCallback callback) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 35f977d..8474068 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -42,6 +42,7 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
 import static android.os.Process.INVALID_UID;
+import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -73,13 +74,9 @@
 import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS_AND_RESTORE;
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
 import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT;
 import static com.android.server.wm.Task.TAG_CLEANUP;
-import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
-import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
 import android.Manifest;
@@ -93,6 +90,7 @@
 import android.app.IActivityClientController;
 import android.app.ProfilerInfo;
 import android.app.ResultInfo;
+import android.app.TaskInfo;
 import android.app.WaitResult;
 import android.app.servertransaction.ActivityLifecycleItem;
 import android.app.servertransaction.ClientTransaction;
@@ -121,7 +119,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.Trace;
@@ -155,6 +152,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.function.Consumer;
 
 // TODO: This class has become a dumping ground. Let's
 // - Move things relating to the hierarchy to RootWindowContainer
@@ -246,6 +244,9 @@
     /** Helper class to abstract out logic for fetching the set of currently running tasks */
     private RunningTasks mRunningTasks;
 
+    /** Helper for {@link Task#fillTaskInfo}. */
+    final TaskInfoHelper mTaskInfoHelper = new TaskInfoHelper();
+
     private final ActivityTaskSupervisorHandler mHandler;
     final Looper mLooper;
 
@@ -1316,7 +1317,7 @@
     }
 
     void acquireLaunchWakelock() {
-        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != SYSTEM_UID) {
             throw new IllegalStateException("Calling must be system uid");
         }
         mLaunchingActivityWakeLock.acquire();
@@ -1389,8 +1390,7 @@
 
             if (mLaunchingActivityWakeLock.isHeld()) {
                 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
-                if (VALIDATE_WAKE_LOCK_CALLER &&
-                        Binder.getCallingUid() != Process.myUid()) {
+                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != SYSTEM_UID) {
                     throw new IllegalStateException("Calling must be system uid");
                 }
                 mLaunchingActivityWakeLock.release();
@@ -1434,10 +1434,10 @@
                 mUserLeaving = true;
             }
 
-            task.mTransitionController.requestTransitionIfNeeded(TRANSIT_TO_FRONT,
-                    0 /* flags */, task, task /* readyGroupRef */,
-                    options != null ? options.getRemoteTransition() : null,
-                    null /* displayChange */);
+            final Transition newTransition = task.mTransitionController.isShellTransitionsEnabled()
+                    ? task.mTransitionController.isCollecting() ? null
+                    : task.mTransitionController.createTransition(TRANSIT_TO_FRONT) : null;
+            task.mTransitionController.collect(task);
             reason = reason + " findTaskToMoveToFront";
             boolean reparented = false;
             if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) {
@@ -1480,6 +1480,17 @@
             handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
                     mRootWindowContainer.getDefaultTaskDisplayArea(), currentRootTask,
                     forceNonResizeable);
+            if (r != null) {
+                // Use a starting window to reduce the transition latency for reshowing the task.
+                // Note that with shell transition, this should be executed before requesting
+                // transition to avoid delaying the starting window.
+                r.showStartingWindow(true /* taskSwitch */);
+            }
+            if (newTransition != null) {
+                task.mTransitionController.requestStartTransition(newTransition, task,
+                        options != null ? options.getRemoteTransition() : null,
+                        null /* displayChange */);
+            }
         } finally {
             mUserLeaving = false;
         }
@@ -1800,7 +1811,7 @@
         if (!mGoingToSleepWakeLock.isHeld()) {
             mGoingToSleepWakeLock.acquire();
             if (mLaunchingActivityWakeLock.isHeld()) {
-                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != SYSTEM_UID) {
                     throw new IllegalStateException("Calling must be system uid");
                 }
                 mLaunchingActivityWakeLock.release();
@@ -1921,9 +1932,7 @@
         ArrayList<ActivityRecord> readyToStopActivities = null;
         for (int i = mStoppingActivities.size() - 1; i >= 0; --i) {
             final ActivityRecord s = mStoppingActivities.get(i);
-            final boolean animating = s.isAnimating(TRANSITION | PARENTS,
-                    ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS)
-                    || s.inTransition();
+            final boolean animating = s.isInTransition();
             ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
                     + "finishing=%s", s, s.nowVisible, animating, s.finishing);
             if (!animating || mService.mShuttingDown) {
@@ -2461,8 +2470,7 @@
                 case LAUNCH_TIMEOUT_MSG: {
                     if (mLaunchingActivityWakeLock.isHeld()) {
                         Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
-                        if (VALIDATE_WAKE_LOCK_CALLER
-                                && Binder.getCallingUid() != Process.myUid()) {
+                        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != SYSTEM_UID) {
                             throw new IllegalStateException("Calling must be system uid");
                         }
                         mLaunchingActivityWakeLock.release();
@@ -2623,6 +2631,41 @@
     }
 
     /**
+     * Fills the info that needs to iterate all activities of task, such as the number of
+     * non-finishing activities and collecting launch cookies.
+     */
+    static class TaskInfoHelper implements Consumer<ActivityRecord> {
+        private TaskInfo mInfo;
+        private ActivityRecord mTopRunning;
+
+        ActivityRecord fillAndReturnTop(Task task, TaskInfo info) {
+            info.numActivities = 0;
+            info.baseActivity = null;
+            mInfo = info;
+            task.forAllActivities(this);
+            final ActivityRecord top = mTopRunning;
+            mTopRunning = null;
+            mInfo = null;
+            return top;
+        }
+
+        @Override
+        public void accept(ActivityRecord r) {
+            if (r.finishing) {
+                return;
+            }
+            if (r.mLaunchCookie != null) {
+                mInfo.addLaunchCookie(r.mLaunchCookie);
+            }
+            mInfo.numActivities++;
+            mInfo.baseActivity = r.mActivityComponent;
+            if (mTopRunning == null) {
+                mTopRunning = r;
+            }
+        }
+    }
+
+    /**
      * Internal container to store a match qualifier alongside a WaitResult.
      */
     private static class WaitInfo {
diff --git a/services/core/java/com/android/server/wm/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index 6befefd..b23f501 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -256,7 +256,7 @@
         Slog.i(TAG_WM, "Pre-dump for unresponsive");
 
         final ArrayList<Integer> firstPids = new ArrayList<>(1);
-        firstPids.add(ActivityManagerService.MY_PID);
+        firstPids.add(WindowManagerService.MY_PID);
         ArrayList<Integer> nativePids = null;
         final int[] pids = shouldDumpSf[0]
                 ? Process.getPidsForCommands(new String[] { "/system/bin/surfaceflinger" })
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 5410dd8..53f2c71 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -34,6 +34,8 @@
 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_RELAUNCH;
 import static android.view.WindowManager.TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN;
 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE;
@@ -64,6 +66,9 @@
 import static com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_dreamActivityCloseExitAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_dreamActivityOpenEnterAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_dreamActivityOpenExitAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindSourceAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindTargetAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation;
@@ -309,6 +314,10 @@
         setAppTransitionState(APP_STATE_TIMEOUT);
     }
 
+    @ColorInt int getNextAppTransitionBackgroundColor() {
+        return mNextAppTransitionBackgroundColor;
+    }
+
     HardwareBuffer getAppTransitionThumbnailHeader(WindowContainer container) {
         AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(
                 container.hashCode());
@@ -518,6 +527,95 @@
         return TransitionAnimation.loadAnimationSafely(context, resId, TAG);
     }
 
+    static int mapOpenCloseTransitTypes(int transit, boolean enter) {
+        int animAttr = 0;
+        switch (transit) {
+            case TRANSIT_OLD_ACTIVITY_OPEN:
+            case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN:
+                animAttr = enter
+                        ? WindowAnimation_activityOpenEnterAnimation
+                        : WindowAnimation_activityOpenExitAnimation;
+                break;
+            case TRANSIT_OLD_ACTIVITY_CLOSE:
+            case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE:
+                animAttr = enter
+                        ? WindowAnimation_activityCloseEnterAnimation
+                        : WindowAnimation_activityCloseExitAnimation;
+                break;
+            case TRANSIT_OLD_TASK_OPEN:
+                animAttr = enter
+                        ? WindowAnimation_taskOpenEnterAnimation
+                        : WindowAnimation_taskOpenExitAnimation;
+                break;
+            case TRANSIT_OLD_TASK_CLOSE:
+                animAttr = enter
+                        ? WindowAnimation_taskCloseEnterAnimation
+                        : WindowAnimation_taskCloseExitAnimation;
+                break;
+            case TRANSIT_OLD_TASK_TO_FRONT:
+                animAttr = enter
+                        ? WindowAnimation_taskToFrontEnterAnimation
+                        : WindowAnimation_taskToFrontExitAnimation;
+                break;
+            case TRANSIT_OLD_TASK_TO_BACK:
+                animAttr = enter
+                        ? WindowAnimation_taskToBackEnterAnimation
+                        : WindowAnimation_taskToBackExitAnimation;
+                break;
+            case TRANSIT_OLD_WALLPAPER_OPEN:
+                animAttr = enter
+                        ? WindowAnimation_wallpaperOpenEnterAnimation
+                        : WindowAnimation_wallpaperOpenExitAnimation;
+                break;
+            case TRANSIT_OLD_WALLPAPER_CLOSE:
+                animAttr = enter
+                        ? WindowAnimation_wallpaperCloseEnterAnimation
+                        : WindowAnimation_wallpaperCloseExitAnimation;
+                break;
+            case TRANSIT_OLD_WALLPAPER_INTRA_OPEN:
+                animAttr = enter
+                        ? WindowAnimation_wallpaperIntraOpenEnterAnimation
+                        : WindowAnimation_wallpaperIntraOpenExitAnimation;
+                break;
+            case TRANSIT_OLD_WALLPAPER_INTRA_CLOSE:
+                animAttr = enter
+                        ? WindowAnimation_wallpaperIntraCloseEnterAnimation
+                        : WindowAnimation_wallpaperIntraCloseExitAnimation;
+                break;
+            case TRANSIT_OLD_TASK_OPEN_BEHIND:
+                animAttr = enter
+                        ? WindowAnimation_launchTaskBehindSourceAnimation
+                        : WindowAnimation_launchTaskBehindTargetAnimation;
+                break;
+            // TODO(b/189386466): Use activity transition as the fallback. Investigate if we
+            //  need new TaskFragment transition.
+            case TRANSIT_OLD_TASK_FRAGMENT_OPEN:
+                animAttr = enter
+                        ? WindowAnimation_activityOpenEnterAnimation
+                        : WindowAnimation_activityOpenExitAnimation;
+                break;
+            // TODO(b/189386466): Use activity transition as the fallback. Investigate if we
+            //  need new TaskFragment transition.
+            case TRANSIT_OLD_TASK_FRAGMENT_CLOSE:
+                animAttr = enter
+                        ? WindowAnimation_activityCloseEnterAnimation
+                        : WindowAnimation_activityCloseExitAnimation;
+                break;
+            case TRANSIT_OLD_DREAM_ACTIVITY_OPEN:
+                animAttr = enter
+                        ? WindowAnimation_dreamActivityOpenEnterAnimation
+                        : WindowAnimation_dreamActivityOpenExitAnimation;
+                break;
+            case TRANSIT_OLD_DREAM_ACTIVITY_CLOSE:
+                animAttr = enter
+                        ? 0
+                        : WindowAnimation_dreamActivityCloseExitAnimation;
+                break;
+        }
+
+        return animAttr;
+    }
+
     @Nullable
     Animation loadAnimationAttr(LayoutParams lp, int animAttr, int transit) {
         return mTransitionAnimation.loadAnimationAttr(lp, animAttr, transit);
@@ -645,9 +743,15 @@
             @Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean isVoiceInteraction,
             boolean freeform, WindowContainer container) {
 
-        if (mNextAppTransitionOverrideRequested
-                && (container.canCustomizeAppTransition() || mOverrideTaskTransition)) {
-            mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
+        final boolean canCustomizeAppTransition = container.canCustomizeAppTransition();
+
+        if (mNextAppTransitionOverrideRequested) {
+            if (canCustomizeAppTransition || mOverrideTaskTransition) {
+                mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
+            } else {
+                ProtoLog.e(WM_DEBUG_APP_TRANSITIONS_ANIM, "applyAnimation: "
+                        + " override requested, but it is prohibited by policy.");
+            }
         }
 
         Animation a;
@@ -762,87 +866,16 @@
                     "applyAnimation: anim=%s transit=%s isEntrance=%b Callers=%s",
                     a, appTransitionOldToString(transit), enter, Debug.getCallers(3));
         } else {
-            int animAttr = 0;
-            switch (transit) {
-                case TRANSIT_OLD_ACTIVITY_OPEN:
-                case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN:
-                    animAttr = enter
-                            ? WindowAnimation_activityOpenEnterAnimation
-                            : WindowAnimation_activityOpenExitAnimation;
-                    break;
-                case TRANSIT_OLD_ACTIVITY_CLOSE:
-                case TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE:
-                    animAttr = enter
-                            ? WindowAnimation_activityCloseEnterAnimation
-                            : WindowAnimation_activityCloseExitAnimation;
-                    break;
-                case TRANSIT_OLD_TASK_OPEN:
-                    animAttr = enter
-                            ? WindowAnimation_taskOpenEnterAnimation
-                            : WindowAnimation_taskOpenExitAnimation;
-                    break;
-                case TRANSIT_OLD_TASK_CLOSE:
-                    animAttr = enter
-                            ? WindowAnimation_taskCloseEnterAnimation
-                            : WindowAnimation_taskCloseExitAnimation;
-                    break;
-                case TRANSIT_OLD_TASK_TO_FRONT:
-                    animAttr = enter
-                            ? WindowAnimation_taskToFrontEnterAnimation
-                            : WindowAnimation_taskToFrontExitAnimation;
-                    break;
-                case TRANSIT_OLD_TASK_TO_BACK:
-                    animAttr = enter
-                            ? WindowAnimation_taskToBackEnterAnimation
-                            : WindowAnimation_taskToBackExitAnimation;
-                    break;
-                case TRANSIT_OLD_WALLPAPER_OPEN:
-                    animAttr = enter
-                            ? WindowAnimation_wallpaperOpenEnterAnimation
-                            : WindowAnimation_wallpaperOpenExitAnimation;
-                    break;
-                case TRANSIT_OLD_WALLPAPER_CLOSE:
-                    animAttr = enter
-                            ? WindowAnimation_wallpaperCloseEnterAnimation
-                            : WindowAnimation_wallpaperCloseExitAnimation;
-                    break;
-                case TRANSIT_OLD_WALLPAPER_INTRA_OPEN:
-                    animAttr = enter
-                            ? WindowAnimation_wallpaperIntraOpenEnterAnimation
-                            : WindowAnimation_wallpaperIntraOpenExitAnimation;
-                    break;
-                case TRANSIT_OLD_WALLPAPER_INTRA_CLOSE:
-                    animAttr = enter
-                            ? WindowAnimation_wallpaperIntraCloseEnterAnimation
-                            : WindowAnimation_wallpaperIntraCloseExitAnimation;
-                    break;
-                case TRANSIT_OLD_TASK_OPEN_BEHIND:
-                    animAttr = enter
-                            ? WindowAnimation_launchTaskBehindSourceAnimation
-                            : WindowAnimation_launchTaskBehindTargetAnimation;
-                    break;
-                // TODO(b/189386466): Use activity transition as the fallback. Investigate if we
-                //  need new TaskFragment transition.
-                case TRANSIT_OLD_TASK_FRAGMENT_OPEN:
-                    animAttr = enter
-                            ? WindowAnimation_activityOpenEnterAnimation
-                            : WindowAnimation_activityOpenExitAnimation;
-                    break;
-                // TODO(b/189386466): Use activity transition as the fallback. Investigate if we
-                //  need new TaskFragment transition.
-                case TRANSIT_OLD_TASK_FRAGMENT_CLOSE:
-                    animAttr = enter
-                            ? WindowAnimation_activityCloseEnterAnimation
-                            : WindowAnimation_activityCloseExitAnimation;
-                    break;
-            }
-            a = animAttr != 0 ? loadAnimationAttr(lp, animAttr, transit) : null;
+            int animAttr = mapOpenCloseTransitTypes(transit, enter);
+            a = animAttr == 0 ? null : (canCustomizeAppTransition
+                ? loadAnimationAttr(lp, animAttr, transit)
+                : mTransitionAnimation.loadDefaultAnimationAttr(animAttr, transit));
 
             ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
                     "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b "
-                            + "Callers=%s",
+                            + " canCustomizeAppTransition=%b Callers=%s",
                     a, animAttr, appTransitionOldToString(transit), enter,
-                    Debug.getCallers(3));
+                    canCustomizeAppTransition, Debug.getCallers(3));
         }
         setAppTransitionFinishedCallbackIfNeeded(a);
 
@@ -988,18 +1021,19 @@
     }
 
     void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter) {
-        overridePendingAppTransitionRemote(remoteAnimationAdapter, false /* sync */);
+        overridePendingAppTransitionRemote(remoteAnimationAdapter, false /* sync */,
+                false /* isActivityEmbedding*/);
     }
 
     void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter,
-            boolean sync) {
+            boolean sync, boolean isActivityEmbedding) {
         ProtoLog.i(WM_DEBUG_APP_TRANSITIONS, "Override pending remote transitionSet=%b adapter=%s",
                         isTransitionSet(), remoteAnimationAdapter);
         if (isTransitionSet() && !mNextAppTransitionIsSync) {
             clear();
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE;
             mRemoteAnimationController = new RemoteAnimationController(mService, mDisplayContent,
-                    remoteAnimationAdapter, mHandler);
+                    remoteAnimationAdapter, mHandler, isActivityEmbedding);
             mNextAppTransitionIsSync = sync;
         }
     }
@@ -1157,6 +1191,12 @@
             case TRANSIT_OLD_TASK_FRAGMENT_CHANGE: {
                 return "TRANSIT_OLD_TASK_FRAGMENT_CHANGE";
             }
+            case TRANSIT_OLD_DREAM_ACTIVITY_OPEN: {
+                return "TRANSIT_OLD_DREAM_ACTIVITY_OPEN";
+            }
+            case TRANSIT_OLD_DREAM_ACTIVITY_CLOSE: {
+                return "TRANSIT_OLD_DREAM_ACTIVITY_CLOSE";
+            }
             default: {
                 return "<UNKNOWN: " + transition + ">";
             }
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index e60ea12..fb9d7e6 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_FLAG_APP_CRASHED;
@@ -32,6 +33,8 @@
 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_RELAUNCH;
 import static android.view.WindowManager.TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN;
 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE;
@@ -339,6 +342,9 @@
             ArraySet<WindowContainer> changingContainers, @Nullable WindowState wallpaperTarget,
             @Nullable WindowState oldWallpaper, boolean skipAppTransitionAnimation) {
 
+        final ActivityRecord topOpeningApp = getTopApp(openingApps, false /* ignoreHidden */);
+        final ActivityRecord topClosingApp = getTopApp(closingApps, true /* ignoreHidden */);
+
         // Determine if closing and opening app token sets are wallpaper targets, in which case
         // special animations are needed.
         final boolean openingAppHasWallpaper = canBeWallpaperTarget(openingApps)
@@ -346,7 +352,7 @@
         final boolean closingAppHasWallpaper = canBeWallpaperTarget(closingApps)
                 && wallpaperTarget != null;
 
-        // Keyguard transit has highest priority.
+        // Keyguard transit has high priority.
         switch (appTransition.getKeyguardTransition()) {
             case TRANSIT_KEYGUARD_GOING_AWAY:
                 return openingAppHasWallpaper ? TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER
@@ -361,6 +367,15 @@
                 return TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
         }
 
+        // Determine whether the top opening and closing activity is a dream activity. If so, this
+        // has higher priority than others except keyguard transit.
+        if (topOpeningApp != null && topOpeningApp.getActivityType() == ACTIVITY_TYPE_DREAM) {
+            return TRANSIT_OLD_DREAM_ACTIVITY_OPEN;
+        } else if (topClosingApp != null
+                && topClosingApp.getActivityType() == ACTIVITY_TYPE_DREAM) {
+            return TRANSIT_OLD_DREAM_ACTIVITY_CLOSE;
+        }
+
         // This is not keyguard transition and one of the app has request to skip app transition.
         if (skipAppTransitionAnimation) {
             return WindowManager.TRANSIT_OLD_UNSET;
@@ -424,11 +439,6 @@
             }
         }
 
-        final ActivityRecord topOpeningApp = getTopApp(openingApps,
-                false /* ignoreHidden */);
-        final ActivityRecord topClosingApp = getTopApp(closingApps,
-                true /* ignoreHidden */);
-
         if (closingAppHasWallpaper && openingAppHasWallpaper) {
             ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Wallpaper animation!");
             switch (firstTransit) {
@@ -682,7 +692,8 @@
         if (adapter == null) {
             return false;
         }
-        mDisplayContent.mAppTransition.overridePendingAppTransitionRemote(adapter);
+        mDisplayContent.mAppTransition.overridePendingAppTransitionRemote(
+                adapter, false /* sync */, true /*isActivityEmbedding*/);
         ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
                 "Override with TaskFragment remote animation for transit=%s",
                 AppTransition.appTransitionOldToString(transit));
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 61deb59..e3de18b1 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -18,7 +18,6 @@
 
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
 
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_TOKEN_TRANSFORM;
 
@@ -144,8 +143,7 @@
         // Legacy animation doesn't need to wait for the start transaction.
         if (mTransitionOp == OP_LEGACY) {
             mIsStartTransactionCommitted = true;
-        } else if (displayContent.mTransitionController.useShellTransitionsRotation()
-                || displayContent.mTransitionController.isCollecting(displayContent)) {
+        } else if (displayContent.mTransitionController.isCollecting(displayContent)) {
             keepAppearanceInPreviousRotation();
         }
     }
@@ -153,8 +151,7 @@
     /** Assigns the operation for the window tokens which can update rotation asynchronously. */
     @Override
     public void accept(WindowState w) {
-        if (w.mActivityRecord != null || !w.mHasSurface || w.mIsWallpaper || w.mIsImWindow
-                || w.mAttrs.type == TYPE_NOTIFICATION_SHADE) {
+        if (!w.mHasSurface || !canBeAsync(w.mToken)) {
             return;
         }
         if (mTransitionOp == OP_LEGACY && w.mForceSeamlesslyRotate) {
@@ -186,23 +183,28 @@
         mTargetWindowTokens.put(w.mToken, new Operation(action));
     }
 
+    /** Returns {@code true} if the window token can update rotation independently. */
+    static boolean canBeAsync(WindowToken token) {
+        final int type = token.windowType;
+        return type > WindowManager.LayoutParams.LAST_APPLICATION_WINDOW
+                && type != WindowManager.LayoutParams.TYPE_INPUT_METHOD
+                && type != WindowManager.LayoutParams.TYPE_WALLPAPER
+                && type != WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
+    }
+
     /**
      * Enables {@link #handleFinishDrawing(WindowState, SurfaceControl.Transaction)} to capture the
      * draw transactions of the target windows if needed.
      */
     void keepAppearanceInPreviousRotation() {
+        if (mIsSyncDrawRequested) return;
         // The transition sync group may be finished earlier because it doesn't wait for these
         // target windows. But the windows still need to use sync transaction to keep the appearance
         // in previous rotation, so request a no-op sync to keep the state.
         for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
-            if (mHasScreenRotationAnimation
-                    && mTargetWindowTokens.valueAt(i).mAction == Operation.ACTION_FADE) {
-                // The windows are hidden (leash is alpha 0) before finishing drawing so it is
-                // unnecessary to request sync.
-                continue;
-            }
             final WindowToken token = mTargetWindowTokens.keyAt(i);
             for (int j = token.getChildCount() - 1; j >= 0; j--) {
+                // TODO(b/234585256): The consumer should be handleFinishDrawing().
                 token.getChildAt(j).applyWithNextDraw(t -> {});
             }
         }
@@ -214,10 +216,10 @@
     private void finishOp(WindowToken windowToken) {
         final Operation op = mTargetWindowTokens.remove(windowToken);
         if (op == null) return;
-        if (op.mCapturedDrawTransaction != null) {
+        if (op.mDrawTransaction != null) {
             // Unblock the window to show its latest content.
-            mDisplayContent.getPendingTransaction().merge(op.mCapturedDrawTransaction);
-            op.mCapturedDrawTransaction = null;
+            mDisplayContent.getPendingTransaction().merge(op.mDrawTransaction);
+            op.mDrawTransaction = null;
             if (DEBUG) Slog.d(TAG, "finishOp merge transaction " + windowToken.getTopChild());
         }
         if (op.mAction == Operation.ACTION_FADE) {
@@ -351,14 +353,34 @@
     }
 
     /**
-     * Whether the insets animation leash should use previous position when running fade out
-     * animation in rotated display.
+     * Whether the insets animation leash should use previous position when running fade animation
+     * or seamless transformation in a rotated display.
      */
     boolean shouldFreezeInsetsPosition(WindowState w) {
         return mTransitionOp == OP_APP_SWITCH && w.mTransitionController.inTransition()
                 && isTargetToken(w.mToken);
     }
 
+    /**
+     * Returns the transaction which will be applied after the window redraws in new rotation.
+     * This is used to update the position of insets animation leash synchronously.
+     */
+    SurfaceControl.Transaction getDrawTransaction(WindowToken token) {
+        if (mTransitionOp == OP_LEGACY) {
+            // Legacy transition uses startSeamlessRotation and finishSeamlessRotation of
+            // InsetsSourceProvider.
+            return null;
+        }
+        final Operation op = mTargetWindowTokens.get(token);
+        if (op != null) {
+            if (op.mDrawTransaction == null) {
+                op.mDrawTransaction = new SurfaceControl.Transaction();
+            }
+            return op.mDrawTransaction;
+        }
+        return null;
+    }
+
     void setOnShowRunnable(Runnable onShowRunnable) {
         mOnShowRunnable = onShowRunnable;
     }
@@ -368,6 +390,7 @@
      * transition starts. And associate transaction callback to consume pending animations.
      */
     void setupStartTransaction(SurfaceControl.Transaction t) {
+        if (mIsStartTransactionCommitted) return;
         for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
             final Operation op = mTargetWindowTokens.valueAt(i);
             final SurfaceControl leash = op.mLeash;
@@ -395,7 +418,6 @@
             }
         }
 
-        if (mIsStartTransactionCommitted) return;
         // If there are windows have redrawn in new rotation but the start transaction has not
         // been applied yet, the fade-in animation will be deferred. So once the transaction is
         // committed, the fade-in animation can run with screen rotation animation.
@@ -452,23 +474,18 @@
      * by this controller.
      */
     boolean handleFinishDrawing(WindowState w, SurfaceControl.Transaction postDrawTransaction) {
-        if (mTransitionOp == OP_LEGACY || postDrawTransaction == null
-                || !mIsSyncDrawRequested || !w.mTransitionController.inTransition()) {
+        if (mTransitionOp == OP_LEGACY || postDrawTransaction == null || !mIsSyncDrawRequested) {
             return false;
         }
         final Operation op = mTargetWindowTokens.get(w.mToken);
         if (op == null) return false;
-        final boolean keepUntilTransitionFinish =
-                mTransitionOp == OP_APP_SWITCH && op.mAction == Operation.ACTION_FADE;
-        final boolean keepUntilStartTransaction =
-                !mIsStartTransactionCommitted && op.mAction == Operation.ACTION_SEAMLESS;
-        if (!keepUntilTransitionFinish && !keepUntilStartTransaction) return false;
-        if (op.mCapturedDrawTransaction == null) {
-            op.mCapturedDrawTransaction = postDrawTransaction;
+        if (DEBUG) Slog.d(TAG, "handleFinishDrawing " + w);
+        if (op.mDrawTransaction == null) {
+            op.mDrawTransaction = postDrawTransaction;
         } else {
-            op.mCapturedDrawTransaction.merge(postDrawTransaction);
+            op.mDrawTransaction.merge(postDrawTransaction);
         }
-        if (DEBUG) Slog.d(TAG, "Capture draw transaction " + w);
+        mDisplayContent.finishAsyncRotation(w.mToken);
         return true;
     }
 
@@ -512,7 +529,7 @@
          * the start transaction of transition, so there won't be a flickering such as the window
          * has redrawn during fading out.
          */
-        SurfaceControl.Transaction mCapturedDrawTransaction;
+        SurfaceControl.Transaction mDrawTransaction;
 
         Operation(@Action int action) {
             mAction = action;
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index 46ce433..9a94a4f 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -236,12 +236,18 @@
 
         private void onTimeout() {
             if (!mActiveSyncs.contains(mSyncId)) return;
+            boolean allFinished = true;
             for (int i = mRootMembers.size() - 1; i >= 0; --i) {
                 final WindowContainer<?> wc = mRootMembers.valueAt(i);
                 if (!wc.isSyncFinished()) {
+                    allFinished = false;
                     Slog.i(TAG, "Unfinished container: " + wc);
                 }
             }
+            if (allFinished && !mReady) {
+                Slog.w(TAG, "Sync group " + mSyncId + " timed-out because not ready. If you see "
+                        + "this, please file a bug.");
+            }
             finishNow();
         }
     }
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index fcdf175..0c6cea8 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -486,14 +486,6 @@
         return WindowConfiguration.inMultiWindowMode(windowingMode);
     }
 
-    /**
-     * Returns true if this container supports split-screen multi-window and can be put in
-     * split-screen based on its current state.
-     */
-    public boolean supportsSplitScreenWindowingMode() {
-        return mFullConfiguration.windowConfiguration.supportSplitScreenWindowingMode();
-    }
-
     public boolean inPinnedWindowingMode() {
         return mFullConfiguration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_PINNED;
     }
diff --git a/services/core/java/com/android/server/wm/ContentRecordingController.java b/services/core/java/com/android/server/wm/ContentRecordingController.java
index fca4942..fff7637 100644
--- a/services/core/java/com/android/server/wm/ContentRecordingController.java
+++ b/services/core/java/com/android/server/wm/ContentRecordingController.java
@@ -63,6 +63,7 @@
      */
     void setContentRecordingSessionLocked(@Nullable ContentRecordingSession incomingSession,
             @NonNull WindowManagerService wmService) {
+        // TODO(b/219761722) handle a null session arriving due to task setup failing
         if (incomingSession != null && (!ContentRecordingSession.isValid(incomingSession)
                 || ContentRecordingSession.isSameDisplay(mSession, incomingSession))) {
             // Ignore an invalid session, or a session for the same display as currently recording.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 72b996c..288777b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -130,7 +130,6 @@
 import static com.android.server.wm.DisplayContentProto.ROOT_DISPLAY_AREA;
 import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
 import static com.android.server.wm.DisplayContentProto.SLEEP_TOKENS;
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -558,7 +557,8 @@
     final FixedRotationTransitionListener mFixedRotationTransitionListener =
             new FixedRotationTransitionListener();
 
-    private PhysicalDisplaySwitchTransitionLauncher mDisplaySwitchTransitionLauncher;
+    private final PhysicalDisplaySwitchTransitionLauncher mDisplaySwitchTransitionLauncher;
+    final RemoteDisplayChangeController mRemoteDisplayChangeController;
 
     /** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
     final ArrayList<WindowState> mWinAddedSinceNullFocus = new ArrayList<>();
@@ -756,8 +756,7 @@
         }
         if (w.mAttrs.type == TYPE_INPUT_METHOD_DIALOG && mImeLayeringTarget != null
                 && !mImeLayeringTarget.getRequestedVisibility(ITYPE_IME)
-                && mImeLayeringTarget.isAnimating(PARENTS | TRANSITION,
-                ANIMATION_TYPE_APP_TRANSITION)) {
+                && !mImeLayeringTarget.isVisibleRequested()) {
             return false;
         }
 
@@ -1054,6 +1053,7 @@
         mUnknownAppVisibilityController = new UnknownAppVisibilityController(mWmService, this);
         mDisplaySwitchTransitionLauncher = new PhysicalDisplaySwitchTransitionLauncher(this,
                 mTransitionController);
+        mRemoteDisplayChangeController = new RemoteDisplayChangeController(mWmService, mDisplayId);
 
         final InputChannel inputChannel = mWmService.mInputManager.monitorInput(
                 "PointerEventDispatcher" + mDisplayId, mDisplayId);
@@ -1435,7 +1435,7 @@
         if (!isReady()) {
             return;
         }
-        if (mDisplayRotation.isWaitingForRemoteRotation()) {
+        if (mRemoteDisplayChangeController.isWaitingForRemoteDisplayChange()) {
             return;
         }
 
@@ -1535,8 +1535,8 @@
             config = new Configuration();
             computeScreenConfiguration(config);
         } else if (!(mTransitionController.isCollecting(this)
-                // If waiting for a remote rotation, don't prematurely update configuration.
-                || mDisplayRotation.isWaitingForRemoteRotation())) {
+                // If waiting for a remote display change, don't prematurely update configuration.
+                || mRemoteDisplayChangeController.isWaitingForRemoteDisplayChange())) {
             // No obvious action we need to take, but if our current state mismatches the
             // activity manager's, update it, disregarding font scale, which should remain set
             // to the value of the previous configuration.
@@ -1583,8 +1583,10 @@
                 mAtmService.getTaskChangeNotificationController()
                         .notifyTaskRequestedOrientationChanged(task.mTaskId, orientation);
             }
-            // Currently there is no use case from non-activity.
-            if (handleTopActivityLaunchingInDifferentOrientation(r, true /* checkOpening */)) {
+            // The orientation source may not be the top if it uses SCREEN_ORIENTATION_BEHIND.
+            final ActivityRecord topCandidate = !r.mVisibleRequested ? topRunningActivity() : r;
+            if (handleTopActivityLaunchingInDifferentOrientation(
+                    topCandidate, r, true /* checkOpening */)) {
                 // Display orientation should be deferred until the top fixed rotation is finished.
                 return false;
             }
@@ -1596,21 +1598,31 @@
     boolean isSyncFinished() {
         // Do not consider children because if they are requested to be synced, they should be
         // added to sync group explicitly.
-        return !mDisplayRotation.isWaitingForRemoteRotation();
+        return !mRemoteDisplayChangeController.isWaitingForRemoteDisplayChange();
     }
 
     /**
      * Returns a valid rotation if the activity can use different orientation than the display.
-     * Otherwise {@link #ROTATION_UNDEFINED}.
+     * Otherwise {@link android.app.WindowConfiguration#ROTATION_UNDEFINED}.
      */
     @Rotation
     int rotationForActivityInDifferentOrientation(@NonNull ActivityRecord r) {
         if (mTransitionController.useShellTransitionsRotation()) {
             return ROTATION_UNDEFINED;
         }
-        if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
+        if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM
+                || getIgnoreOrientationRequest()) {
             return ROTATION_UNDEFINED;
         }
+        if (r.mOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
+            final ActivityRecord nextCandidate = getActivity(
+                    a -> a.mOrientation != SCREEN_ORIENTATION_UNSET
+                            && a.mOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND,
+                    r, false /* includeBoundary */, true /* traverseTopToBottom */);
+            if (nextCandidate != null) {
+                r = nextCandidate;
+            }
+        }
         if (r.inMultiWindowMode() || r.getRequestedConfigurationOrientation(true /* forDisplay */)
                 == getConfiguration().orientation) {
             return ROTATION_UNDEFINED;
@@ -1624,18 +1636,25 @@
         return rotation;
     }
 
+    boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
+            boolean checkOpening) {
+        return handleTopActivityLaunchingInDifferentOrientation(r, r, checkOpening);
+    }
+
     /**
      * We need to keep display rotation fixed for a while when the activity in different orientation
      * is launching until the launch animation is done to avoid showing the previous activity
      * inadvertently in a wrong orientation.
      *
      * @param r The launching activity which may change display orientation.
+     * @param orientationSrc It may be different from {@param r} if the launching activity uses
+     *                       "behind" orientation.
      * @param checkOpening Whether to check if the activity is animating by transition. Set to
      *                     {@code true} if the caller is not sure whether the activity is launching.
      * @return {@code true} if the fixed rotation is started.
      */
-    boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
-            boolean checkOpening) {
+    private boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
+            @NonNull ActivityRecord orientationSrc, boolean checkOpening) {
         if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
             return false;
         }
@@ -1684,7 +1703,7 @@
             // animation is not running (it may be swiping to home).
             return false;
         }
-        final int rotation = rotationForActivityInDifferentOrientation(r);
+        final int rotation = rotationForActivityInDifferentOrientation(orientationSrc);
         if (rotation == ROTATION_UNDEFINED) {
             // The display rotation won't be changed by current top activity. The client side
             // adjustments of previous rotated activity should be cleared earlier. Otherwise if
@@ -1762,7 +1781,7 @@
      * rotation transform to it and indicate that the display may be rotated after it is launched.
      */
     void setFixedRotationLaunchingApp(@NonNull ActivityRecord r, @Rotation int rotation) {
-        final WindowToken prevRotatedLaunchingApp = mFixedRotationLaunchingApp;
+        final ActivityRecord prevRotatedLaunchingApp = mFixedRotationLaunchingApp;
         if (prevRotatedLaunchingApp == r
                 && r.getWindowConfiguration().getRotation() == rotation) {
             // The given launching app and target rotation are the same as the existing ones.
@@ -1771,8 +1790,7 @@
         if (prevRotatedLaunchingApp != null
                 && prevRotatedLaunchingApp.getWindowConfiguration().getRotation() == rotation
                 // It is animating so we can expect there will have a transition callback.
-                && (prevRotatedLaunchingApp.isAnimating(TRANSITION | PARENTS)
-                        || mTransitionController.inTransition(prevRotatedLaunchingApp))) {
+                && (prevRotatedLaunchingApp.isInTransition())) {
             // It may be the case that multiple activities launch consecutively. Because their
             // rotation are the same, the transformed state can be shared to avoid duplicating
             // the heavy operations. This also benefits that the states of multiple activities
@@ -1813,8 +1831,8 @@
             sendNewConfiguration();
             return;
         }
-        if (mDisplayRotation.isWaitingForRemoteRotation()) {
-            // There is pending rotation change to apply.
+        if (mRemoteDisplayChangeController.isWaitingForRemoteDisplayChange()) {
+            // There is pending display change to apply.
             return;
         }
         // The orientation of display is not changed.
@@ -1862,7 +1880,7 @@
     }
 
     /** Returns {@code true} if the decided new rotation has not applied to configuration yet. */
-    private boolean isRotationChanging() {
+    boolean isRotationChanging() {
         return mDisplayRotation.getRotation() != getWindowConfiguration().getRotation();
     }
 
@@ -2015,7 +2033,6 @@
                 ProtoLog.v(WM_DEBUG_ORIENTATION, "Set mOrientationChanging of %s", w);
                 w.setOrientationChanging(true);
             }
-            w.mReportOrientationChanged = true;
         }, true /* traverseTopToBottom */);
 
         for (int i = mWmService.mRotationWatchers.size() - 1; i >= 0; i--) {
@@ -2205,9 +2222,9 @@
 
         final float density = mDisplayMetrics.density;
         outConfig.screenWidthDp = (int) (mDisplayPolicy.getConfigDisplayWidth(dw, dh, rotation,
-                uiMode, displayCutout) / density);
+                uiMode, displayCutout) / density + 0.5f);
         outConfig.screenHeightDp = (int) (mDisplayPolicy.getConfigDisplayHeight(dw, dh, rotation,
-                uiMode, displayCutout) / density);
+                uiMode, displayCutout) / density + 0.5f);
         outConfig.compatScreenWidthDp = (int) (outConfig.screenWidthDp / mCompatibleScreenScale);
         outConfig.compatScreenHeightDp = (int) (outConfig.screenHeightDp / mCompatibleScreenScale);
 
@@ -2390,7 +2407,8 @@
         sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw, uiMode);
         sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh, uiMode);
         sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw, uiMode);
-        outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
+        outConfig.smallestScreenWidthDp =
+                (int) (displayInfo.smallestNominalAppWidth / density + 0.5f);
         outConfig.screenLayout = sl;
     }
 
@@ -2412,8 +2430,8 @@
             longSize = shortSize;
             shortSize = tmp;
         }
-        longSize = (int)(longSize/density);
-        shortSize = (int)(shortSize/density);
+        longSize = (int) (longSize / density + 0.5f);
+        shortSize = (int) (shortSize / density + 0.5f);
         return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
     }
 
@@ -2758,6 +2776,7 @@
     private void updateBaseDisplayMetricsIfNeeded() {
         // Get real display metrics without overrides from WM.
         mWmService.mDisplayManagerInternal.getNonOverrideDisplayInfo(mDisplayId, mDisplayInfo);
+        final int currentRotation = getRotation();
         final int orientation = mDisplayInfo.rotation;
         final boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
         final int newWidth = rotated ? mDisplayInfo.logicalHeight : mDisplayInfo.logicalWidth;
@@ -2818,7 +2837,8 @@
             reconfigureDisplayLocked();
 
             if (physicalDisplayChanged) {
-                mDisplaySwitchTransitionLauncher.onDisplayUpdated();
+                mDisplaySwitchTransitionLauncher.onDisplayUpdated(currentRotation, getRotation(),
+                        getDisplayAreaInfo());
             }
         }
     }
@@ -2922,9 +2942,10 @@
             // Set some sort of reasonable bounds on the size of the display that we will try
             // to emulate.
             final int minSize = 200;
-            final int maxScale = 2;
-            width = Math.min(Math.max(width, minSize), mInitialDisplayWidth * maxScale);
-            height = Math.min(Math.max(height, minSize), mInitialDisplayHeight * maxScale);
+            final int maxScale = 3;
+            final int maxSize = Math.max(mInitialDisplayWidth, mInitialDisplayHeight) * maxScale;
+            width = Math.min(Math.max(width, minSize), maxSize);
+            height = Math.min(Math.max(height, minSize), maxSize);
         }
 
         Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
@@ -4385,8 +4406,8 @@
             boolean imeLayeringTargetMayUseIme =
                     LayoutParams.mayUseInputMethod(mImeLayeringTarget.mAttrs.flags)
                     || mImeLayeringTarget.mAttrs.type == TYPE_APPLICATION_STARTING;
-            if (imeLayeringTargetMayUseIme && mImeInputTarget != null
-                    && mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord()) {
+            if (imeLayeringTargetMayUseIme && (mImeInputTarget == null
+                    || mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord())) {
                 // Do not change parent if the window hasn't requested IME.
                 return null;
             }
@@ -4858,9 +4879,7 @@
                 return true;
             }
 
-            // TODO(b/165794880): Freeform task organizer doesn't support drag-resize yet. Remove
-            // the special case when it does.
-            if (task.isOrganized() && task.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
+            if (task.isOrganized()) {
                 return true;
             }
 
@@ -6091,7 +6110,8 @@
                 rootTask.ensureActivitiesVisible(starting, configChanges, preserveWindows,
                         notifyClients);
             });
-            if (mTransitionController.isCollecting()
+            if (mTransitionController.useShellTransitionsRotation()
+                    && mTransitionController.isCollecting()
                     && mWallpaperController.getWallpaperTarget() != null) {
                 // Also update wallpapers so that their requestedVisibility immediately reflects
                 // the changes to activity visibility.
@@ -6268,7 +6288,6 @@
     /**
      * Sets if Display APIs should be sandboxed to the activity window bounds.
      */
-    @VisibleForTesting
     void setSandboxDisplayApis(boolean sandboxDisplayApis) {
         mSandboxDisplayApis = sandboxDisplayApis;
     }
@@ -6456,7 +6475,7 @@
                     // Different tasks won't be in one activity transition animation.
                     return;
                 }
-                if (task.isAppTransitioning()) {
+                if (task.getActivity(ActivityRecord::isInTransition) != null) {
                     return;
                     // Continue to update orientation because the transition of the top rotated
                     // launching activity is done.
diff --git a/services/core/java/com/android/server/wm/DisplayFrames.java b/services/core/java/com/android/server/wm/DisplayFrames.java
index fd06313..7ca38b8 100644
--- a/services/core/java/com/android/server/wm/DisplayFrames.java
+++ b/services/core/java/com/android/server/wm/DisplayFrames.java
@@ -99,19 +99,28 @@
         state.setRoundedCorners(roundedCorners);
         state.setPrivacyIndicatorBounds(indicatorBounds);
         state.getDisplayCutoutSafe(safe);
-        if (!cutout.isEmpty()) {
+        if (safe.left > unrestricted.left) {
             state.getSource(ITYPE_LEFT_DISPLAY_CUTOUT).setFrame(
                     unrestricted.left, unrestricted.top, safe.left, unrestricted.bottom);
+        } else {
+            state.removeSource(ITYPE_LEFT_DISPLAY_CUTOUT);
+        }
+        if (safe.top > unrestricted.top) {
             state.getSource(ITYPE_TOP_DISPLAY_CUTOUT).setFrame(
                     unrestricted.left, unrestricted.top, unrestricted.right, safe.top);
+        } else {
+            state.removeSource(ITYPE_TOP_DISPLAY_CUTOUT);
+        }
+        if (safe.right < unrestricted.right) {
             state.getSource(ITYPE_RIGHT_DISPLAY_CUTOUT).setFrame(
                     safe.right, unrestricted.top, unrestricted.right, unrestricted.bottom);
+        } else {
+            state.removeSource(ITYPE_RIGHT_DISPLAY_CUTOUT);
+        }
+        if (safe.bottom < unrestricted.bottom) {
             state.getSource(ITYPE_BOTTOM_DISPLAY_CUTOUT).setFrame(
                     unrestricted.left, safe.bottom, unrestricted.right, unrestricted.bottom);
         } else {
-            state.removeSource(ITYPE_LEFT_DISPLAY_CUTOUT);
-            state.removeSource(ITYPE_TOP_DISPLAY_CUTOUT);
-            state.removeSource(ITYPE_RIGHT_DISPLAY_CUTOUT);
             state.removeSource(ITYPE_BOTTOM_DISPLAY_CUTOUT);
         }
         return true;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 7e91989a..cff8b93 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -61,6 +61,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.TRANSIT_WAKE;
 import static android.view.WindowManagerGlobal.ADD_OKAY;
 import static android.view.WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED;
 import static android.view.WindowManagerPolicyConstants.ALT_BAR_BOTTOM;
@@ -119,6 +120,7 @@
 import android.view.DisplayInfo;
 import android.view.Gravity;
 import android.view.InsetsFlags;
+import android.view.InsetsFrameProvider;
 import android.view.InsetsSource;
 import android.view.InsetsState;
 import android.view.InsetsState.InternalInsetsType;
@@ -778,7 +780,23 @@
     }
 
     public void setAwake(boolean awake) {
+        if (awake == mAwake) {
+            return;
+        }
         mAwake = awake;
+        synchronized (mService.mGlobalLock) {
+            if (!mDisplayContent.isDefaultDisplay) {
+                return;
+            }
+            if (mAwake && mDisplayContent.mTransitionController.isShellTransitionsEnabled()
+                    && !mDisplayContent.mTransitionController.isCollecting()) {
+                // Start a transition for waking. This is needed for showWhenLocked activities.
+                mDisplayContent.mTransitionController.requestTransitionIfNeeded(TRANSIT_WAKE,
+                        0 /* flags */, null /* trigger */, mDisplayContent);
+            }
+            mService.mAtmService.mKeyguardController.updateDeferWakeTransition(
+                    mAwake /* waiting */);
+        }
     }
 
     public boolean isAwake() {
@@ -1062,17 +1080,18 @@
                 return WindowManagerGlobal.ADD_INVALID_TYPE;
         }
 
-        if (attrs.providesInsetsTypes != null) {
+        if (attrs.providedInsets != null) {
             // Recents component is allowed to add inset types.
             if (!mService.mAtmService.isCallerRecents(callingUid)) {
                 mContext.enforcePermission(
                         android.Manifest.permission.STATUS_BAR_SERVICE, callingPid, callingUid,
                         "DisplayPolicy");
             }
-            enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providesInsetsTypes);
+            enforceSingleInsetsTypeCorrespondingToWindowType(attrs.providedInsets);
 
-            for (@InternalInsetsType int insetType : attrs.providesInsetsTypes) {
-                switch (insetType) {
+            for (InsetsFrameProvider provider : attrs.providedInsets) {
+                @InternalInsetsType int insetsType = provider.type;
+                switch (insetsType) {
                     case ITYPE_STATUS_BAR:
                         if ((mStatusBar != null && mStatusBar.isAlive())
                                 || (mStatusBarAlt != null && mStatusBarAlt.isAlive())) {
@@ -1138,12 +1157,17 @@
                 mDisplayContent.setInsetProvider(ITYPE_NAVIGATION_BAR, win,
                         (displayFrames, windowContainer, inOutFrame) -> {
                             if (!mNavButtonForcedVisible) {
-                                final Insets[] providedInternalInsets = win.getLayoutingAttrs(
-                                        displayFrames.mRotation).providedInternalInsets;
-                                if (providedInternalInsets != null
-                                        && providedInternalInsets.length > ITYPE_NAVIGATION_BAR
-                                        && providedInternalInsets[ITYPE_NAVIGATION_BAR] != null) {
-                                    inOutFrame.inset(providedInternalInsets[ITYPE_NAVIGATION_BAR]);
+                                final LayoutParams lp =
+                                        win.mAttrs.forRotation(displayFrames.mRotation);
+                                if (lp.providedInsets != null) {
+                                    for (InsetsFrameProvider provider : lp.providedInsets) {
+                                        if (provider.type != ITYPE_NAVIGATION_BAR) {
+                                            continue;
+                                        }
+                                        calculateInsetsFrame(displayFrames, win, inOutFrame,
+                                                provider.source, provider.insetsSize
+                                        );
+                                    }
                                 }
                                 inOutFrame.inset(win.mGivenContentInsets);
                             }
@@ -1187,21 +1211,10 @@
                 if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                 break;
             default:
-                if (attrs.providesInsetsTypes != null) {
-                    for (@InternalInsetsType int insetsType : attrs.providesInsetsTypes) {
-                        final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider =
-                                win.getAttrs().providedInternalImeInsets != null
-                                        ? (displayFrames, windowContainer, inOutFrame) -> {
-                                    final Insets[] providedInternalImeInsets =
-                                            win.getLayoutingAttrs(displayFrames.mRotation)
-                                                    .providedInternalImeInsets;
-                                    if (providedInternalImeInsets != null
-                                            && providedInternalImeInsets.length > insetsType
-                                            && providedInternalImeInsets[insetsType] != null) {
-                                        inOutFrame.inset(providedInternalImeInsets[insetsType]);
-                                    }
-                                } : null;
-                        switch (insetsType) {
+                if (attrs.providedInsets != null) {
+                    for (int i = attrs.providedInsets.length - 1; i >= 0; i--) {
+                        final InsetsFrameProvider provider = attrs.providedInsets[i];
+                        switch (provider.type) {
                             case ITYPE_STATUS_BAR:
                                 mStatusBarAlt = win;
                                 mStatusBarAltPosition = getAltBarPosition(attrs);
@@ -1219,41 +1232,32 @@
                                 mExtraNavBarAltPosition = getAltBarPosition(attrs);
                                 break;
                         }
-                        mDisplayContent.setInsetProvider(insetsType, win,
-                                win.getAttrs().providedInternalInsets != null ? (displayFrames,
-                                        windowContainer, inOutFrame) -> {
-                                    final Insets[] providedInternalInsets = win.getLayoutingAttrs(
-                                            displayFrames.mRotation).providedInternalInsets;
-                                    if (providedInternalInsets != null
-                                            && providedInternalInsets.length > insetsType
-                                            && providedInternalInsets[insetsType] != null) {
-                                        inOutFrame.inset(providedInternalInsets[insetsType]);
-                                    }
-                                    inOutFrame.inset(win.mGivenContentInsets);
-                                } : null, imeFrameProvider);
-                        if (mNavigationBar == null && (insetsType == ITYPE_NAVIGATION_BAR
-                                || insetsType == ITYPE_EXTRA_NAVIGATION_BAR)) {
-                            mDisplayContent.setInsetProvider(ITYPE_LEFT_GESTURES, win,
-                                    (displayFrames, windowState, inOutFrame) -> {
-                                final int leftSafeInset =
-                                        Math.max(displayFrames.mDisplayCutoutSafe.left,0);
-                                        inOutFrame.left = 0;
-                                        inOutFrame.top = 0;
-                                        inOutFrame.bottom = displayFrames.mDisplayHeight;
-                                        inOutFrame.right =
-                                                leftSafeInset + mLeftGestureInset;
-                                    });
-                            mDisplayContent.setInsetProvider(ITYPE_RIGHT_GESTURES, win,
-                                    (displayFrames, windowState, inOutFrame) -> {
-                                        final int rightSafeInset =
-                                                Math.min(displayFrames.mDisplayCutoutSafe.right,
-                                                        displayFrames.mUnrestricted.right);
-                                        inOutFrame.left = rightSafeInset - mRightGestureInset;
-                                        inOutFrame.top = 0;
-                                        inOutFrame.bottom = displayFrames.mDisplayHeight;
-                                        inOutFrame.right = displayFrames.mDisplayWidth;
-                                    });
-                        }
+                        // The index of the provider and corresponding insets types cannot change at
+                        // runtime as ensured in WMS. Make use of the index in the provider directly
+                        // to access the latest provided size at runtime.
+                        final int index = i;
+                        final TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider =
+                                provider.insetsSize != null
+                                        ? (displayFrames, windowContainer, inOutFrame) -> {
+                                            inOutFrame.inset(win.mGivenContentInsets);
+                                            final InsetsFrameProvider ifp =
+                                                    win.mAttrs.forRotation(displayFrames.mRotation)
+                                                            .providedInsets[index];
+                                            calculateInsetsFrame(displayFrames, windowContainer,
+                                                    inOutFrame, ifp.source, ifp.insetsSize);
+                                        } : null;
+                        final TriConsumer<DisplayFrames, WindowContainer, Rect> imeFrameProvider =
+                                provider.imeInsetsSize != null
+                                        ? (displayFrames, windowContainer, inOutFrame) -> {
+                                            inOutFrame.inset(win.mGivenContentInsets);
+                                            final InsetsFrameProvider ifp =
+                                                    win.mAttrs.forRotation(displayFrames.mRotation)
+                                                            .providedInsets[index];
+                                            calculateInsetsFrame(displayFrames, windowContainer,
+                                                    inOutFrame, ifp.source, ifp.imeInsetsSize);
+                                        } : null;
+                        mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
+                                imeFrameProvider);
                         mInsetsSourceWindowsExceptIme.add(win);
                     }
                 }
@@ -1261,6 +1265,31 @@
         }
     }
 
+    private void calculateInsetsFrame(DisplayFrames df, WindowContainer container, Rect inOutFrame,
+            int source, Insets insetsSize) {
+        if (source == InsetsFrameProvider.SOURCE_DISPLAY) {
+            inOutFrame.set(df.mUnrestricted);
+        } else if (source == InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS) {
+            inOutFrame.set(container.getBounds());
+        }
+        if (insetsSize == null) {
+            return;
+        }
+        // Only one side of the provider shall be applied. Check in the order of left - top -
+        // right - bottom, only the first non-zero value will be applied.
+        if (insetsSize.left != 0) {
+            inOutFrame.right = inOutFrame.left + insetsSize.left;
+        } else if (insetsSize.top != 0) {
+            inOutFrame.bottom = inOutFrame.top + insetsSize.top;
+        } else if (insetsSize.right != 0) {
+            inOutFrame.left = inOutFrame.right - insetsSize.right;
+        } else if (insetsSize.bottom != 0) {
+            inOutFrame.top = inOutFrame.bottom - insetsSize.bottom;
+        } else {
+            inOutFrame.setEmpty();
+        }
+    }
+
     @WindowManagerPolicy.AltBarPosition
     private int getAltBarPosition(WindowManager.LayoutParams params) {
         switch (params.gravity) {
@@ -1299,10 +1328,11 @@
         };
     }
 
-    private static void enforceSingleInsetsTypeCorrespondingToWindowType(int[] insetsTypes) {
+    private static void enforceSingleInsetsTypeCorrespondingToWindowType(
+            InsetsFrameProvider[] providers) {
         int count = 0;
-        for (int insetsType : insetsTypes) {
-            switch (insetsType) {
+        for (InsetsFrameProvider provider : providers) {
+            switch (provider.type) {
                 case ITYPE_NAVIGATION_BAR:
                 case ITYPE_STATUS_BAR:
                 case ITYPE_CLIMATE_BAR:
@@ -1350,7 +1380,7 @@
     private int getStatusBarHeight(DisplayFrames displayFrames) {
         int statusBarHeight;
         if (mStatusBar != null) {
-            statusBarHeight = mStatusBar.getLayoutingAttrs(displayFrames.mRotation).height;
+            statusBarHeight = mStatusBar.mAttrs.forRotation(displayFrames.mRotation).height;
         } else {
             statusBarHeight = 0;
         }
@@ -1504,13 +1534,14 @@
      */
     void simulateLayoutDisplay(DisplayFrames displayFrames) {
         final InsetsStateController controller = mDisplayContent.getInsetsStateController();
+        sTmpClientFrames.attachedFrame = null;
         for (int i = mInsetsSourceWindowsExceptIme.size() - 1; i >= 0; i--) {
             final WindowState win = mInsetsSourceWindowsExceptIme.valueAt(i);
-            mWindowLayout.computeFrames(win.getLayoutingAttrs(displayFrames.mRotation),
+            mWindowLayout.computeFrames(win.mAttrs.forRotation(displayFrames.mRotation),
                     displayFrames.mInsetsState, displayFrames.mDisplayCutoutSafe,
                     displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
-                    UNSPECIFIED_LENGTH, win.getRequestedVisibilities(),
-                    null /* attachedWindowFrame */, win.mGlobalScale, sTmpClientFrames);
+                    UNSPECIFIED_LENGTH, win.getRequestedVisibilities(), win.mGlobalScale,
+                    sTmpClientFrames);
             final SparseArray<InsetsSource> sources = win.getProvidedInsetsSources();
             final InsetsState state = displayFrames.mInsetsState;
             for (int index = sources.size() - 1; index >= 0; index--) {
@@ -1522,13 +1553,14 @@
     }
 
     void updateInsetsSourceFramesExceptIme(DisplayFrames displayFrames) {
+        sTmpClientFrames.attachedFrame = null;
         for (int i = mInsetsSourceWindowsExceptIme.size() - 1; i >= 0; i--) {
             final WindowState win = mInsetsSourceWindowsExceptIme.valueAt(i);
-            mWindowLayout.computeFrames(win.getLayoutingAttrs(displayFrames.mRotation),
+            mWindowLayout.computeFrames(win.mAttrs.forRotation(displayFrames.mRotation),
                     displayFrames.mInsetsState, displayFrames.mDisplayCutoutSafe,
                     displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
-                    UNSPECIFIED_LENGTH, win.getRequestedVisibilities(),
-                    null /* attachedWindowFrame */, win.mGlobalScale, sTmpClientFrames);
+                    UNSPECIFIED_LENGTH, win.getRequestedVisibilities(), win.mGlobalScale,
+                    sTmpClientFrames);
             win.updateSourceFrame(sTmpClientFrames.frame);
         }
     }
@@ -1557,8 +1589,8 @@
         // We invoke this to get the proper DisplayFrames.
         displayFrames = win.getDisplayFrames(displayFrames);
 
-        final WindowManager.LayoutParams attrs = win.getLayoutingAttrs(displayFrames.mRotation);
-        final Rect attachedWindowFrame = attached != null ? attached.getFrame() : null;
+        final WindowManager.LayoutParams attrs = win.mAttrs.forRotation(displayFrames.mRotation);
+        sTmpClientFrames.attachedFrame = attached != null ? attached.getFrame() : null;
 
         // If this window has different LayoutParams for rotations, we cannot trust its requested
         // size. Because it might have not sent its requested size for the new rotation.
@@ -1568,8 +1600,7 @@
 
         mWindowLayout.computeFrames(attrs, win.getInsetsState(), displayFrames.mDisplayCutoutSafe,
                 win.getBounds(), win.getWindowingMode(), requestedWidth, requestedHeight,
-                win.getRequestedVisibilities(), attachedWindowFrame, win.mGlobalScale,
-                sTmpClientFrames);
+                win.getRequestedVisibilities(), win.mGlobalScale, sTmpClientFrames);
 
         win.setFrames(sTmpClientFrames, win.mRequestedWidth, win.mRequestedHeight);
     }
@@ -1961,25 +1992,20 @@
                 && lp.paramsForRotation[rotation] != null) {
             lp = lp.paramsForRotation[rotation];
         }
-        final Insets providedInternalInsets;
-        if (lp.providedInternalInsets != null
-                && lp.providedInternalInsets.length > ITYPE_NAVIGATION_BAR
-                && lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] != null) {
-            providedInternalInsets = lp.providedInternalInsets[ITYPE_NAVIGATION_BAR];
-        } else {
-            providedInternalInsets = Insets.NONE;
-        }
-        if (position == NAV_BAR_LEFT) {
-            if (lp.width > providedInternalInsets.right) {
-                return lp.width - providedInternalInsets.right;
-            } else {
-                return 0;
+        Insets providedInsetsSize = null;
+        if (lp.providedInsets != null) {
+            for (InsetsFrameProvider provider : lp.providedInsets) {
+                if (provider.type != ITYPE_NAVIGATION_BAR) {
+                    continue;
+                }
+                providedInsetsSize = provider.insetsSize;
             }
-        } else if (position == NAV_BAR_RIGHT) {
-            if (lp.width > providedInternalInsets.left) {
-                return lp.width - providedInternalInsets.left;
-            } else {
-                return 0;
+        }
+        if (providedInsetsSize != null) {
+            if (position == NAV_BAR_LEFT) {
+                return providedInsetsSize.left;
+            } else if (position == NAV_BAR_RIGHT) {
+                return providedInsetsSize.right;
             }
         }
         return lp.width;
@@ -2025,19 +2051,21 @@
         if (mNavigationBar == null) {
             return 0;
         }
-        LayoutParams lp = mNavigationBar.getLayoutingAttrs(rotation);
-        final Insets providedInternalInsets;
-        if (lp.providedInternalInsets != null
-                && lp.providedInternalInsets.length > ITYPE_NAVIGATION_BAR
-                && lp.providedInternalInsets[ITYPE_NAVIGATION_BAR] != null) {
-            providedInternalInsets = lp.providedInternalInsets[ITYPE_NAVIGATION_BAR];
-        } else {
-            providedInternalInsets = Insets.NONE;
+        LayoutParams lp = mNavigationBar.mAttrs.forRotation(rotation);
+        Insets providedInsetsSize = null;
+        if (lp.providedInsets != null) {
+            for (InsetsFrameProvider provider : lp.providedInsets) {
+                if (provider.type != ITYPE_NAVIGATION_BAR) {
+                    continue;
+                }
+                providedInsetsSize = provider.insetsSize;
+                if (providedInsetsSize != null) {
+                    return providedInsetsSize.bottom;
+                }
+                break;
+            }
         }
-        if (lp.height < providedInternalInsets.top) {
-            return 0;
-        }
-        return lp.height - providedInternalInsets.top;
+        return lp.height;
     }
 
     /**
@@ -2055,7 +2083,7 @@
         if (mNavigationBar == null) {
             return 0;
         }
-        return mNavigationBar.getLayoutingAttrs(rotation).height;
+        return mNavigationBar.mAttrs.forRotation(rotation).height;
     }
 
     /**
@@ -2184,7 +2212,7 @@
     @NavigationBarPosition
     int navigationBarPosition(int displayRotation) {
         if (mNavigationBar != null) {
-            final int gravity = mNavigationBar.getLayoutingAttrs(displayRotation).gravity;
+            final int gravity = mNavigationBar.mAttrs.forRotation(displayRotation).gravity;
             switch (gravity) {
                 case Gravity.LEFT:
                     return NAV_BAR_LEFT;
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 03e1429..b9d8319 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -51,14 +51,12 @@
 import android.database.ContentObserver;
 import android.hardware.power.Boost;
 import android.os.Handler;
-import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
-import android.view.IDisplayWindowRotationCallback;
 import android.view.IWindowManager;
 import android.view.Surface;
 import android.window.TransitionRequestInfo;
@@ -67,7 +65,6 @@
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
-import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
 import com.android.server.UiThread;
 import com.android.server.policy.WindowManagerPolicy;
@@ -211,31 +208,6 @@
     private boolean mDemoHdmiRotationLock;
     private boolean mDemoRotationLock;
 
-    private static final int REMOTE_ROTATION_TIMEOUT_MS = 800;
-
-    private boolean mIsWaitingForRemoteRotation = false;
-
-    private final Runnable mDisplayRotationHandlerTimeout =
-            new Runnable() {
-                @Override
-                public void run() {
-                    continueRotation(mRotation, null /* transaction */);
-                }
-            };
-
-    private final IDisplayWindowRotationCallback mRemoteRotationCallback =
-            new IDisplayWindowRotationCallback.Stub() {
-                @Override
-                public void continueRotateDisplay(int targetRotation,
-                        WindowContainerTransaction t) {
-                    synchronized (mService.getWindowManagerLock()) {
-                        mService.mH.sendMessage(PooledLambda.obtainMessage(
-                                DisplayRotation::continueRotation, DisplayRotation.this,
-                                targetRotation, t));
-                    }
-                }
-            };
-
     DisplayRotation(WindowManagerService service, DisplayContent displayContent) {
         this(service, displayContent, displayContent.getDisplayPolicy(),
                 service.mDisplayWindowSettings, service.mContext, service.getWindowManagerLock());
@@ -511,6 +483,7 @@
             final TransitionRequestInfo.DisplayChange change = wasCollecting ? null
                     : new TransitionRequestInfo.DisplayChange(mDisplayContent.getDisplayId(),
                             oldRotation, mRotation);
+
             mDisplayContent.requestChangeTransitionIfNeeded(
                     ActivityInfo.CONFIG_WINDOW_CONFIGURATION, change);
             if (wasCollecting) {
@@ -554,61 +527,39 @@
         return null;
     }
 
-    /**
-     * A Remote rotation is when we are waiting for some registered (remote)
-     * {@link IDisplayWindowRotationController} to calculate and return some hierarchy operations
-     *  to perform in sync with the rotation.
-     */
-    boolean isWaitingForRemoteRotation() {
-        return mIsWaitingForRemoteRotation;
-    }
-
     private void startRemoteRotation(int fromRotation, int toRotation) {
-        if (mService.mDisplayRotationController == null) {
-            return;
-        }
-        mIsWaitingForRemoteRotation = true;
-        try {
-            mService.mDisplayRotationController.onRotateDisplay(mDisplayContent.getDisplayId(),
-                    fromRotation, toRotation, mRemoteRotationCallback);
-            mService.mH.removeCallbacks(mDisplayRotationHandlerTimeout);
-            mService.mH.postDelayed(mDisplayRotationHandlerTimeout, REMOTE_ROTATION_TIMEOUT_MS);
-        } catch (RemoteException e) {
-            mIsWaitingForRemoteRotation = false;
-            return;
-        }
+        mDisplayContent.mRemoteDisplayChangeController.performRemoteDisplayChange(
+                fromRotation, toRotation, null /* newDisplayAreaInfo */,
+                (transaction) -> continueRotation(toRotation, transaction)
+        );
     }
 
     private void continueRotation(int targetRotation, WindowContainerTransaction t) {
-        synchronized (mService.mGlobalLock) {
-            if (targetRotation != mRotation || !mIsWaitingForRemoteRotation) {
-                // Drop it, this is either coming from an outdated remote rotation; or, we've
-                // already moved on.
-                return;
-            }
-            mService.mH.removeCallbacks(mDisplayRotationHandlerTimeout);
-            mIsWaitingForRemoteRotation = false;
+        if (targetRotation != mRotation) {
+            // Drop it, this is either coming from an outdated remote rotation; or, we've
+            // already moved on.
+            return;
+        }
 
-            if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
-                if (!mDisplayContent.mTransitionController.isCollecting()) {
-                    throw new IllegalStateException("Trying to rotate outside a transition");
-                }
-                mDisplayContent.mTransitionController.collect(mDisplayContent);
-                // Go through all tasks and collect them before the rotation
-                // TODO(shell-transitions): move collect() to onConfigurationChange once wallpaper
-                //       handling is synchronized.
-                mDisplayContent.mTransitionController.collectForDisplayChange(mDisplayContent,
-                        null /* use collecting transition */);
+        if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
+            if (!mDisplayContent.mTransitionController.isCollecting()) {
+                throw new IllegalStateException("Trying to rotate outside a transition");
             }
-            mService.mAtmService.deferWindowLayout();
-            try {
-                mDisplayContent.sendNewConfiguration();
-                if (t != null) {
-                    mService.mAtmService.mWindowOrganizerController.applyTransaction(t);
-                }
-            } finally {
-                mService.mAtmService.continueWindowLayout();
+            mDisplayContent.mTransitionController.collect(mDisplayContent);
+            // Go through all tasks and collect them before the rotation
+            // TODO(shell-transitions): move collect() to onConfigurationChange once wallpaper
+            //       handling is synchronized.
+            mDisplayContent.mTransitionController.collectForDisplayChange(mDisplayContent,
+                    null /* use collecting transition */);
+        }
+        mService.mAtmService.deferWindowLayout();
+        try {
+            mDisplayContent.sendNewConfiguration();
+            if (t != null) {
+                mService.mAtmService.mWindowOrganizerController.applyTransaction(t);
             }
+        } finally {
+            mService.mAtmService.continueWindowLayout();
         }
     }
 
@@ -669,7 +620,8 @@
         // We only enable seamless rotation if the top window has requested it and is in the
         // fullscreen opaque state. Seamless rotation requires freezing various Surface states and
         // won't work well with animations, so we disable it in the animation case for now.
-        if (w.getAttrs().rotationAnimation != ROTATION_ANIMATION_SEAMLESS || w.isAnimatingLw()) {
+        if (w.getAttrs().rotationAnimation != ROTATION_ANIMATION_SEAMLESS || w.inMultiWindowMode()
+                || w.isAnimatingLw()) {
             return false;
         }
 
@@ -1571,8 +1523,8 @@
         }
 
         @Override
-        public boolean isKeyguardLocked() {
-            return mService.isKeyguardLocked();
+        public boolean isKeyguardShowingAndNotOccluded() {
+            return mService.isKeyguardShowingAndNotOccluded();
         }
 
         @Override
@@ -1684,7 +1636,9 @@
                 final WindowContainer<?> source = dc.getLastOrientationSource();
                 if (source != null) {
                     mLastOrientationSource = source.toString();
-                    mSourceOrientation = source.mOrientation;
+                    final WindowState w = source.asWindowState();
+                    mSourceOrientation =
+                            w != null ? w.mAttrs.screenOrientation : source.mOrientation;
                 } else {
                     mLastOrientationSource = null;
                     mSourceOrientation = SCREEN_ORIENTATION_UNSET;
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 65b1f02..f2d4d54 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -31,6 +31,8 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.MY_PID;
+import static com.android.server.wm.WindowManagerService.MY_UID;
 
 import android.animation.Animator;
 import android.animation.PropertyValuesHolder;
@@ -45,7 +47,6 @@
 import android.os.Build;
 import android.os.IBinder;
 import android.os.InputConfig;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -208,8 +209,6 @@
 
         // Send drag end broadcast if drag start has been sent.
         if (mDragInProgress) {
-            final int myPid = Process.myPid();
-
             if (DEBUG_DRAG) {
                 Slog.d(TAG_WM, "broadcasting DRAG_ENDED");
             }
@@ -237,7 +236,7 @@
                 }
                 // if the current window is in the same process,
                 // the dispatch has already recycled the event
-                if (myPid != ws.mSession.mPid) {
+                if (MY_PID != ws.mSession.mPid) {
                     event.recycle();
                 }
             }
@@ -321,7 +320,6 @@
                 mData.fixUris(mSourceUserId);
             }
         }
-        final int myPid = Process.myPid();
         final IBinder clientToken = touchedWin.mClient.asBinder();
         final DragEvent event = obtainDragEvent(DragEvent.ACTION_DROP, x, y,
                 mData, targetInterceptsGlobalDrag(touchedWin),
@@ -337,7 +335,7 @@
             endDragLocked();
             return false;
         } finally {
-            if (myPid != touchedWin.mSession.mPid) {
+            if (MY_PID != touchedWin.mSession.mPid) {
                 event.recycle();
             }
         }
@@ -365,8 +363,8 @@
             mDragWindowHandle.token = mClientChannel.getToken();
             mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
             mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-            mDragWindowHandle.ownerPid = Process.myPid();
-            mDragWindowHandle.ownerUid = Process.myUid();
+            mDragWindowHandle.ownerPid = MY_PID;
+            mDragWindowHandle.ownerUid = MY_UID;
             mDragWindowHandle.scaleFactor = 1.0f;
 
             // Keep the default behavior of this window to be focusable, which allows the system
@@ -478,7 +476,7 @@
                 Slog.w(TAG_WM, "Unable to drag-start window " + newWin);
             } finally {
                 // if the callee was local, the dispatch has already recycled the event
-                if (Process.myPid() != newWin.mSession.mPid) {
+                if (MY_PID != newWin.mSession.mPid) {
                     event.recycle();
                 }
             }
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index 59be3e0..39622c1 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -23,7 +23,6 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.InputConfig;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.view.InputApplicationHandle;
@@ -72,8 +71,8 @@
         mWindowHandle.token = mClientChannel.getToken();
         mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
         mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-        mWindowHandle.ownerPid = Process.myPid();
-        mWindowHandle.ownerUid = Process.myUid();
+        mWindowHandle.ownerPid = WindowManagerService.MY_PID;
+        mWindowHandle.ownerUid = WindowManagerService.MY_UID;
         mWindowHandle.scaleFactor = 1.0f;
         mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.TRUSTED_OVERLAY;
 
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 7e06b88..8389dbd 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -288,10 +288,7 @@
         SurfaceControl touchableRegionCrop = null;
         final Task task = w.getTask();
         if (task != null) {
-            // TODO(b/165794636): Remove the special case for freeform window once drag resizing is
-            // handled by WM shell.
-            if (task.isOrganized() && task.getWindowingMode() != WINDOWING_MODE_FULLSCREEN
-                        && !task.inFreeformWindowingMode()) {
+            if (task.isOrganized() && task.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
                 // If the window is in a TaskManaged by a TaskOrganizer then most cropping will
                 // be applied using the SurfaceControl hierarchy from the Organizer. This means
                 // we need to make sure that these changes in crop are reflected in the input
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 9e0d7b5..db2ee2d 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -55,6 +55,7 @@
 import android.view.InsetsAnimationControlImpl;
 import android.view.InsetsAnimationControlRunner;
 import android.view.InsetsController;
+import android.view.InsetsFrameProvider;
 import android.view.InsetsSource;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
@@ -322,14 +323,14 @@
         }
 
         // If not one of the types above, check whether an internal inset mapping is specified.
-        if (attrs.providesInsetsTypes != null) {
-            for (@InternalInsetsType int insetsType : attrs.providesInsetsTypes) {
-                switch (insetsType) {
+        if (attrs.providedInsets != null) {
+            for (InsetsFrameProvider provider : attrs.providedInsets) {
+                switch (provider.type) {
                     case ITYPE_STATUS_BAR:
                     case ITYPE_NAVIGATION_BAR:
                     case ITYPE_CLIMATE_BAR:
                     case ITYPE_EXTRA_NAVIGATION_BAR:
-                        return insetsType;
+                        return provider.type;
                 }
             }
         }
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 358e93d..610bf05 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -42,6 +42,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.proto.ProtoOutputStream;
+import android.view.InsetsFrameProvider;
 import android.view.InsetsSource;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
@@ -290,7 +291,22 @@
                         && windowState.mWinAnimator.getShown() && mWindowContainer.okToDisplay()) {
                     windowState.applyWithNextDraw(mSetLeashPositionConsumer);
                 } else {
-                    mSetLeashPositionConsumer.accept(mWindowContainer.getSyncTransaction());
+                    Transaction t = mWindowContainer.getSyncTransaction();
+                    if (windowState != null) {
+                        // Make the buffer, token transformation, and leash position to be updated
+                        // together when the window is drawn for new rotation. Otherwise the window
+                        // may be outside the screen by the inconsistent orientations.
+                        final AsyncRotationController rotationController =
+                                mDisplayContent.getAsyncRotationController();
+                        if (rotationController != null) {
+                            final Transaction drawT =
+                                    rotationController.getDrawTransaction(windowState.mToken);
+                            if (drawT != null) {
+                                t = drawT;
+                            }
+                        }
+                    }
+                    mSetLeashPositionConsumer.accept(t);
                 }
             }
             if (mServerVisible && !mLastSourceFrame.equals(mSource.getFrame())) {
@@ -310,17 +326,15 @@
     }
 
     private Point getWindowFrameSurfacePosition() {
-        WindowState win = mWindowContainer.asWindowState();
-        if (mControl != null) {
-            final AsyncRotationController controller =
-                    win.mDisplayContent.getAsyncRotationController();
+        final WindowState win = mWindowContainer.asWindowState();
+        if (win != null && mControl != null) {
+            final AsyncRotationController controller = mDisplayContent.getAsyncRotationController();
             if (controller != null && controller.shouldFreezeInsetsPosition(win)) {
-                // Use previous position because the fade-out animation runs in old rotation.
+                // Use previous position because the window still shows with old rotation.
                 return mControl.getSurfacePosition();
             }
         }
-        final Rect frame = mWindowContainer.asWindowState() != null
-                ? mWindowContainer.asWindowState().getFrame() : mWindowContainer.getBounds();
+        final Rect frame = win != null ? win.getFrame() : mWindowContainer.getBounds();
         final Point position = new Point();
         mWindowContainer.transformFrameToSurfacePosition(frame.left, frame.top, position);
         return position;
@@ -500,12 +514,13 @@
         if (mWindowContainer.asWindowState() == null) {
             return false;
         }
-        final int[] provides = ((WindowState) mWindowContainer).mAttrs.providesInsetsTypes;
-        if (provides == null) {
+        final InsetsFrameProvider[] providers =
+                ((WindowState) mWindowContainer).mAttrs.providedInsets;
+        if (providers == null) {
             return false;
         }
-        for (int i = 0; i < provides.length; i++) {
-            if (provides[i] == ITYPE_IME) {
+        for (int i = 0; i < providers.length; i++) {
+            if (providers[i].type == ITYPE_IME) {
                 return true;
             }
         }
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 01c9414..ca4376e 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -41,6 +41,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.wm.KeyguardControllerProto.AOD_SHOWING;
+import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_GOING_AWAY;
 import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_PER_DISPLAY;
 import static com.android.server.wm.KeyguardControllerProto.KEYGUARD_SHOWING;
 
@@ -72,6 +73,8 @@
 
     static final String KEYGUARD_SLEEP_TOKEN_TAG = "keyguard";
 
+    private static final int DEFER_WAKE_TRANSITION_TIMEOUT_MS = 5000;
+
     private final ActivityTaskSupervisor mTaskSupervisor;
     private WindowManagerService mWindowManager;
 
@@ -79,7 +82,7 @@
     private final ActivityTaskManagerService mService;
     private RootWindowContainer mRootWindowContainer;
     private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer;
-
+    private boolean mWaitingForWakeTransition;
 
     KeyguardController(ActivityTaskManagerService service,
             ActivityTaskSupervisor taskSupervisor) {
@@ -171,6 +174,9 @@
         // Do not reset keyguardChanged status if this is aodChanged.
         final boolean keyguardChanged = (keyguardShowing != state.mKeyguardShowing)
                 || (state.mKeyguardGoingAway && keyguardShowing && !aodChanged);
+        if (aodChanged && !aodShowing) {
+            updateDeferWakeTransition(false /* waiting */);
+        }
         if (!keyguardChanged && !aodChanged) {
             setWakeTransitionReady();
             return;
@@ -199,10 +205,6 @@
 
         state.mKeyguardShowing = keyguardShowing;
         state.mAodShowing = aodShowing;
-        if (aodChanged) {
-            // Ensure the new state takes effect.
-            mWindowManager.mWindowPlacerLocked.performSurfacePlacement();
-        }
 
         if (keyguardChanged) {
             // Irrelevant to AOD.
@@ -220,6 +222,10 @@
         mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
         InputMethodManagerInternal.get().updateImeWindowStatus(false /* disableImeIcon */);
         setWakeTransitionReady();
+        if (aodChanged) {
+            // Ensure the new state takes effect.
+            mWindowManager.mWindowPlacerLocked.performSurfacePlacement();
+        }
     }
 
     private void setWakeTransitionReady() {
@@ -526,6 +532,33 @@
         }
     }
 
+    private final Runnable mResetWaitTransition = () -> {
+        synchronized (mWindowManager.mGlobalLock) {
+            updateDeferWakeTransition(false /* waiting */);
+        }
+    };
+
+    void updateDeferWakeTransition(boolean waiting) {
+        if (waiting == mWaitingForWakeTransition) {
+            return;
+        }
+        if (!mWindowManager.mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+            return;
+        }
+        // if aod is showing, defer the wake transition until aod state changed.
+        if (waiting && isAodShowing(DEFAULT_DISPLAY)) {
+            mWaitingForWakeTransition = true;
+            mWindowManager.mAtmService.getTransitionController().deferTransitionReady();
+            mWindowManager.mH.postDelayed(mResetWaitTransition, DEFER_WAKE_TRANSITION_TIMEOUT_MS);
+        } else if (!waiting) {
+            // dismiss the deferring if the aod state change or cancel awake.
+            mWaitingForWakeTransition = false;
+            mWindowManager.mAtmService.getTransitionController().continueTransitionReady();
+            mWindowManager.mH.removeCallbacks(mResetWaitTransition);
+        }
+    }
+
+
     /** Represents Keyguard state per individual display. */
     private static class KeyguardDisplayState {
         private final int mDisplayId;
@@ -594,6 +627,7 @@
                 } else if (top.canShowWhenLocked()) {
                     mTopOccludesActivity = top;
                 }
+                top.mDismissKeyguard = false;
 
                 // Only the top activity may control occluded, as we can't occlude the Keyguard
                 // if the top app doesn't want to occlude it.
@@ -671,6 +705,7 @@
             proto.write(KeyguardPerDisplayProto.KEYGUARD_SHOWING, mKeyguardShowing);
             proto.write(KeyguardPerDisplayProto.AOD_SHOWING, mAodShowing);
             proto.write(KeyguardPerDisplayProto.KEYGUARD_OCCLUDED, mOccluded);
+            proto.write(KeyguardPerDisplayProto.KEYGUARD_GOING_AWAY, mKeyguardGoingAway);
             proto.end(token);
         }
     }
@@ -691,6 +726,7 @@
         final long token = proto.start(fieldId);
         proto.write(AOD_SHOWING, default_state.mAodShowing);
         proto.write(KEYGUARD_SHOWING, default_state.mKeyguardShowing);
+        proto.write(KEYGUARD_GOING_AWAY, default_state.mKeyguardGoingAway);
         writeDisplayStatesToProto(proto, KEYGUARD_PER_DISPLAY);
         proto.end(token);
     }
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 40df02c..b5eff41 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -25,7 +25,6 @@
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.os.InputConfig;
-import android.os.Process;
 import android.view.GestureDetector;
 import android.view.InputChannel;
 import android.view.InputEvent;
@@ -72,7 +71,8 @@
     private final LetterboxSurface mFullWindowSurface = new LetterboxSurface("fullWindow");
     private final LetterboxSurface[] mSurfaces = { mLeft, mTop, mRight, mBottom };
     // Reachability gestures.
-    private final IntConsumer mDoubleTapCallback;
+    private final IntConsumer mDoubleTapCallbackX;
+    private final IntConsumer mDoubleTapCallbackY;
 
     /**
      * Constructs a Letterbox.
@@ -86,7 +86,8 @@
             Supplier<Boolean> hasWallpaperBackgroundSupplier,
             Supplier<Integer> blurRadiusSupplier,
             Supplier<Float> darkScrimAlphaSupplier,
-            IntConsumer doubleTapCallback) {
+            IntConsumer doubleTapCallbackX,
+            IntConsumer doubleTapCallbackY) {
         mSurfaceControlFactory = surfaceControlFactory;
         mTransactionFactory = transactionFactory;
         mAreCornersRounded = areCornersRounded;
@@ -94,7 +95,8 @@
         mHasWallpaperBackgroundSupplier = hasWallpaperBackgroundSupplier;
         mBlurRadiusSupplier = blurRadiusSupplier;
         mDarkScrimAlphaSupplier = darkScrimAlphaSupplier;
-        mDoubleTapCallback = doubleTapCallback;
+        mDoubleTapCallbackX = doubleTapCallbackX;
+        mDoubleTapCallbackY = doubleTapCallbackY;
     }
 
     /**
@@ -264,7 +266,8 @@
         @Override
         public boolean onDoubleTapEvent(MotionEvent e) {
             if (e.getAction() == MotionEvent.ACTION_UP) {
-                mDoubleTapCallback.accept((int) e.getX());
+                mDoubleTapCallbackX.accept((int) e.getX());
+                mDoubleTapCallbackY.accept((int) e.getY());
                 return true;
             }
             return false;
@@ -293,8 +296,8 @@
             mWindowHandle.token = mToken;
             mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
             mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-            mWindowHandle.ownerPid = Process.myPid();
-            mWindowHandle.ownerUid = Process.myUid();
+            mWindowHandle.ownerPid = WindowManagerService.MY_PID;
+            mWindowHandle.ownerUid = WindowManagerService.MY_UID;
             mWindowHandle.scaleFactor = 1.0f;
             mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.SLIPPERY;
         }
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index d02ad99..91b2fb6 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -22,7 +22,6 @@
 import android.graphics.Color;
 
 import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -56,25 +55,48 @@
     static final int LETTERBOX_BACKGROUND_WALLPAPER = 3;
 
     /**
-     * Enum for Letterbox reachability position types.
+     * Enum for Letterbox horizontal reachability position types.
      *
      * <p>Order from left to right is important since it's used in {@link
      * #movePositionForReachabilityToNextRightStop} and {@link
      * #movePositionForReachabilityToNextLeftStop}.
      */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({LETTERBOX_REACHABILITY_POSITION_LEFT, LETTERBOX_REACHABILITY_POSITION_CENTER,
-            LETTERBOX_REACHABILITY_POSITION_RIGHT})
-    @interface LetterboxReachabilityPosition {};
+    @IntDef({LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT,
+            LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER,
+            LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT})
+    @interface LetterboxHorizontalReachabilityPosition {};
 
     /** Letterboxed app window is aligned to the left side. */
-    static final int LETTERBOX_REACHABILITY_POSITION_LEFT = 0;
+    static final int LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT = 0;
 
     /** Letterboxed app window is positioned in the horizontal center. */
-    static final int LETTERBOX_REACHABILITY_POSITION_CENTER = 1;
+    static final int LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER = 1;
 
     /** Letterboxed app window is aligned to the right side. */
-    static final int LETTERBOX_REACHABILITY_POSITION_RIGHT = 2;
+    static final int LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT = 2;
+
+    /**
+     * Enum for Letterbox vertical reachability position types.
+     *
+     * <p>Order from top to bottom is important since it's used in {@link
+     * #movePositionForReachabilityToNextBottomStop} and {@link
+     * #movePositionForReachabilityToNextTopStop}.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP,
+            LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER,
+            LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM})
+    @interface LetterboxVerticalReachabilityPosition {};
+
+    /** Letterboxed app window is aligned to the left side. */
+    static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP = 0;
+
+    /** Letterboxed app window is positioned in the vertical center. */
+    static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER = 1;
+
+    /** Letterboxed app window is aligned to the right side. */
+    static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM = 2;
 
     final Context mContext;
 
@@ -82,6 +104,9 @@
     // MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
     private float mFixedOrientationLetterboxAspectRatio;
 
+    // Default min aspect ratio for unresizable apps that are eligible for the size compat mode.
+    private float mDefaultMinAspectRatioForUnresizableApps;
+
     // Corners radius for activities presented in the letterbox mode, values < 0 will be ignored.
     private int mLetterboxActivityCornersRadius;
 
@@ -107,29 +132,57 @@
     // side of the screen and 1.0 to the right side.
     private float mLetterboxHorizontalPositionMultiplier;
 
-    // Default horizontal position the letterboxed app window when reachability is enabled and
-    // an app is fullscreen in landscape device orientatio.
-    // It is used as a starting point for mLetterboxPositionForReachability.
-    @LetterboxReachabilityPosition
-    private int mDefaultPositionForReachability;
+    // Vertical position of a center of the letterboxed app window. 0 corresponds to the top
+    // side of the screen and 1.0 to the bottom side.
+    private float mLetterboxVerticalPositionMultiplier;
 
-    // Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape
-    // device orientation.
-    private boolean mIsReachabilityEnabled;
+    // Default horizontal position the letterboxed app window when horizontal reachability is
+    // enabled and an app is fullscreen in landscape device orientation.
+    // It is used as a starting point for mLetterboxPositionForHorizontalReachability.
+    @LetterboxHorizontalReachabilityPosition
+    private int mDefaultPositionForHorizontalReachability;
+
+    // Default vertical position the letterboxed app window when vertical reachability is enabled
+    // and an app is fullscreen in portrait device orientation.
+    // It is used as a starting point for mLetterboxPositionForVerticalReachability.
+    @LetterboxVerticalReachabilityPosition
+    private int mDefaultPositionForVerticalReachability;
+
+    // Whether horizontal reachability repositioning is allowed for letterboxed fullscreen apps in
+    // landscape device orientation.
+    private boolean mIsHorizontalReachabilityEnabled;
+
+    // Whether vertical reachability repositioning is allowed for letterboxed fullscreen apps in
+    // portrait device orientation.
+    private boolean mIsVerticalReachabilityEnabled;
+
 
     // Horizontal position of a center of the letterboxed app window which is global to prevent
     // "jumps" when switching between letterboxed apps. It's updated to reposition the app window
     // in response to a double tap gesture (see LetterboxUiController#handleDoubleTap). Used in
     // LetterboxUiController#getHorizontalPositionMultiplier which is called from
-    // ActivityRecord#updateResolvedBoundsHorizontalPosition.
+    // ActivityRecord#updateResolvedBoundsPosition.
     // TODO(b/199426138): Global reachability setting causes a jump when resuming an app from
     // Overview after changing position in another app.
-    @LetterboxReachabilityPosition
-    private volatile int mLetterboxPositionForReachability;
+    @LetterboxHorizontalReachabilityPosition
+    private volatile int mLetterboxPositionForHorizontalReachability;
+
+    // Vertical position of a center of the letterboxed app window which is global to prevent
+    // "jumps" when switching between letterboxed apps. It's updated to reposition the app window
+    // in response to a double tap gesture (see LetterboxUiController#handleDoubleTap). Used in
+    // LetterboxUiController#getVerticalPositionMultiplier which is called from
+    // ActivityRecord#updateResolvedBoundsPosition.
+    // TODO(b/199426138): Global reachability setting causes a jump when resuming an app from
+    // Overview after changing position in another app.
+    @LetterboxVerticalReachabilityPosition
+    private volatile int mLetterboxPositionForVerticalReachability;
 
     // Whether education is allowed for letterboxed fullscreen apps.
     private boolean mIsEducationEnabled;
 
+    // Whether using split screen aspect ratio as a default aspect ratio for unresizable apps.
+    private boolean mIsSplitScreenAspectRatioForUnresizableAppsEnabled;
+
     LetterboxConfiguration(Context systemUiContext) {
         mContext = systemUiContext;
         mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
@@ -143,12 +196,24 @@
                 R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
         mLetterboxHorizontalPositionMultiplier = mContext.getResources().getFloat(
                 R.dimen.config_letterboxHorizontalPositionMultiplier);
-        mIsReachabilityEnabled = mContext.getResources().getBoolean(
-                R.bool.config_letterboxIsReachabilityEnabled);
-        mDefaultPositionForReachability = readLetterboxReachabilityPositionFromConfig(mContext);
-        mLetterboxPositionForReachability = mDefaultPositionForReachability;
+        mLetterboxVerticalPositionMultiplier = mContext.getResources().getFloat(
+                R.dimen.config_letterboxVerticalPositionMultiplier);
+        mIsHorizontalReachabilityEnabled = mContext.getResources().getBoolean(
+                R.bool.config_letterboxIsHorizontalReachabilityEnabled);
+        mIsVerticalReachabilityEnabled = mContext.getResources().getBoolean(
+                R.bool.config_letterboxIsVerticalReachabilityEnabled);
+        mDefaultPositionForHorizontalReachability =
+                readLetterboxHorizontalReachabilityPositionFromConfig(mContext);
+        mDefaultPositionForVerticalReachability =
+                readLetterboxVerticalReachabilityPositionFromConfig(mContext);
+        mLetterboxPositionForHorizontalReachability = mDefaultPositionForHorizontalReachability;
+        mLetterboxPositionForVerticalReachability = mDefaultPositionForVerticalReachability;
         mIsEducationEnabled = mContext.getResources().getBoolean(
                 R.bool.config_letterboxIsEducationEnabled);
+        setDefaultMinAspectRatioForUnresizableApps(mContext.getResources().getFloat(
+                R.dimen.config_letterboxDefaultMinAspectRatioForUnresizableApps));
+        mIsSplitScreenAspectRatioForUnresizableAppsEnabled = mContext.getResources().getBoolean(
+                R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled);
     }
 
     /**
@@ -157,7 +222,6 @@
      * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored and
      * the framework implementation will be used to determine the aspect ratio.
      */
-    @VisibleForTesting
     void setFixedOrientationLetterboxAspectRatio(float aspectRatio) {
         mFixedOrientationLetterboxAspectRatio = aspectRatio;
     }
@@ -166,7 +230,6 @@
      * Resets the aspect ratio of letterbox for fixed orientation to {@link
      * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}.
      */
-    @VisibleForTesting
     void resetFixedOrientationLetterboxAspectRatio() {
         mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
                 com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio);
@@ -180,6 +243,47 @@
     }
 
     /**
+     * Resets the min aspect ratio for unresizable apps that are eligible for size compat mode.
+     */
+    void resetDefaultMinAspectRatioForUnresizableApps() {
+        setDefaultMinAspectRatioForUnresizableApps(mContext.getResources().getFloat(
+                R.dimen.config_letterboxDefaultMinAspectRatioForUnresizableApps));
+    }
+
+    /**
+     * Gets the min aspect ratio for unresizable apps that are eligible for size compat mode.
+     */
+    float getDefaultMinAspectRatioForUnresizableApps() {
+        return mDefaultMinAspectRatioForUnresizableApps;
+    }
+
+    /**
+     * Overrides the min aspect ratio for unresizable apps that are eligible for size compat mode.
+     */
+    void setDefaultMinAspectRatioForUnresizableApps(float aspectRatio) {
+        mDefaultMinAspectRatioForUnresizableApps = aspectRatio;
+    }
+
+    /**
+     * Overrides corners raidus for activities presented in the letterbox mode. If given value < 0,
+     * both it and a value of {@link
+     * com.android.internal.R.integer.config_letterboxActivityCornersRadius} will be ignored and
+     * corners of the activity won't be rounded.
+     */
+    void setLetterboxActivityCornersRadius(int cornersRadius) {
+        mLetterboxActivityCornersRadius = cornersRadius;
+    }
+
+    /**
+     * Resets corners raidus for activities presented in the letterbox mode to {@link
+     * com.android.internal.R.integer.config_letterboxActivityCornersRadius}.
+     */
+    void resetLetterboxActivityCornersRadius() {
+        mLetterboxActivityCornersRadius = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_letterboxActivityCornersRadius);
+    }
+
+    /**
      * Whether corners of letterboxed activities are rounded.
      */
     boolean isLetterboxActivityCornersRounded() {
@@ -210,6 +314,34 @@
         return Color.valueOf(mContext.getResources().getColor(colorId));
     }
 
+
+    /**
+     * Sets color of letterbox background which is used when {@link
+     * #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
+     * fallback for other backfround types.
+     */
+    void setLetterboxBackgroundColor(Color color) {
+        mLetterboxBackgroundColorOverride = color;
+    }
+
+    /**
+     * Sets color ID of letterbox background which is used when {@link
+     * #getLetterboxBackgroundType()} is {@link #LETTERBOX_BACKGROUND_SOLID_COLOR} or as
+     * fallback for other backfround types.
+     */
+    void setLetterboxBackgroundColorResourceId(int colorId) {
+        mLetterboxBackgroundColorResourceIdOverride = colorId;
+    }
+
+    /**
+     * Resets color of letterbox background to {@link
+     * com.android.internal.R.color.config_letterboxBackgroundColor}.
+     */
+    void resetLetterboxBackgroundColor() {
+        mLetterboxBackgroundColorOverride = null;
+        mLetterboxBackgroundColorResourceIdOverride = null;
+    }
+
     /**
      * Gets {@link LetterboxBackgroundType} specified in {@link
      * com.android.internal.R.integer.config_letterboxBackgroundType} or over via ADB command.
@@ -219,6 +351,19 @@
         return mLetterboxBackgroundType;
     }
 
+    /** Sets letterbox background type. */
+    void setLetterboxBackgroundType(@LetterboxBackgroundType int backgroundType) {
+        mLetterboxBackgroundType = backgroundType;
+    }
+
+    /**
+     * Resets cletterbox background type to {@link
+     * com.android.internal.R.integer.config_letterboxBackgroundType}.
+     */
+    void resetLetterboxBackgroundType() {
+        mLetterboxBackgroundType = readLetterboxBackgroundTypeFromConfig(mContext);
+    }
+
     /** Returns a string representing the given {@link LetterboxBackgroundType}. */
     static String letterboxBackgroundTypeToString(
             @LetterboxBackgroundType int backgroundType) {
@@ -248,6 +393,27 @@
     }
 
     /**
+     * Overrides alpha of a black scrim shown over wallpaper for {@link
+     * #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link mLetterboxBackgroundType}.
+     *
+     * <p>If given value is < 0 or >= 1, both it and a value of {@link
+     * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha} are ignored
+     * and 0.0 (transparent) is instead.
+     */
+    void setLetterboxBackgroundWallpaperDarkScrimAlpha(float alpha) {
+        mLetterboxBackgroundWallpaperDarkScrimAlpha = alpha;
+    }
+
+    /**
+     * Resets alpha of a black scrim shown over wallpaper letterbox background to {@link
+     * com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha}.
+     */
+    void resetLetterboxBackgroundWallpaperDarkScrimAlpha() {
+        mLetterboxBackgroundWallpaperDarkScrimAlpha = mContext.getResources().getFloat(
+                com.android.internal.R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
+    }
+
+    /**
      * Gets alpha of a black scrim shown over wallpaper letterbox background.
      */
     float getLetterboxBackgroundWallpaperDarkScrimAlpha() {
@@ -255,6 +421,28 @@
     }
 
     /**
+     * Overrides blur radius for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in
+     * {@link mLetterboxBackgroundType}.
+     *
+     * <p> If given value <= 0, both it and a value of {@link
+     * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius} are ignored
+     * and 0 is used instead.
+     */
+    void setLetterboxBackgroundWallpaperBlurRadius(int radius) {
+        mLetterboxBackgroundWallpaperBlurRadius = radius;
+    }
+
+    /**
+     * Resets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
+     * mLetterboxBackgroundType} to {@link
+     * com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius}.
+     */
+    void resetLetterboxBackgroundWallpaperBlurRadius() {
+        mLetterboxBackgroundWallpaperBlurRadius = mContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.config_letterboxBackgroundWallpaperBlurRadius);
+    }
+
+    /**
      * Gets blur raidus for {@link #LETTERBOX_BACKGROUND_WALLPAPER} option in {@link
      * mLetterboxBackgroundType}.
      */
@@ -275,72 +463,187 @@
                         ? 0.5f : mLetterboxHorizontalPositionMultiplier;
     }
 
+    /*
+     * Gets vertical position of a center of the letterboxed app window specified
+     * in {@link com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier}
+     * or via an ADB command. 0 corresponds to the top side of the screen and 1 to the
+     * bottom side.
+     */
+    float getLetterboxVerticalPositionMultiplier() {
+        return (mLetterboxVerticalPositionMultiplier < 0.0f
+                || mLetterboxVerticalPositionMultiplier > 1.0f)
+                        // Default to central position if invalid value is provided.
+                        ? 0.5f : mLetterboxVerticalPositionMultiplier;
+    }
+
     /**
      * Overrides horizontal position of a center of the letterboxed app window. If given value < 0
      * or > 1, then it and a value of {@link
      * com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier} are ignored and
      * central position (0.5) is used.
      */
-    @VisibleForTesting
     void setLetterboxHorizontalPositionMultiplier(float multiplier) {
         mLetterboxHorizontalPositionMultiplier = multiplier;
     }
 
     /**
+     * Overrides vertical position of a center of the letterboxed app window. If given value < 0
+     * or > 1, then it and a value of {@link
+     * com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier} are ignored and
+     * central position (0.5) is used.
+     */
+    void setLetterboxVerticalPositionMultiplier(float multiplier) {
+        mLetterboxVerticalPositionMultiplier = multiplier;
+    }
+
+    /**
      * Resets horizontal position of a center of the letterboxed app window to {@link
      * com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}.
      */
-    @VisibleForTesting
     void resetLetterboxHorizontalPositionMultiplier() {
         mLetterboxHorizontalPositionMultiplier = mContext.getResources().getFloat(
                 com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier);
     }
 
-    /*
-     * Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape
-     * device orientation.
+    /**
+     * Resets vertical position of a center of the letterboxed app window to {@link
+     * com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier}.
      */
-    boolean getIsReachabilityEnabled() {
-        return mIsReachabilityEnabled;
+    void resetLetterboxVerticalPositionMultiplier() {
+        mLetterboxVerticalPositionMultiplier = mContext.getResources().getFloat(
+                com.android.internal.R.dimen.config_letterboxVerticalPositionMultiplier);
     }
 
-    /**
-     * Overrides whether reachability repositioning is allowed for letterboxed fullscreen apps in
+    /*
+     * Whether horizontal reachability repositioning is allowed for letterboxed fullscreen apps in
      * landscape device orientation.
      */
-    @VisibleForTesting
-    void setIsReachabilityEnabled(boolean enabled) {
-        mIsReachabilityEnabled = enabled;
-    }
-
-    /**
-     * Resets whether reachability repositioning is allowed for letterboxed fullscreen apps in
-     * landscape device orientation to {@link R.bool.config_letterboxIsReachabilityEnabled}.
-     */
-    @VisibleForTesting
-    void resetIsReachabilityEnabled() {
-        mIsReachabilityEnabled = mContext.getResources().getBoolean(
-                R.bool.config_letterboxIsReachabilityEnabled);
+    boolean getIsHorizontalReachabilityEnabled() {
+        return mIsHorizontalReachabilityEnabled;
     }
 
     /*
-     * Gets default horizontal position of the letterboxed app window when reachability is enabled.
-     * Specified in {@link R.integer.config_letterboxDefaultPositionForReachability} or via an ADB
-     * command.
+     * Whether vertical reachability repositioning is allowed for letterboxed fullscreen apps in
+     * portrait device orientation.
      */
-    @LetterboxReachabilityPosition
-    int getDefaultPositionForReachability() {
-        return mDefaultPositionForReachability;
+    boolean getIsVerticalReachabilityEnabled() {
+        return mIsVerticalReachabilityEnabled;
     }
 
-    @LetterboxReachabilityPosition
-    private static int readLetterboxReachabilityPositionFromConfig(Context context) {
+    /**
+     * Overrides whether horizontal reachability repositioning is allowed for letterboxed fullscreen
+     * apps in landscape device orientation.
+     */
+    void setIsHorizontalReachabilityEnabled(boolean enabled) {
+        mIsHorizontalReachabilityEnabled = enabled;
+    }
+
+    /**
+     * Overrides whether vertical reachability repositioning is allowed for letterboxed fullscreen
+     * apps in portrait device orientation.
+     */
+    void setIsVerticalReachabilityEnabled(boolean enabled) {
+        mIsVerticalReachabilityEnabled = enabled;
+    }
+
+    /**
+     * Resets whether horizontal reachability repositioning is allowed for letterboxed fullscreen
+     * apps in landscape device orientation to
+     * {@link R.bool.config_letterboxIsHorizontalReachabilityEnabled}.
+     */
+    void resetIsHorizontalReachabilityEnabled() {
+        mIsHorizontalReachabilityEnabled = mContext.getResources().getBoolean(
+                R.bool.config_letterboxIsHorizontalReachabilityEnabled);
+    }
+
+    /**
+     * Resets whether vertical reachability repositioning is allowed for letterboxed fullscreen apps
+     * in portrait device orientation to
+     * {@link R.bool.config_letterboxIsVerticalReachabilityEnabled}.
+     */
+    void resetIsVerticalReachabilityEnabled() {
+        mIsVerticalReachabilityEnabled = mContext.getResources().getBoolean(
+                R.bool.config_letterboxIsVerticalReachabilityEnabled);
+    }
+
+    /*
+     * Gets default horizontal position of the letterboxed app window when horizontal reachability
+     * is enabled.
+     *
+     * <p> Specified in {@link R.integer.config_letterboxDefaultPositionForHorizontalReachability}
+     *  or via an ADB command.
+     */
+    @LetterboxHorizontalReachabilityPosition
+    int getDefaultPositionForHorizontalReachability() {
+        return mDefaultPositionForHorizontalReachability;
+    }
+
+    /*
+     * Gets default vertical position of the letterboxed app window when vertical reachability is
+     * enabled.
+     *
+     * <p> Specified in {@link R.integer.config_letterboxDefaultPositionForVerticalReachability} or
+     *  via an ADB command.
+     */
+    @LetterboxVerticalReachabilityPosition
+    int getDefaultPositionForVerticalReachability() {
+        return mDefaultPositionForVerticalReachability;
+    }
+
+    /**
+     * Overrides default horizontal position of the letterboxed app window when horizontal
+     * reachability is enabled.
+     */
+    void setDefaultPositionForHorizontalReachability(
+            @LetterboxHorizontalReachabilityPosition int position) {
+        mDefaultPositionForHorizontalReachability = position;
+    }
+
+    /**
+     * Overrides default vertical position of the letterboxed app window when vertical
+     * reachability is enabled.
+     */
+    void setDefaultPositionForVerticalReachability(
+            @LetterboxVerticalReachabilityPosition int position) {
+        mDefaultPositionForVerticalReachability = position;
+    }
+
+    /**
+     * Resets default horizontal position of the letterboxed app window when horizontal reachability
+     * is enabled to {@link R.integer.config_letterboxDefaultPositionForHorizontalReachability}.
+     */
+    void resetDefaultPositionForHorizontalReachability() {
+        mDefaultPositionForHorizontalReachability =
+                readLetterboxHorizontalReachabilityPositionFromConfig(mContext);
+    }
+
+    /**
+     * Resets default vertical position of the letterboxed app window when vertical reachability
+     * is enabled to {@link R.integer.config_letterboxDefaultPositionForVerticalReachability}.
+     */
+    void resetDefaultPositionForVerticalReachability() {
+        mDefaultPositionForVerticalReachability =
+                readLetterboxVerticalReachabilityPositionFromConfig(mContext);
+    }
+
+    @LetterboxHorizontalReachabilityPosition
+    private static int readLetterboxHorizontalReachabilityPositionFromConfig(Context context) {
         int position = context.getResources().getInteger(
-                R.integer.config_letterboxDefaultPositionForReachability);
-        return position == LETTERBOX_REACHABILITY_POSITION_LEFT
-                    || position == LETTERBOX_REACHABILITY_POSITION_CENTER
-                    || position == LETTERBOX_REACHABILITY_POSITION_RIGHT
-                    ? position : LETTERBOX_REACHABILITY_POSITION_CENTER;
+                R.integer.config_letterboxDefaultPositionForHorizontalReachability);
+        return position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT
+                    || position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
+                    || position == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT
+                    ? position : LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
+    }
+
+    @LetterboxVerticalReachabilityPosition
+    private static int readLetterboxVerticalReachabilityPositionFromConfig(Context context) {
+        int position = context.getResources().getInteger(
+                R.integer.config_letterboxDefaultPositionForVerticalReachability);
+        return position == LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP
+                || position == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER
+                || position == LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM
+                ? position : LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
     }
 
     /*
@@ -350,48 +653,126 @@
      * <p>The position multiplier is changed after each double tap in the letterbox area.
      */
     float getHorizontalMultiplierForReachability() {
-        switch (mLetterboxPositionForReachability) {
-            case LETTERBOX_REACHABILITY_POSITION_LEFT:
+        switch (mLetterboxPositionForHorizontalReachability) {
+            case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT:
                 return 0.0f;
-            case LETTERBOX_REACHABILITY_POSITION_CENTER:
+            case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER:
                 return 0.5f;
-            case LETTERBOX_REACHABILITY_POSITION_RIGHT:
+            case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT:
                 return 1.0f;
             default:
                 throw new AssertionError(
-                    "Unexpected letterbox position type: " + mLetterboxPositionForReachability);
+                    "Unexpected letterbox position type: "
+                            + mLetterboxPositionForHorizontalReachability);
+        }
+    }
+    /*
+     * Gets vertical position of a center of the letterboxed app window when reachability
+     * is enabled specified. 0 corresponds to the top side of the screen and 1 to the bottom side.
+     *
+     * <p>The position multiplier is changed after each double tap in the letterbox area.
+     */
+    float getVerticalMultiplierForReachability() {
+        switch (mLetterboxPositionForVerticalReachability) {
+            case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP:
+                return 0.0f;
+            case LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER:
+                return 0.5f;
+            case LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM:
+                return 1.0f;
+            default:
+                throw new AssertionError(
+                        "Unexpected letterbox position type: "
+                                + mLetterboxPositionForVerticalReachability);
         }
     }
 
-    /** Returns a string representing the given {@link LetterboxReachabilityPosition}. */
-    static String letterboxReachabilityPositionToString(
-            @LetterboxReachabilityPosition int position) {
+    /*
+     * Gets the horizontal position of the letterboxed app window when horizontal reachability is
+     * enabled.
+     */
+    @LetterboxHorizontalReachabilityPosition
+    int getLetterboxPositionForHorizontalReachability() {
+        return mLetterboxPositionForHorizontalReachability;
+    }
+
+    /*
+     * Gets the vertical position of the letterboxed app window when vertical reachability is
+     * enabled.
+     */
+    @LetterboxVerticalReachabilityPosition
+    int getLetterboxPositionForVerticalReachability() {
+        return mLetterboxPositionForVerticalReachability;
+    }
+
+    /** Returns a string representing the given {@link LetterboxHorizontalReachabilityPosition}. */
+    static String letterboxHorizontalReachabilityPositionToString(
+            @LetterboxHorizontalReachabilityPosition int position) {
         switch (position) {
-            case LETTERBOX_REACHABILITY_POSITION_LEFT:
-                return "LETTERBOX_REACHABILITY_POSITION_LEFT";
-            case LETTERBOX_REACHABILITY_POSITION_CENTER:
-                return "LETTERBOX_REACHABILITY_POSITION_CENTER";
-            case LETTERBOX_REACHABILITY_POSITION_RIGHT:
-                return "LETTERBOX_REACHABILITY_POSITION_RIGHT";
+            case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT:
+                return "LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT";
+            case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER:
+                return "LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER";
+            case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT:
+                return "LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT";
             default:
                 throw new AssertionError(
                     "Unexpected letterbox position type: " + position);
         }
     }
 
-    /**
-     * Changes letterbox position for reachability to the next available one on the right side.
-     */
-    void movePositionForReachabilityToNextRightStop() {
-        mLetterboxPositionForReachability = Math.min(
-                mLetterboxPositionForReachability + 1, LETTERBOX_REACHABILITY_POSITION_RIGHT);
+    /** Returns a string representing the given {@link LetterboxVerticalReachabilityPosition}. */
+    static String letterboxVerticalReachabilityPositionToString(
+            @LetterboxVerticalReachabilityPosition int position) {
+        switch (position) {
+            case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP:
+                return "LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP";
+            case LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER:
+                return "LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER";
+            case LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM:
+                return "LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM";
+            default:
+                throw new AssertionError(
+                        "Unexpected letterbox position type: " + position);
+        }
     }
 
     /**
-     * Changes letterbox position for reachability to the next available one on the left side.
+     * Changes letterbox position for horizontal reachability to the next available one on the
+     * right side.
      */
-    void movePositionForReachabilityToNextLeftStop() {
-        mLetterboxPositionForReachability = Math.max(mLetterboxPositionForReachability - 1, 0);
+    void movePositionForHorizontalReachabilityToNextRightStop() {
+        mLetterboxPositionForHorizontalReachability = Math.min(
+                mLetterboxPositionForHorizontalReachability + 1,
+                LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT);
+    }
+
+    /**
+     * Changes letterbox position for horizontal reachability to the next available one on the left
+     * side.
+     */
+    void movePositionForHorizontalReachabilityToNextLeftStop() {
+        mLetterboxPositionForHorizontalReachability =
+                Math.max(mLetterboxPositionForHorizontalReachability - 1, 0);
+    }
+
+    /**
+     * Changes letterbox position for vertical reachability to the next available one on the bottom
+     * side.
+     */
+    void movePositionForVerticalReachabilityToNextBottomStop() {
+        mLetterboxPositionForVerticalReachability = Math.min(
+                mLetterboxPositionForVerticalReachability + 1,
+                LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM);
+    }
+
+    /**
+     * Changes letterbox position for vertical reachability to the next available one on the top
+     * side.
+     */
+    void movePositionForVerticalReachabilityToNextTopStop() {
+        mLetterboxPositionForVerticalReachability =
+                Math.max(mLetterboxPositionForVerticalReachability - 1, 0);
     }
 
     /**
@@ -404,8 +785,41 @@
     /**
      * Overrides whether education is allowed for letterboxed fullscreen apps.
      */
-    @VisibleForTesting
     void setIsEducationEnabled(boolean enabled) {
         mIsEducationEnabled = enabled;
     }
+
+    /**
+     * Resets whether education is allowed for letterboxed fullscreen apps to
+     * {@link R.bool.config_letterboxIsEducationEnabled}.
+     */
+    void resetIsEducationEnabled() {
+        mIsEducationEnabled = mContext.getResources().getBoolean(
+                R.bool.config_letterboxIsEducationEnabled);
+    }
+
+    /**
+     * Whether using split screen aspect ratio as a default aspect ratio for unresizable apps.
+     */
+    boolean getIsSplitScreenAspectRatioForUnresizableAppsEnabled() {
+        return mIsSplitScreenAspectRatioForUnresizableAppsEnabled;
+    }
+
+    /**
+     * Overrides whether using split screen aspect ratio as a default aspect ratio for unresizable
+     * apps.
+     */
+    void setIsSplitScreenAspectRatioForUnresizableAppsEnabled(boolean enabled) {
+        mIsSplitScreenAspectRatioForUnresizableAppsEnabled = enabled;
+    }
+
+    /**
+     * Resets whether using split screen aspect ratio as a default aspect ratio for unresizable
+     * apps {@link R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled}.
+     */
+    void resetIsSplitScreenAspectRatioForUnresizableAppsEnabled() {
+        mIsSplitScreenAspectRatioForUnresizableAppsEnabled = mContext.getResources().getBoolean(
+                R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled);
+    }
+
 }
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index bb15d76..d652767 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -21,6 +21,20 @@
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__LEFT;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__RIGHT;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__TOP;
+import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__BOTTOM_TO_CENTER;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_BOTTOM;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_LEFT;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_RIGHT;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_TOP;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__LEFT_TO_CENTER;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__RIGHT_TO_CENTER;
+import static com.android.internal.util.FrameworkStatsLog.LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__TOP_TO_CENTER;
 import static com.android.server.wm.ActivityRecord.computeAspectRatio;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -28,6 +42,13 @@
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
+import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
 import static com.android.server.wm.LetterboxConfiguration.letterboxBackgroundTypeToString;
 
 import android.annotation.Nullable;
@@ -163,7 +184,8 @@
                         this::hasWallpaperBackgroudForLetterbox,
                         this::getLetterboxWallpaperBlurRadius,
                         this::getLetterboxWallpaperDarkScrimAlpha,
-                        this::handleDoubleTap);
+                        this::handleHorizontalDoubleTap,
+                        this::handleVerticalDoubleTap);
                 mLetterbox.attachInput(w);
             }
             mActivityRecord.getPosition(mTmpPoint);
@@ -193,18 +215,36 @@
     float getHorizontalPositionMultiplier(Configuration parentConfiguration) {
         // Don't check resolved configuration because it may not be updated yet during
         // configuration change.
-        return isReachabilityEnabled(parentConfiguration)
+        return isHorizontalReachabilityEnabled(parentConfiguration)
                 // Using the last global dynamic position to avoid "jumps" when moving
                 // between apps or activities.
                 ? mLetterboxConfiguration.getHorizontalMultiplierForReachability()
                 : mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier();
     }
 
-    float getFixedOrientationLetterboxAspectRatio(Configuration parentConfiguration) {
-        // Don't check resolved windowing mode because it may not be updated yet during
+    float getVerticalPositionMultiplier(Configuration parentConfiguration) {
+        // Don't check resolved configuration because it may not be updated yet during
         // configuration change.
-        if (!isReachabilityEnabled(parentConfiguration)) {
-            return mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
+        return isVerticalReachabilityEnabled(parentConfiguration)
+                // Using the last global dynamic position to avoid "jumps" when moving
+                // between apps or activities.
+                ? mLetterboxConfiguration.getVerticalMultiplierForReachability()
+                : mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier();
+    }
+
+    float getFixedOrientationLetterboxAspectRatio() {
+        return mActivityRecord.shouldCreateCompatDisplayInsets()
+                ? getDefaultMinAspectRatioForUnresizableApps()
+                : mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
+    }
+
+    private float getDefaultMinAspectRatioForUnresizableApps() {
+        if (!mLetterboxConfiguration.getIsSplitScreenAspectRatioForUnresizableAppsEnabled()
+                || mActivityRecord.getDisplayContent() == null) {
+            return mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
+                    > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
+                            ? mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps()
+                            : mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
         }
 
         int dividerWindowWidth =
@@ -214,10 +254,14 @@
         int dividerSize = dividerWindowWidth - dividerInsets * 2;
 
         // Getting the same aspect ratio that apps get in split screen.
-        Rect bounds = new Rect(parentConfiguration.windowConfiguration.getAppBounds());
-        bounds.inset(dividerSize, /* dy */ 0);
-        bounds.right = bounds.centerX();
-
+        Rect bounds = new Rect(mActivityRecord.getDisplayContent().getBounds());
+        if (bounds.width() >= bounds.height()) {
+            bounds.inset(/* dx */ dividerSize / 2, /* dy */ 0);
+            bounds.right = bounds.centerX();
+        } else {
+            bounds.inset(/* dx */ 0, /* dy */ dividerSize / 2);
+            bounds.bottom = bounds.centerY();
+        }
         return computeAspectRatio(bounds);
     }
 
@@ -225,8 +269,8 @@
         return mActivityRecord.mWmService.mContext.getResources();
     }
 
-    private void handleDoubleTap(int x) {
-        if (!isReachabilityEnabled() || mActivityRecord.isInTransition()) {
+    private void handleHorizontalDoubleTap(int x) {
+        if (!isHorizontalReachabilityEnabled() || mActivityRecord.isInTransition()) {
             return;
         }
 
@@ -235,12 +279,61 @@
             return;
         }
 
+        int letterboxPositionForHorizontalReachability = mLetterboxConfiguration
+                .getLetterboxPositionForHorizontalReachability();
         if (mLetterbox.getInnerFrame().left > x) {
             // Moving to the next stop on the left side of the app window: right > center > left.
-            mLetterboxConfiguration.movePositionForReachabilityToNextLeftStop();
+            mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextLeftStop();
+            int changeToLog =
+                    letterboxPositionForHorizontalReachability
+                            == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
+                                ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_LEFT
+                                : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__RIGHT_TO_CENTER;
+            logLetterboxPositionChange(changeToLog);
         } else if (mLetterbox.getInnerFrame().right < x) {
             // Moving to the next stop on the right side of the app window: left > center > right.
-            mLetterboxConfiguration.movePositionForReachabilityToNextRightStop();
+            mLetterboxConfiguration.movePositionForHorizontalReachabilityToNextRightStop();
+            int changeToLog =
+                    letterboxPositionForHorizontalReachability
+                            == LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER
+                                ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_RIGHT
+                                : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__LEFT_TO_CENTER;
+            logLetterboxPositionChange(changeToLog);
+        }
+
+        // TODO(197549949): Add animation for transition.
+        mActivityRecord.recomputeConfiguration();
+    }
+
+    private void handleVerticalDoubleTap(int y) {
+        if (!isVerticalReachabilityEnabled() || mActivityRecord.isInTransition()) {
+            return;
+        }
+
+        if (mLetterbox.getInnerFrame().top <= y && mLetterbox.getInnerFrame().bottom >= y) {
+            // Only react to clicks at the top and bottom of the letterboxed app window.
+            return;
+        }
+        int letterboxPositionForVerticalReachability = mLetterboxConfiguration
+                .getLetterboxPositionForVerticalReachability();
+        if (mLetterbox.getInnerFrame().top > y) {
+            // Moving to the next stop on the top side of the app window: bottom > center > top.
+            mLetterboxConfiguration.movePositionForVerticalReachabilityToNextTopStop();
+            int changeToLog =
+                    letterboxPositionForVerticalReachability
+                            == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER
+                                ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_TOP
+                                : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__BOTTOM_TO_CENTER;
+            logLetterboxPositionChange(changeToLog);
+        } else if (mLetterbox.getInnerFrame().bottom < y) {
+            // Moving to the next stop on the bottom side of the app window: top > center > bottom.
+            mLetterboxConfiguration.movePositionForVerticalReachabilityToNextBottomStop();
+            int changeToLog =
+                    letterboxPositionForVerticalReachability
+                            == LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER
+                                ? LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__CENTER_TO_BOTTOM
+                                : LETTERBOX_POSITION_CHANGED__POSITION_CHANGE__TOP_TO_CENTER;
+            logLetterboxPositionChange(changeToLog);
         }
 
         // TODO(197549949): Add animation for transition.
@@ -248,25 +341,47 @@
     }
 
     /**
-     * Whether reachability is enabled for an activity in the curren configuration.
+     * Whether horizontal reachability is enabled for an activity in the current configuration.
      *
      * <p>Conditions that needs to be met:
      * <ul>
      *   <li>Activity is portrait-only.
      *   <li>Fullscreen window in landscape device orientation.
-     *   <li>Reachability is enabled.
+     *   <li>Horizontal Reachability is enabled.
      * </ul>
      */
-    private boolean isReachabilityEnabled(Configuration parentConfiguration) {
-        return mLetterboxConfiguration.getIsReachabilityEnabled()
+    private boolean isHorizontalReachabilityEnabled(Configuration parentConfiguration) {
+        return mLetterboxConfiguration.getIsHorizontalReachabilityEnabled()
                 && parentConfiguration.windowConfiguration.getWindowingMode()
                         == WINDOWING_MODE_FULLSCREEN
-                && parentConfiguration.orientation == ORIENTATION_LANDSCAPE
-                && mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_PORTRAIT;
+                && (parentConfiguration.orientation == ORIENTATION_LANDSCAPE
+                && mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_PORTRAIT);
     }
 
-    private boolean isReachabilityEnabled() {
-        return isReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
+    private boolean isHorizontalReachabilityEnabled() {
+        return isHorizontalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
+    }
+
+    /**
+     * Whether vertical reachability is enabled for an activity in the current configuration.
+     *
+     * <p>Conditions that needs to be met:
+     * <ul>
+     *   <li>Activity is landscape-only.
+     *   <li>Fullscreen window in portrait device orientation.
+     *   <li>Vertical Reachability is enabled.
+     * </ul>
+     */
+    private boolean isVerticalReachabilityEnabled(Configuration parentConfiguration) {
+        return mLetterboxConfiguration.getIsVerticalReachabilityEnabled()
+                && parentConfiguration.windowConfiguration.getWindowingMode()
+                        == WINDOWING_MODE_FULLSCREEN
+                && (parentConfiguration.orientation == ORIENTATION_PORTRAIT
+                && mActivityRecord.getRequestedConfigurationOrientation() == ORIENTATION_LANDSCAPE);
+    }
+
+    private boolean isVerticalReachabilityEnabled() {
+        return isVerticalReachabilityEnabled(mActivityRecord.getParent().getConfiguration());
     }
 
     @VisibleForTesting
@@ -474,12 +589,19 @@
                     + getLetterboxWallpaperBlurRadius());
         }
 
-        pw.println(prefix + "  isReachabilityEnabled=" + isReachabilityEnabled());
+        pw.println(prefix + "  isHorizontalReachabilityEnabled="
+                + isHorizontalReachabilityEnabled());
+        pw.println(prefix + "  isVerticalReachabilityEnabled=" + isVerticalReachabilityEnabled());
         pw.println(prefix + "  letterboxHorizontalPositionMultiplier="
                 + getHorizontalPositionMultiplier(mActivityRecord.getParent().getConfiguration()));
+        pw.println(prefix + "  letterboxVerticalPositionMultiplier="
+                + getVerticalPositionMultiplier(mActivityRecord.getParent().getConfiguration()));
         pw.println(prefix + "  fixedOrientationLetterboxAspectRatio="
-                + getFixedOrientationLetterboxAspectRatio(
-                        mActivityRecord.getParent().getConfiguration()));
+                + mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio());
+        pw.println(prefix + "  defaultMinAspectRatioForUnresizableApps="
+                + mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps());
+        pw.println(prefix + "  isSplitScreenAspectRatioForUnresizableAppsEnabled="
+                + mLetterboxConfiguration.getIsSplitScreenAspectRatioForUnresizableAppsEnabled());
     }
 
     /**
@@ -496,7 +618,69 @@
         if (mainWin.isLetterboxedForDisplayCutout()) {
             return "DISPLAY_CUTOUT";
         }
+        if (mActivityRecord.isAspectRatioApplied()) {
+            return "ASPECT_RATIO";
+        }
         return "UNKNOWN_REASON";
     }
 
+    private int letterboxHorizontalReachabilityPositionToLetterboxPosition(
+            @LetterboxConfiguration.LetterboxHorizontalReachabilityPosition int position) {
+        switch (position) {
+            case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT:
+                return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__LEFT;
+            case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER:
+                return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
+            case LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT:
+                return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__RIGHT;
+            default:
+                throw new AssertionError(
+                        "Unexpected letterbox horizontal reachability position type: "
+                                + position);
+        }
+    }
+
+    private int letterboxVerticalReachabilityPositionToLetterboxPosition(
+            @LetterboxConfiguration.LetterboxVerticalReachabilityPosition int position) {
+        switch (position) {
+            case LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP:
+                return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__TOP;
+            case LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER:
+                return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
+            case LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM:
+                return APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
+            default:
+                throw new AssertionError(
+                        "Unexpected letterbox vertical reachability position type: "
+                                + position);
+        }
+    }
+
+    int getLetterboxPositionForLogging() {
+        int positionToLog = APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION;
+        if (isHorizontalReachabilityEnabled()) {
+            int letterboxPositionForHorizontalReachability = getLetterboxConfiguration()
+                    .getLetterboxPositionForHorizontalReachability();
+            positionToLog = letterboxHorizontalReachabilityPositionToLetterboxPosition(
+                            letterboxPositionForHorizontalReachability);
+        } else if (isVerticalReachabilityEnabled()) {
+            int letterboxPositionForVerticalReachability = getLetterboxConfiguration()
+                    .getLetterboxPositionForVerticalReachability();
+            positionToLog = letterboxVerticalReachabilityPositionToLetterboxPosition(
+                            letterboxPositionForVerticalReachability);
+        }
+        return positionToLog;
+    }
+
+    private LetterboxConfiguration getLetterboxConfiguration() {
+        return mLetterboxConfiguration;
+    }
+
+    /**
+     * Logs letterbox position changes via {@link ActivityMetricsLogger#logLetterboxPositionChange}.
+     */
+    private void logLetterboxPositionChange(int letterboxPositionChange) {
+        mActivityRecord.mTaskSupervisor.getActivityMetricsLogger()
+                .logLetterboxPositionChange(mActivityRecord, letterboxPositionChange);
+    }
 }
diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
index 9c1d560..d209f08 100644
--- a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
+++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
@@ -22,17 +22,21 @@
 import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY;
 
 import android.animation.ValueAnimator;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Rect;
 import android.hardware.devicestate.DeviceStateManager;
 import android.os.HandlerExecutor;
+import android.window.DisplayAreaInfo;
 import android.window.TransitionRequestInfo;
+import android.window.WindowContainerTransaction;
 
 public class PhysicalDisplaySwitchTransitionLauncher {
 
     private final DisplayContent mDisplayContent;
+    private final WindowManagerService mService;
     private final DeviceStateManager mDeviceStateManager;
-    private final Context mContext;
     private final TransitionController mTransitionController;
 
     private DeviceStateListener mDeviceStateListener;
@@ -46,13 +50,13 @@
     public PhysicalDisplaySwitchTransitionLauncher(DisplayContent displayContent,
             TransitionController transitionController) {
         mDisplayContent = displayContent;
-        mContext = mDisplayContent.mWmService.mContext;
+        mService = displayContent.mWmService;
         mTransitionController = transitionController;
 
-        mDeviceStateManager = mContext.getSystemService(DeviceStateManager.class);
+        mDeviceStateManager = mService.mContext.getSystemService(DeviceStateManager.class);
 
         if (mDeviceStateManager != null) {
-            mDeviceStateListener = new DeviceStateListener(mContext);
+            mDeviceStateListener = new DeviceStateListener(mService.mContext);
             mDeviceStateManager
                     .registerCallback(new HandlerExecutor(mDisplayContent.mWmService.mH),
                             mDeviceStateListener);
@@ -74,7 +78,7 @@
         if (!mDisplayContent.getLastHasContent()) return;
 
         boolean shouldRequestUnfoldTransition = !mIsFolded
-                && mContext.getResources().getBoolean(config_unfoldTransitionEnabled)
+                && mService.mContext.getResources().getBoolean(config_unfoldTransitionEnabled)
                 && ValueAnimator.areAnimatorsEnabled();
 
         if (!shouldRequestUnfoldTransition) {
@@ -102,13 +106,44 @@
         }
     }
 
-    public void onDisplayUpdated() {
-        if (mTransition != null) {
-            mTransition.setAllReady();
-            mTransition = null;
+    /**
+     * Called when physical display is getting updated, this could happen e.g. on foldable
+     * devices when the physical underlying display is replaced.
+     *
+     * @param fromRotation rotation before the display change
+     * @param toRotation rotation after the display change
+     * @param newDisplayAreaInfo display area info after the display change
+     */
+    public void onDisplayUpdated(int fromRotation, int toRotation,
+            @NonNull DisplayAreaInfo newDisplayAreaInfo) {
+        if (mTransition == null) return;
+
+        final boolean started = mDisplayContent.mRemoteDisplayChangeController
+                .performRemoteDisplayChange(fromRotation, toRotation, newDisplayAreaInfo,
+                        this::continueDisplayUpdate);
+
+        if (!started) {
+            markTransitionAsReady();
         }
     }
 
+    private void continueDisplayUpdate(@Nullable WindowContainerTransaction transaction) {
+        if (mTransition == null) return;
+
+        if (transaction != null) {
+            mService.mAtmService.mWindowOrganizerController.applyTransaction(transaction);
+        }
+
+        markTransitionAsReady();
+    }
+
+    private void markTransitionAsReady() {
+        if (mTransition == null) return;
+
+        mTransition.setAllReady();
+        mTransition = null;
+    }
+
     class DeviceStateListener extends DeviceStateManager.FoldStateListener {
 
         DeviceStateListener(Context context) {
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index eca201d..f840171 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -203,9 +203,7 @@
         final LaunchingState launchingState =
                 mTaskSupervisor.getActivityMetricsLogger().notifyActivityLaunching(mTargetIntent);
 
-        if (mCaller != null) {
-            mCaller.setRunningRecentsAnimation(true);
-        }
+        setProcessAnimating(true);
 
         mService.deferWindowLayout();
         try {
@@ -409,15 +407,33 @@
                     if (mWindowManager.mRoot.isLayoutNeeded()) {
                         mWindowManager.mRoot.performSurfacePlacement();
                     }
-                    if (mCaller != null) {
-                        mCaller.setRunningRecentsAnimation(false);
-                    }
+                    setProcessAnimating(false);
                     Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                 }
             });
         }
     }
 
+    /** Gives the owner of recents animation higher priority. */
+    private void setProcessAnimating(boolean animating) {
+        if (mCaller == null) return;
+        // Apply the top-app scheduling group to who runs the animation.
+        mCaller.setRunningRecentsAnimation(animating);
+        int demoteReasons = mService.mDemoteTopAppReasons;
+        if (animating) {
+            demoteReasons |= ActivityTaskManagerService.DEMOTE_TOP_REASON_ANIMATING_RECENTS;
+        } else {
+            demoteReasons &= ~ActivityTaskManagerService.DEMOTE_TOP_REASON_ANIMATING_RECENTS;
+        }
+        mService.mDemoteTopAppReasons = demoteReasons;
+        // Make the demotion of the real top app take effect. No need to restore top app state for
+        // finishing recents because addToStopping -> scheduleIdle -> activityIdleInternal ->
+        // trimApplications will have a full update.
+        if (animating && mService.mTopApp != null) {
+            mService.mTopApp.scheduleUpdateOomAdj();
+        }
+    }
+
     @Override
     public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode,
             boolean sendUserLeaveHint) {
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index fe0ab2b..d2ce048 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -1335,16 +1335,16 @@
                     mDisplayContent.mPinnedTaskController.setEnterPipTransaction(
                             mFinishTransaction);
                 }
+                // In the case where we are transferring the transform to the task in preparation
+                // for entering PIP, we disable the task being able to affect sysui flags otherwise
+                // it may cause a flash
+                if (mTask.getActivityType() != mTargetActivityType
+                        && mFinishTransaction.getShouldDisableCanAffectSystemUiFlags()) {
+                    mTask.setCanAffectSystemUiFlags(false);
+                }
                 mFinishTransaction = null;
                 mFinishOverlay = null;
                 pendingTransaction.apply();
-
-                // In the case where we are transferring the transform to the task in preparation 
-                // for entering PIP, we disable the task being able to affect sysui flags otherwise
-                // it may cause a flash
-                if (mTask.getActivityType() != mTargetActivityType) {
-                    mTask.setCanAffectSystemUiFlags(false);
-                }
             } else if (!mTask.isAttached()) {
                 // Apply the task's pending transaction in case it is detached and its transaction
                 // is not reachable.
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 871b4d8..ac1a2b1 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -22,6 +22,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
+import android.annotation.ColorInt;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Point;
@@ -57,7 +58,7 @@
  */
 class RemoteAnimationController implements DeathRecipient {
     private static final String TAG = TAG_WITH_CLASS_NAME
-                    ? "RemoteAnimationController" : TAG_WM;
+            ? "RemoteAnimationController" : TAG_WM;
     private static final long TIMEOUT_MS = 10000;
 
     private final WindowManagerService mService;
@@ -72,35 +73,40 @@
     private final Runnable mTimeoutRunnable = () -> cancelAnimation("timeoutRunnable");
 
     private FinishedCallback mFinishedCallback;
+    private final boolean mIsActivityEmbedding;
     private boolean mCanceled;
     private boolean mLinkedToDeathOfRunner;
     @Nullable
     private Runnable mOnRemoteAnimationReady;
 
     RemoteAnimationController(WindowManagerService service, DisplayContent displayContent,
-            RemoteAnimationAdapter remoteAnimationAdapter, Handler handler) {
+            RemoteAnimationAdapter remoteAnimationAdapter, Handler handler,
+            boolean isActivityEmbedding) {
         mService = service;
         mDisplayContent = displayContent;
         mRemoteAnimationAdapter = remoteAnimationAdapter;
         mHandler = handler;
+        mIsActivityEmbedding = isActivityEmbedding;
     }
 
     /**
      * Creates an animation record for each individual {@link WindowContainer}.
      *
      * @param windowContainer The windows to animate.
-     * @param position The position app bounds relative to its parent.
-     * @param localBounds The bounds of the app relative to its parent.
-     * @param endBounds The end bounds after the transition, in screen coordinates.
-     * @param startBounds The start bounds before the transition, in screen coordinates.
+     * @param position        The position app bounds relative to its parent.
+     * @param localBounds     The bounds of the app relative to its parent.
+     * @param endBounds       The end bounds after the transition, in screen coordinates.
+     * @param startBounds     The start bounds before the transition, in screen coordinates.
+     * @param showBackdrop    To show background behind a window during animation.
      * @return The record representing animation(s) to run on the app.
      */
     RemoteAnimationRecord createRemoteAnimationRecord(WindowContainer windowContainer,
-            Point position, Rect localBounds, Rect endBounds, Rect startBounds) {
+            Point position, Rect localBounds, Rect endBounds, Rect startBounds,
+            boolean showBackdrop) {
         ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAnimationAdapter(): container=%s",
                 windowContainer);
         final RemoteAnimationRecord adapters = new RemoteAnimationRecord(windowContainer, position,
-                localBounds, endBounds, startBounds);
+                localBounds, endBounds, startBounds, showBackdrop);
         mPendingAnimations.add(adapters);
         return adapters;
     }
@@ -111,6 +117,15 @@
     }
 
     /**
+     * We use isFromActivityEmbedding() in the server process to tell if we're running an
+     * Activity Embedding type remote animation, where animations are driven by the client.
+     * This is currently supporting features like showBackdrop where we need to load App XML.
+     */
+    public boolean isFromActivityEmbedding() {
+        return mIsActivityEmbedding;
+    }
+
+    /**
      * Called when the transition is ready to be started, and all leashes have been set up.
      */
     void goodToGo(@WindowManager.TransitionOldType int transit) {
@@ -418,30 +433,37 @@
         RemoteAnimationTarget mTarget;
         final WindowContainer mWindowContainer;
         final Rect mStartBounds;
+        final boolean mShowBackdrop;
+        @ColorInt int mBackdropColor = 0;
         private @RemoteAnimationTarget.Mode int mMode = RemoteAnimationTarget.MODE_CHANGING;
 
         RemoteAnimationRecord(WindowContainer windowContainer, Point endPos, Rect localBounds,
-                Rect endBounds, Rect startBounds) {
+                Rect endBounds, Rect startBounds, boolean showBackdrop) {
             mWindowContainer = windowContainer;
+            mShowBackdrop = showBackdrop;
             if (startBounds != null) {
                 mStartBounds = new Rect(startBounds);
                 mAdapter = new RemoteAnimationAdapterWrapper(this, endPos, localBounds, endBounds,
-                        mStartBounds);
+                        mStartBounds, mShowBackdrop);
                 if (mRemoteAnimationAdapter.getChangeNeedsSnapshot()) {
                     final Rect thumbnailLocalBounds = new Rect(startBounds);
                     thumbnailLocalBounds.offsetTo(0, 0);
                     // Snapshot is located at (0,0) of the animation leash. It doesn't have size
                     // change, so the startBounds is its end bounds, and no start bounds for it.
                     mThumbnailAdapter = new RemoteAnimationAdapterWrapper(this, new Point(0, 0),
-                            thumbnailLocalBounds, startBounds, new Rect());
+                            thumbnailLocalBounds, startBounds, new Rect(), mShowBackdrop);
                 }
             } else {
                 mAdapter = new RemoteAnimationAdapterWrapper(this, endPos, localBounds, endBounds,
-                        new Rect());
+                        new Rect(), mShowBackdrop);
                 mStartBounds = null;
             }
         }
 
+        void setBackDropColor(@ColorInt int backdropColor) {
+            mBackdropColor = backdropColor;
+        }
+
         RemoteAnimationTarget createRemoteAnimationTarget() {
             if (mAdapter == null
                     || mAdapter.mCapturedFinishCallback == null
@@ -483,14 +505,27 @@
         final Rect mLocalBounds;
         final Rect mEndBounds = new Rect();
         final Rect mStartBounds = new Rect();
+        final boolean mShowBackdrop;
 
         RemoteAnimationAdapterWrapper(RemoteAnimationRecord record, Point position,
-                Rect localBounds, Rect endBounds, Rect startBounds) {
+                Rect localBounds, Rect endBounds, Rect startBounds, boolean showBackdrop) {
             mRecord = record;
             mPosition.set(position.x, position.y);
             mLocalBounds = localBounds;
             mEndBounds.set(endBounds);
             mStartBounds.set(startBounds);
+            mShowBackdrop = showBackdrop;
+        }
+
+        @Override
+        @ColorInt
+        public int getBackgroundColor() {
+            return mRecord.mBackdropColor;
+        }
+
+        @Override
+        public boolean getShowBackground() {
+            return mShowBackdrop;
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
new file mode 100644
index 0000000..43baebc
--- /dev/null
+++ b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.IDisplayChangeWindowCallback;
+import android.window.DisplayAreaInfo;
+import android.window.WindowContainerTransaction;
+
+import com.android.internal.protolog.common.ProtoLog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A helper class, a wrapper around {@link android.view.IDisplayChangeWindowController} to perform
+ * a synchronous display change in other parts (e.g. in the Shell) and continue the process
+ * in the system server. It handles timeouts and multiple requests.
+ * We have an instance of this controller for each display.
+ */
+public class RemoteDisplayChangeController {
+
+    private static final String TAG = "RemoteDisplayChangeController";
+
+    private static final int REMOTE_DISPLAY_CHANGE_TIMEOUT_MS = 800;
+
+    private final WindowManagerService mService;
+    private final int mDisplayId;
+
+    private final Runnable mTimeoutRunnable = this::onContinueTimedOut;
+
+    // all remote changes that haven't finished yet.
+    private final List<ContinueRemoteDisplayChangeCallback> mCallbacks = new ArrayList<>();
+
+    public RemoteDisplayChangeController(WindowManagerService service, int displayId) {
+        mService = service;
+        mDisplayId = displayId;
+    }
+
+    /**
+     * A Remote change is when we are waiting for some registered (remote)
+     * {@link IDisplayChangeWindowController} to calculate and return some hierarchy operations
+     *  to perform in sync with the display change.
+     */
+    public boolean isWaitingForRemoteDisplayChange() {
+        return !mCallbacks.isEmpty();
+    }
+
+    /**
+     * Starts remote display change
+     * @param fromRotation rotation before the change
+     * @param toRotation rotation after the change
+     * @param newDisplayAreaInfo display area info after change
+     * @param callback that will be called after completing remote display change
+     * @return true if the change successfully started, false otherwise
+     */
+    public boolean performRemoteDisplayChange(
+            int fromRotation, int toRotation,
+            @Nullable DisplayAreaInfo newDisplayAreaInfo,
+            ContinueRemoteDisplayChangeCallback callback) {
+        if (mService.mDisplayChangeController == null) {
+            return false;
+        }
+        mCallbacks.add(callback);
+
+        if (newDisplayAreaInfo != null) {
+            ProtoLog.v(WM_DEBUG_CONFIGURATION,
+                    "Starting remote display change: "
+                            + "from [rot = %d], "
+                            + "to [%dx%d, rot = %d]",
+                    fromRotation,
+                    newDisplayAreaInfo.configuration.windowConfiguration
+                            .getMaxBounds().width(),
+                    newDisplayAreaInfo.configuration.windowConfiguration
+                            .getMaxBounds().height(),
+                    toRotation);
+        }
+
+        final IDisplayChangeWindowCallback remoteCallback = createCallback(callback);
+        try {
+            mService.mH.removeCallbacks(mTimeoutRunnable);
+            mService.mH.postDelayed(mTimeoutRunnable, REMOTE_DISPLAY_CHANGE_TIMEOUT_MS);
+            mService.mDisplayChangeController.onDisplayChange(mDisplayId, fromRotation, toRotation,
+                    newDisplayAreaInfo, remoteCallback);
+            return true;
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Exception while dispatching remote display-change", e);
+            mCallbacks.remove(callback);
+            return false;
+        }
+    }
+
+    private void onContinueTimedOut() {
+        Slog.e(TAG, "RemoteDisplayChange timed-out, UI might get messed-up after this.");
+        // timed-out, so run all continue callbacks and clear the list
+        synchronized (mService.mGlobalLock) {
+            for (int i = 0; i < mCallbacks.size(); ++i) {
+                mCallbacks.get(i).onContinueRemoteDisplayChange(null /* transaction */);
+            }
+            mCallbacks.clear();
+        }
+    }
+
+    private void continueDisplayChange(@NonNull ContinueRemoteDisplayChangeCallback callback,
+            @Nullable WindowContainerTransaction transaction) {
+        synchronized (mService.mGlobalLock) {
+            int idx = mCallbacks.indexOf(callback);
+            if (idx < 0) {
+                // already called this callback or a more-recent one (eg. via timeout)
+                return;
+            }
+            for (int i = 0; i < idx; ++i) {
+                // Expect remote callbacks in order. If they don't come in order, then force
+                // ordering by continuing everything up until this one with empty transactions.
+                mCallbacks.get(i).onContinueRemoteDisplayChange(null /* transaction */);
+            }
+            mCallbacks.subList(0, idx + 1).clear();
+            if (mCallbacks.isEmpty()) {
+                mService.mH.removeCallbacks(mTimeoutRunnable);
+            }
+            callback.onContinueRemoteDisplayChange(transaction);
+        }
+    }
+
+    private IDisplayChangeWindowCallback createCallback(
+            @NonNull ContinueRemoteDisplayChangeCallback callback) {
+        return new IDisplayChangeWindowCallback.Stub() {
+                    @Override
+                    public void continueDisplayChange(WindowContainerTransaction t) {
+                        synchronized (mService.mGlobalLock) {
+                            if (!mCallbacks.contains(callback)) {
+                                // already ran this callback or a more-recent one.
+                                return;
+                            }
+                            mService.mH.post(() -> RemoteDisplayChangeController.this
+                                    .continueDisplayChange(callback, t));
+                        }
+                    }
+                };
+    }
+
+    /**
+     * Callback interface to handle continuation of the remote display change
+     */
+    public interface ContinueRemoteDisplayChangeCallback {
+        /**
+         * This method is called when the remote display change has been applied
+         * @param transaction window changes collected by the remote display change
+         */
+        void onContinueRemoteDisplayChange(@Nullable WindowContainerTransaction transaction);
+    }
+}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index ef18b50..db730e0 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -37,6 +37,7 @@
 import static android.view.WindowManager.TRANSIT_NONE;
 import static android.view.WindowManager.TRANSIT_PIP;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.view.WindowManager.TRANSIT_WAKE;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
@@ -1238,11 +1239,6 @@
     }
 
     @Override
-    void scheduleAnimation() {
-        mWmService.scheduleAnimationLocked();
-    }
-
-    @Override
     protected void removeChild(DisplayContent dc) {
         super.removeChild(dc);
         if (mTopFocusedDisplayId == dc.getDisplayId()) {
@@ -1977,23 +1973,28 @@
 
     void moveActivityToPinnedRootTask(@NonNull ActivityRecord r,
             @Nullable ActivityRecord launchIntoPipHostActivity, String reason) {
-        mService.deferWindowLayout();
+        moveActivityToPinnedRootTask(r, launchIntoPipHostActivity, reason, null /* transition */);
+    }
 
+    void moveActivityToPinnedRootTask(@NonNull ActivityRecord r,
+            @Nullable ActivityRecord launchIntoPipHostActivity, String reason,
+            @Nullable Transition transition) {
         final TaskDisplayArea taskDisplayArea = r.getDisplayArea();
+        final Task task = r.getTask();
+        final Task rootTask;
 
+        Transition newTransition = transition;
+        // Create a transition now (if not provided) to collect the current pinned Task dismiss.
+        // Only do the create here as the Task (trigger) to enter PIP is not ready yet.
+        final TransitionController transitionController = task.mTransitionController;
+        if (newTransition == null && !transitionController.isCollecting()
+                && transitionController.getTransitionPlayer() != null) {
+            newTransition = transitionController.createTransition(TRANSIT_PIP);
+        }
+
+        transitionController.deferTransitionReady();
+        mService.deferWindowLayout();
         try {
-            final Task task = r.getTask();
-
-            // Create a transition now to collect the current pinned Task dismiss. Only do the
-            // create here as the Task (trigger) to enter PIP is not ready yet.
-            final TransitionController transitionController = task.mTransitionController;
-            Transition newTransition = null;
-            if (transitionController.isCollecting()) {
-                transitionController.setReady(task, false /* ready */);
-            } else if (transitionController.getTransitionPlayer() != null) {
-                newTransition = transitionController.createTransition(TRANSIT_PIP);
-            }
-
             // This will change the root pinned task's windowing mode to its original mode, ensuring
             // we only have one root task that is in pinned mode.
             final Task rootPinnedTask = taskDisplayArea.getRootPinnedTask();
@@ -2011,7 +2012,6 @@
 
             final TaskFragment organizedTf = r.getOrganizedTaskFragment();
             final boolean singleActivity = task.getNonFinishingActivityCount() == 1;
-            final Task rootTask;
             if (singleActivity) {
                 rootTask = task;
 
@@ -2044,6 +2044,9 @@
                             task.mLastRecentsAnimationTransaction,
                             task.mLastRecentsAnimationOverlay);
                     task.clearLastRecentsAnimationTransaction(false /* forceRemoveOverlay */);
+                } else {
+                    // Reset the original task surface
+                    task.resetSurfaceControlTransforms();
                 }
 
                 // The organized TaskFragment is becoming empty because this activity is reparented
@@ -2077,6 +2080,9 @@
                     oldTopActivity.mRequestForceTransition = true;
                 }
             }
+
+            transitionController.collect(rootTask);
+
             // The intermediate windowing mode to be set on the ActivityRecord later.
             // This needs to happen before the re-parenting, otherwise we will always set the
             // ActivityRecord to be fullscreen.
@@ -2087,13 +2093,6 @@
                 rootTask.reparent(taskDisplayArea, true /* onTop */);
             }
 
-            // The new PIP Task is ready, start the transition before updating the windowing mode.
-            if (newTransition != null) {
-                transitionController.requestStartTransition(newTransition, rootTask,
-                        null /* remoteTransition */, null /* displayChange */);
-            }
-            transitionController.collect(rootTask);
-
             // Defer the windowing mode change until after the transition to prevent the activity
             // from doing work and changing the activity visuals while animating
             // TODO(task-org): Figure-out more structured way to do this long term.
@@ -2136,9 +2135,23 @@
             }
         } finally {
             mService.continueWindowLayout();
+            try {
+                ensureActivitiesVisible(null, 0, false /* preserveWindows */);
+            } finally {
+                transitionController.continueTransitionReady();
+            }
         }
 
-        ensureActivitiesVisible(null, 0, false /* preserveWindows */);
+        if (newTransition != null) {
+            // Request at end since we want task-organizer events from ensureActivitiesVisible
+            // to be recognized.
+            transitionController.requestStartTransition(newTransition, rootTask,
+                    null /* remoteTransition */, null /* displayChange */);
+            // A new transition was created just for this operations. Since the operation is
+            // complete, mark it as ready.
+            newTransition.setReady(rootTask, true /* ready */);
+        }
+
         resumeFocusedTasksTopActivities();
 
         notifyActivityPipModeChanged(r.getTask(), r);
@@ -2321,6 +2334,14 @@
                 continue;
             }
 
+            // Prepare transition before resume top activity, so it can be collected.
+            if (!displayShouldSleep && display.isDefaultDisplay
+                    && !display.getDisplayPolicy().isAwake()
+                    && display.mTransitionController.isShellTransitionsEnabled()
+                    && !display.mTransitionController.isCollecting()) {
+                display.mTransitionController.requestTransitionIfNeeded(TRANSIT_WAKE,
+                        0 /* flags */, null /* trigger */, display);
+            }
             // Set the sleeping state of the root tasks on the display.
             display.forAllRootTasks(rootTask -> {
                 if (displayShouldSleep) {
diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java
index fd05f19..baa31a0 100644
--- a/services/core/java/com/android/server/wm/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java
@@ -173,7 +173,7 @@
         if (adapter == null) {
             return;
         }
-        if (callingPid == Process.myPid()) {
+        if (callingPid == WindowManagerService.MY_PID) {
             Slog.wtf(TAG, "Safe activity options constructed after clearing calling id");
             return;
         }
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 30b5083..9b013da 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -115,8 +115,6 @@
     private float mLastReportedAnimatorScale;
     private String mPackageName;
     private String mRelayoutTag;
-    private String mUpdateViewVisibilityTag;
-    private String mUpdateWindowLayoutTag;
     private final InsetsVisibilities mDummyRequestedVisibilities = new InsetsVisibilities();
     private final InsetsSourceControl[] mDummyControls =  new InsetsSourceControl[0];
     final boolean mSetsUnrestrictedKeepClearAreas;
@@ -195,27 +193,28 @@
     public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs,
             int viewVisibility, int displayId, InsetsVisibilities requestedVisibilities,
             InputChannel outInputChannel, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
+            InsetsSourceControl[] outActiveControls, Rect outAttachedFrame) {
         return mService.addWindow(this, window, attrs, viewVisibility, displayId,
                 UserHandle.getUserId(mUid), requestedVisibilities, outInputChannel, outInsetsState,
-                outActiveControls);
+                outActiveControls, outAttachedFrame);
     }
 
     @Override
     public int addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs,
             int viewVisibility, int displayId, int userId, InsetsVisibilities requestedVisibilities,
             InputChannel outInputChannel, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
+            InsetsSourceControl[] outActiveControls, Rect outAttachedFrame) {
         return mService.addWindow(this, window, attrs, viewVisibility, displayId, userId,
-                requestedVisibilities, outInputChannel, outInsetsState, outActiveControls);
+                requestedVisibilities, outInputChannel, outInsetsState, outActiveControls,
+                outAttachedFrame);
     }
 
     @Override
     public int addToDisplayWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
-            int viewVisibility, int displayId, InsetsState outInsetsState) {
+            int viewVisibility, int displayId, InsetsState outInsetsState, Rect outAttachedFrame) {
         return mService.addWindow(this, window, attrs, viewVisibility, displayId,
                 UserHandle.getUserId(mUid), mDummyRequestedVisibilities, null /* outInputChannel */,
-                outInsetsState, mDummyControls);
+                outInsetsState, mDummyControls, outAttachedFrame);
     }
 
     @Override
@@ -224,32 +223,16 @@
     }
 
     @Override
-    public int updateVisibility(IWindow client, WindowManager.LayoutParams attrs,
-            int viewVisibility, MergedConfiguration outMergedConfiguration,
-            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
-        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mUpdateViewVisibilityTag);
-        int res = mService.updateViewVisibility(this, client, attrs, viewVisibility,
-                outMergedConfiguration, outSurfaceControl, outInsetsState, outActiveControls);
-        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-        return res;
-    }
-
-    @Override
-    public void updateLayout(IWindow window, WindowManager.LayoutParams attrs, int flags,
-            ClientWindowFrames clientFrames, int requestedWidth, int requestedHeight) {
-        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mUpdateWindowLayoutTag);
-        mService.updateWindowLayout(this, window, attrs, flags, clientFrames, requestedWidth,
-                requestedHeight);
-        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-    }
-
-    @Override
     public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) {
         mService.setWillReplaceWindows(appToken, childrenOnly);
     }
 
     @Override
+    public boolean cancelDraw(IWindow window) {
+        return mService.cancelDraw(this, window);
+    }
+
+    @Override
     public int relayout(IWindow window, WindowManager.LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewFlags, int flags,
             ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
@@ -711,8 +694,6 @@
             if (wpc != null) {
                 mPackageName = wpc.mInfo.packageName;
                 mRelayoutTag = "relayoutWindow: " + mPackageName;
-                mUpdateViewVisibilityTag = "updateVisibility: " + mPackageName;
-                mUpdateWindowLayoutTag = "updateLayout: " + mPackageName;
             } else {
                 Slog.e(TAG_WM, "Unknown process pid=" + mPid);
             }
diff --git a/services/core/java/com/android/server/wm/StartingSurfaceController.java b/services/core/java/com/android/server/wm/StartingSurfaceController.java
index f83173b..0bb773a 100644
--- a/services/core/java/com/android/server/wm/StartingSurfaceController.java
+++ b/services/core/java/com/android/server/wm/StartingSurfaceController.java
@@ -220,6 +220,11 @@
         // Attempt to add starting window from the top-most activity.
         for (int i = mDeferringAddStartActivities.size() - 1; i >= 0; --i) {
             final DeferringStartingWindowRecord next = mDeferringAddStartActivities.get(i);
+            if (next.mDeferring.getTask() == null) {
+                Slog.e(TAG, "No task exists: " + next.mDeferring.shortComponentName
+                        + " parent: " + next.mDeferring.getParent());
+                continue;
+            }
             next.mDeferring.showStartingWindow(next.mPrev, mInitNewTask, mInitTaskSwitch,
                     mInitProcessRunning, true /* startActivity */, next.mSource, topOptions);
             // If one succeeds, it is done.
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index bf5246f..3d12774 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -67,16 +67,14 @@
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
 
-import static com.android.internal.policy.DecorView.DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP;
-import static com.android.internal.policy.DecorView.DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BACK_PREVIEW;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
-import static com.android.server.wm.ActivityRecord.State.INITIALIZING;
 import static com.android.server.wm.ActivityRecord.State.PAUSED;
 import static com.android.server.wm.ActivityRecord.State.PAUSING;
 import static com.android.server.wm.ActivityRecord.State.RESUMED;
@@ -131,7 +129,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.WindowManagerService.dipToPixel;
 
 import static java.lang.Integer.MAX_VALUE;
 
@@ -197,6 +194,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.protolog.ProtoLogGroup;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.util.function.pooled.PooledConsumer;
@@ -426,9 +424,6 @@
     /** Helper object used for updating override configuration. */
     private Configuration mTmpConfig = new Configuration();
 
-    /** Used by fillTaskInfo */
-    final TaskActivitiesReport mReuseActivitiesReport = new TaskActivitiesReport();
-
     /* Unique identifier for this task. */
     final int mTaskId;
     /* User for which this task was created. */
@@ -1404,15 +1399,6 @@
     }
 
     /**
-     * Return the number of running activities, and the number of non-finishing/initializing
-     * activities in the provided {@param reportOut} respectively.
-     */
-    private void getNumRunningActivities(TaskActivitiesReport reportOut) {
-        reportOut.reset();
-        forAllActivities(reportOut);
-    }
-
-    /**
      * Reorder the history task so that the passed activity is brought to the front.
      */
     final void moveActivityToFrontLocked(ActivityRecord newTop) {
@@ -1707,23 +1693,6 @@
                 lockTaskAuthToString());
     }
 
-    @Override
-    public boolean supportsSplitScreenWindowingMode() {
-        return supportsSplitScreenWindowingModeInDisplayArea(getDisplayArea());
-    }
-
-    boolean supportsSplitScreenWindowingModeInDisplayArea(@Nullable TaskDisplayArea tda) {
-        final Task topTask = getTopMostTask();
-        return super.supportsSplitScreenWindowingMode()
-                && (topTask == null || topTask.supportsSplitScreenWindowingModeInner(tda));
-    }
-
-    private boolean supportsSplitScreenWindowingModeInner(@Nullable TaskDisplayArea tda) {
-        return super.supportsSplitScreenWindowingMode()
-                && mAtmService.mSupportsSplitScreenMultiWindow
-                && supportsMultiWindowInDisplayArea(tda);
-    }
-
     boolean supportsFreeform() {
         return supportsFreeformInDisplayArea(getDisplayArea());
     }
@@ -1889,6 +1858,11 @@
         if (getRequestedOverrideWindowingMode() == WINDOWING_MODE_UNDEFINED) {
             nextPersistTaskBounds = newParentConfig.windowConfiguration.persistTaskBounds();
         }
+        // Only restore to the last non-fullscreen bounds when the requested override bounds
+        // have not been explicitly set already.
+        nextPersistTaskBounds &=
+                (getRequestedOverrideConfiguration().windowConfiguration.getBounds() == null
+                || getRequestedOverrideConfiguration().windowConfiguration.getBounds().isEmpty());
         if (!prevPersistTaskBounds && nextPersistTaskBounds
                 && mLastNonFullscreenBounds != null && !mLastNonFullscreenBounds.isEmpty()) {
             // Bypass onRequestedOverrideConfigurationChanged here to avoid infinite loop.
@@ -2031,10 +2005,6 @@
         Rect outOverrideBounds = getResolvedOverrideConfiguration().windowConfiguration.getBounds();
 
         if (windowingMode == WINDOWING_MODE_FULLSCREEN) {
-            if (!isOrganized()) {
-                // Use empty bounds to indicate "fill parent".
-                outOverrideBounds.setEmpty();
-            }
             // The bounds for fullscreen mode shouldn't be adjusted by minimal size. Otherwise if
             // the parent or display is smaller than the size, the content may be cropped.
             return;
@@ -3309,7 +3279,6 @@
         }
 
         final SurfaceControl.Transaction t = getSyncTransaction();
-        updateShadowsRadius(isFocused(), t);
 
         if (mDimmer.updateDims(t, mTmpDimBoundsRect)) {
             scheduleAnimation();
@@ -3384,14 +3353,14 @@
      *            the give {@link TaskDisplayArea}.
      */
     void fillTaskInfo(TaskInfo info, boolean stripExtras, @Nullable TaskDisplayArea tda) {
-        getNumRunningActivities(mReuseActivitiesReport);
+        info.launchCookies.clear();
+        info.addLaunchCookie(mLaunchCookie);
+        final ActivityRecord top = mTaskSupervisor.mTaskInfoHelper.fillAndReturnTop(this, info);
+
         info.userId = isLeafTask() ? mUserId : mCurrentUser;
         info.taskId = mTaskId;
         info.displayId = getDisplayId();
-        if (tda != null) {
-            info.displayAreaFeatureId = tda.mFeatureId;
-        }
-        info.isRunning = getTopNonFinishingActivity() != null;
+        info.displayAreaFeatureId = tda != null ? tda.mFeatureId : FEATURE_UNDEFINED;
         final Intent baseIntent = getBaseIntent();
         // Make a copy of base intent because this is like a snapshot info.
         // Besides, {@link RecentTasks#getRecentTasksImpl} may modify it.
@@ -3400,18 +3369,13 @@
                 ? new Intent()
                 : stripExtras ? baseIntent.cloneFilter() : new Intent(baseIntent);
         info.baseIntent.setFlags(baseIntentFlags);
-        info.baseActivity = mReuseActivitiesReport.base != null
-                ? mReuseActivitiesReport.base.intent.getComponent()
-                : null;
-        info.topActivity = mReuseActivitiesReport.top != null
-                ? mReuseActivitiesReport.top.mActivityComponent
-                : null;
+
+        info.isRunning = top != null;
+        info.topActivity = top != null ? top.mActivityComponent : null;
         info.origActivity = origActivity;
         info.realActivity = realActivity;
-        info.numActivities = mReuseActivitiesReport.numActivities;
         info.lastActiveTime = lastActiveTime;
         info.taskDescription = new ActivityManager.TaskDescription(getTaskDescription());
-        info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingModeInDisplayArea(tda);
         info.supportsMultiWindow = supportsMultiWindowInDisplayArea(tda);
         info.configuration.setTo(getConfiguration());
         // Update to the task's current activity type and windowing mode which may differ from the
@@ -3422,49 +3386,38 @@
 
         //TODO (AM refactor): Just use local once updateEffectiveIntent is run during all child
         //                    order changes.
-        final Task top = getTopMostTask();
-        info.resizeMode = top != null ? top.mResizeMode : mResizeMode;
-        info.topActivityType = top.getActivityType();
+        final Task topTask = top != null ? top.getTask() : this;
+        info.resizeMode = topTask.mResizeMode;
+        info.topActivityType = topTask.getActivityType();
+        info.displayCutoutInsets = topTask.getDisplayCutoutInsets();
         info.isResizeable = isResizeable();
         info.minWidth = mMinWidth;
         info.minHeight = mMinHeight;
         info.defaultMinSize = mDisplayContent == null
                 ? DEFAULT_MIN_TASK_SIZE_DP : mDisplayContent.mMinSizeOfResizeableTaskDp;
-
         info.positionInParent = getRelativePosition();
 
+        info.topActivityInfo = top != null ? top.info : null;
         info.pictureInPictureParams = getPictureInPictureParams(top);
-        info.shouldDockBigOverlays = shouldDockBigOverlays();
-        if (info.pictureInPictureParams != null
+        info.launchIntoPipHostTaskId = (info.pictureInPictureParams != null
                 && info.pictureInPictureParams.isLaunchIntoPip()
-                && top.getTopMostActivity().getLastParentBeforePip() != null) {
-            info.launchIntoPipHostTaskId =
-                    top.getTopMostActivity().getLastParentBeforePip().mTaskId;
-        }
-        info.displayCutoutInsets = top != null ? top.getDisplayCutoutInsets() : null;
-        info.topActivityInfo = mReuseActivitiesReport.top != null
-                ? mReuseActivitiesReport.top.info
-                : null;
+                && top.getLastParentBeforePip() != null)
+                        ? top.getLastParentBeforePip().mTaskId : INVALID_TASK_ID;
+        info.shouldDockBigOverlays = top != null && top.shouldDockBigOverlays;
+        info.mTopActivityLocusId = top != null ? top.getLocusId() : null;
 
-        boolean isTopActivityResumed = mReuseActivitiesReport.top != null
-                 && mReuseActivitiesReport.top.getOrganizedTask() == this
-                 && mReuseActivitiesReport.top.isState(RESUMED);
+        final boolean isTopActivityResumed = top != null
+                && top.getOrganizedTask() == this && top.isState(RESUMED);
         // Whether the direct top activity is in size compat mode on foreground.
-        info.topActivityInSizeCompat = isTopActivityResumed
-                && mReuseActivitiesReport.top.inSizeCompatMode();
+        info.topActivityInSizeCompat = isTopActivityResumed && top.inSizeCompatMode();
         // Whether the direct top activity is eligible for letterbox education.
         info.topActivityEligibleForLetterboxEducation = isTopActivityResumed
-                && mReuseActivitiesReport.top.isEligibleForLetterboxEducation();
+                && top.isEligibleForLetterboxEducation();
         // Whether the direct top activity requested showing camera compat control.
         info.cameraCompatControlState = isTopActivityResumed
-                ? mReuseActivitiesReport.top.getCameraCompatControlState()
+                ? top.getCameraCompatControlState()
                 : TaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
 
-        info.launchCookies.clear();
-        info.addLaunchCookie(mLaunchCookie);
-        forAllActivities(r -> {
-            info.addLaunchCookie(r.mLaunchCookie);
-        });
         final Task parentTask = getParent() != null ? getParent().asTask() : null;
         info.parentTaskId = parentTask != null && parentTask.mCreatedByOrganizer
                 ? parentTask.mTaskId
@@ -3472,19 +3425,17 @@
         info.isFocused = isFocused();
         info.isVisible = hasVisibleChildren();
         info.isSleeping = shouldSleepActivities();
-        ActivityRecord topRecord = getTopNonFinishingActivity();
-        info.mTopActivityLocusId = topRecord != null ? topRecord.getLocusId() : null;
     }
 
     @Nullable PictureInPictureParams getPictureInPictureParams() {
-        return getPictureInPictureParams(getTopMostTask());
+        final Task topTask = getTopMostTask();
+        if (topTask == null) return null;
+        return getPictureInPictureParams(topTask.getTopMostActivity());
     }
 
-    private @Nullable PictureInPictureParams getPictureInPictureParams(Task top) {
-        if (top == null) return null;
-        final ActivityRecord topMostActivity = top.getTopMostActivity();
-        return (topMostActivity == null || topMostActivity.pictureInPictureArgs.empty())
-                ? null : new PictureInPictureParams(topMostActivity.pictureInPictureArgs);
+    private static @Nullable PictureInPictureParams getPictureInPictureParams(ActivityRecord top) {
+        return (top == null || top.pictureInPictureArgs.empty())
+                ? null : new PictureInPictureParams(top.pictureInPictureArgs);
     }
 
     private boolean shouldDockBigOverlays() {
@@ -3673,30 +3624,35 @@
     }
 
     @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder(128);
-        if (stringName != null) {
-            sb.append(stringName);
-            sb.append(" U=");
-            sb.append(mUserId);
-            final Task rootTask = getRootTask();
-            if (rootTask != this) {
-                sb.append(" rootTaskId=");
-                sb.append(rootTask.mTaskId);
-            }
-            sb.append(" visible=");
-            sb.append(shouldBeVisible(null /* starting */));
-            sb.append(" visibleRequested=");
-            sb.append(isVisibleRequested());
-            sb.append(" mode=");
-            sb.append(windowingModeToString(getWindowingMode()));
-            sb.append(" translucent=");
-            sb.append(isTranslucent(null /* starting */));
-            sb.append(" sz=");
-            sb.append(getChildCount());
-            sb.append('}');
-            return sb.toString();
+    String toFullString() {
+        final StringBuilder sb = new StringBuilder(192);
+        sb.append(this);
+        sb.setLength(sb.length() - 1); // Remove tail '}'.
+        sb.append(" U=");
+        sb.append(mUserId);
+        final Task rootTask = getRootTask();
+        if (rootTask != this) {
+            sb.append(" rootTaskId=");
+            sb.append(rootTask.mTaskId);
         }
+        sb.append(" visible=");
+        sb.append(shouldBeVisible(null /* starting */));
+        sb.append(" visibleRequested=");
+        sb.append(isVisibleRequested());
+        sb.append(" mode=");
+        sb.append(windowingModeToString(getWindowingMode()));
+        sb.append(" translucent=");
+        sb.append(isTranslucent(null /* starting */));
+        sb.append(" sz=");
+        sb.append(getChildCount());
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public String toString() {
+        if (stringName != null) return stringName;
+        StringBuilder sb = new StringBuilder(128);
         sb.append("Task{");
         sb.append(Integer.toHexString(System.identityHashCode(this)));
         sb.append(" #");
@@ -3711,47 +3667,9 @@
         } else if (affinityIntent != null && affinityIntent.getComponent() != null) {
             sb.append(" aI=");
             sb.append(affinityIntent.getComponent().flattenToShortString());
-        } else {
-            sb.append(" ??");
         }
-        stringName = sb.toString();
-        return toString();
-    }
-
-    /** @see #getNumRunningActivities(TaskActivitiesReport) */
-    static class TaskActivitiesReport implements Consumer<ActivityRecord> {
-        int numRunning;
-        int numActivities;
-        ActivityRecord top;
-        ActivityRecord base;
-
-        void reset() {
-            numRunning = numActivities = 0;
-            top = base = null;
-        }
-
-        @Override
-        public void accept(ActivityRecord r) {
-            if (r.finishing) {
-                return;
-            }
-
-            base = r;
-
-            // Increment the total number of non-finishing activities
-            numActivities++;
-
-            if (top == null || (top.isState(INITIALIZING))) {
-                top = r;
-                // Reset the number of running activities until we hit the first non-initializing
-                // activity
-                numRunning = 0;
-            }
-            if (r.attachedToProcess()) {
-                // Increment the number of actually running activities
-                numRunning++;
-            }
-        }
+        sb.append('}');
+        return stringName = sb.toString();
     }
 
     /**
@@ -4335,48 +4253,10 @@
     }
 
     /**
-     * @return the desired shadow radius in pixels for the current task.
-     */
-    private float getShadowRadius(boolean taskIsFocused) {
-        int elevation = 0;
-
-        // Get elevation for a specific windowing mode.
-        if (inFreeformWindowingMode()) {
-            elevation = taskIsFocused
-                    ? DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
-        } else {
-            // For all other windowing modes, do not draw a shadow.
-            return 0;
-        }
-
-        // If the task has no visible children, do not draw a shadow.
-        if (!hasVisibleChildren()) {
-            return 0;
-        }
-
-        return dipToPixel(elevation, getDisplayContent().getDisplayMetrics());
-    }
-
-    /**
-     * Update the length of the shadow if needed based on windowing mode and task focus state.
-     */
-    private void updateShadowsRadius(boolean taskIsFocused,
-            SurfaceControl.Transaction pendingTransaction) {
-        if (!isRootTask()) return;
-
-        final float newShadowRadius = getShadowRadius(taskIsFocused);
-        if (mShadowRadius != newShadowRadius) {
-            mShadowRadius = newShadowRadius;
-            pendingTransaction.setShadowRadius(getSurfaceControl(), mShadowRadius);
-        }
-    }
-
-    /**
      * Called on the task when it gained or lost focus.
      * @param hasFocus
      */
     void onAppFocusChanged(boolean hasFocus) {
-        updateShadowsRadius(hasFocus, getSyncTransaction());
         dispatchTaskInfoChangedIfNeeded(false /* force */);
     }
 
@@ -4555,13 +4435,13 @@
                     : WINDOWING_MODE_FULLSCREEN;
         }
         if (currentMode == WINDOWING_MODE_PINNED) {
+            // In the case that we've disabled affecting the SysUI flags as a part of seamlessly
+            // transferring the transform on the leash to the task, reset this state once we're
+            // moving out of pip
+            setCanAffectSystemUiFlags(true);
             mRootWindowContainer.notifyActivityPipModeChanged(this, null);
         }
         if (likelyResolvedMode == WINDOWING_MODE_PINNED) {
-            // In the case that we've disabled affecting the SysUI flags as a part of seamlessly
-            // transferring the transform on the leash to the task, reset this state once we've
-            // actually entered pip
-            setCanAffectSystemUiFlags(true);
             if (taskDisplayArea.getRootPinnedTask() != null) {
                 // Can only have 1 pip at a time, so replace an existing pip
                 taskDisplayArea.getRootPinnedTask().dismissPip();
@@ -4652,22 +4532,12 @@
         moveToFront(reason, null);
     }
 
-    void moveToFront(String reason, Task task) {
-        if (mMoveAdjacentTogether && getAdjacentTaskFragment() != null) {
-            final Task adjacentTask = getAdjacentTaskFragment().asTask();
-            if (adjacentTask != null) {
-                adjacentTask.moveToFrontInner(reason + " adjacentTaskToTop", null /* task */);
-            }
-        }
-        moveToFrontInner(reason, task);
-    }
-
     /**
      * @param reason The reason for moving the root task to the front.
      * @param task If non-null, the task will be moved to the top of the root task.
      */
     @VisibleForTesting
-    void moveToFrontInner(String reason, Task task) {
+    void moveToFront(String reason, Task task) {
         if (!isAttached()) {
             return;
         }
@@ -5581,23 +5451,10 @@
         }
     }
 
-    /**
-     * Worker method for rearranging history task. Implements the function of moving all
-     * activities for a specific task (gathering them if disjoint) into a single group at the
-     * bottom of the root task.
-     *
-     * If a watcher is installed, the action is preflighted and the watcher has an opportunity
-     * to premeptively cancel the move.
-     *
-     * @param tr The task to collect and move to the bottom.
-     * @return Returns true if the move completed, false if not.
-     */
-    boolean moveTaskToBack(Task tr) {
-        Slog.i(TAG, "moveTaskToBack: " + tr);
-
+    private boolean canMoveTaskToBack(Task task) {
         // In LockTask mode, moving a locked task to the back of the root task may expose unlocked
         // ones. Therefore we need to check if this operation is allowed.
-        if (!mAtmService.getLockTaskController().canMoveTaskToBack(tr)) {
+        if (!mAtmService.getLockTaskController().canMoveTaskToBack(task)) {
             return false;
         }
 
@@ -5605,7 +5462,7 @@
         // for *other* available tasks, but if none are available, then try again allowing the
         // current task to be selected.
         if (isTopRootTaskInDisplayArea() && mAtmService.mController != null) {
-            ActivityRecord next = topRunningActivity(null, tr.mTaskId);
+            ActivityRecord next = topRunningActivity(null, task.mTaskId);
             if (next == null) {
                 next = topRunningActivity(null, INVALID_TASK_ID);
             }
@@ -5623,15 +5480,70 @@
                 }
             }
         }
+        return true;
+    }
+
+    /**
+     * Worker method for rearranging history task. Implements the function of moving all
+     * activities for a specific task (gathering them if disjoint) into a single group at the
+     * bottom of the root task.
+     *
+     * If a watcher is installed, the action is preflighted and the watcher has an opportunity
+     * to premeptively cancel the move.
+     *
+     * If this is a pinned task, it will be removed instead of rearranged.
+     *
+     * @param tr The task to collect and move to the bottom.
+     * @return Returns true if the move completed, false if not.
+     */
+    boolean moveTaskToBack(Task tr) {
+        Slog.i(TAG, "moveTaskToBack: " + tr);
+
+        if (!canMoveTaskToBack(tr)) return false;
 
         if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task="
                 + tr.mTaskId);
 
-        // Skip the transition for pinned task.
-        if (!inPinnedWindowingMode()) {
-            mDisplayContent.requestTransitionAndLegacyPrepare(TRANSIT_TO_BACK, tr);
+        if (mTransitionController.isShellTransitionsEnabled()) {
+            final Transition transition = new Transition(TRANSIT_TO_BACK, 0 /* flags */,
+                    mTransitionController, mWmService.mSyncEngine);
+            // Guarantee that this gets its own transition by queueing on SyncEngine
+            if (mWmService.mSyncEngine.hasActiveSync()) {
+                ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
+                        "Creating Pending Move-to-back: %s", transition);
+                mWmService.mSyncEngine.queueSyncSet(
+                        () -> mTransitionController.moveToCollecting(transition),
+                        () -> {
+                            mTransitionController.requestStartTransition(transition, tr,
+                                    null /* remoteTransition */, null /* displayChange */);
+                            // Need to check again since this happens later and the system might
+                            // be in a different state.
+                            if (!canMoveTaskToBack(tr)) {
+                                Slog.e(TAG, "Failed to move task to back after saying we could: "
+                                        + tr.mTaskId);
+                                transition.abort();
+                                return;
+                            }
+                            moveTaskToBackInner(tr);
+                        });
+            } else {
+                mTransitionController.moveToCollecting(transition);
+                mTransitionController.requestStartTransition(transition, tr,
+                        null /* remoteTransition */, null /* displayChange */);
+                moveTaskToBackInner(tr);
+            }
+        } else {
+            // Skip the transition for pinned task.
+            if (!inPinnedWindowingMode()) {
+                mDisplayContent.prepareAppTransition(TRANSIT_TO_BACK);
+            }
+            moveTaskToBackInner(tr);
         }
-        moveToBack("moveTaskToBackLocked", tr);
+        return true;
+    }
+
+    private boolean moveTaskToBackInner(@NonNull Task task) {
+        moveToBack("moveTaskToBackInner", task);
 
         if (inPinnedWindowingMode()) {
             mTaskSupervisor.removeRootTask(this);
@@ -6028,8 +5940,13 @@
         mLastRecentsAnimationTransaction = null;
         mLastRecentsAnimationOverlay = null;
         // reset also the crop and transform introduced by mLastRecentsAnimationTransaction
-        getPendingTransaction().setMatrix(mSurfaceControl, Matrix.IDENTITY_MATRIX, new float[9])
+        resetSurfaceControlTransforms();
+    }
+
+    void resetSurfaceControlTransforms() {
+        getSyncTransaction().setMatrix(mSurfaceControl, Matrix.IDENTITY_MATRIX, new float[9])
                 .setWindowCrop(mSurfaceControl, null)
+                .setShadowRadius(mSurfaceControl, 0)
                 .setCornerRadius(mSurfaceControl, 0);
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index ca91a74..8220cae 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -29,7 +29,6 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.view.WindowManagerPolicyConstants.SPLIT_DIVIDER_LAYER;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
 import static com.android.server.wm.ActivityRecord.State.RESUMED;
@@ -91,20 +90,6 @@
      */
     private int mColorLayerCounter = 0;
 
-    /**
-     * Given that the split-screen divider does not have an AppWindowToken, it
-     * will have to live inside of a "NonAppWindowContainer". However, in visual Z order
-     * it will need to be interleaved with some of our children, appearing on top of
-     * both docked root tasks but underneath any assistant root tasks.
-     *
-     * To solve this problem we have this anchor control, which will always exist so
-     * we can always assign it the correct value in our {@link #assignChildLayers}.
-     * Likewise since it always exists, we can always
-     * assign the divider a layer relative to it. This way we prevent linking lifecycle
-     * events between tasks and the divider window.
-     */
-    private SurfaceControl mSplitScreenDividerAnchor;
-
     // Cached reference to some special tasks we tend to get a lot so we don't need to loop
     // through the list to find them.
     private Task mRootHomeTask;
@@ -422,8 +407,10 @@
         // wasContained} restricts the preferred root task is set only when moving an existing
         // root task to top instead of adding a new root task that may be too early (e.g. in the
         // middle of launching or reparenting).
-        if (moveToTop && child.isFocusableAndVisible()) {
-            mPreferredTopFocusableRootTask = child;
+        final boolean isTopFocusableTask = moveToTop && child.isTopActivityFocusable();
+        if (isTopFocusableTask) {
+            mPreferredTopFocusableRootTask =
+                    child.shouldBeVisible(null /* starting */) ? child : null;
         } else if (mPreferredTopFocusableRootTask == child) {
             mPreferredTopFocusableRootTask = null;
         }
@@ -736,12 +723,7 @@
         // Place root home tasks to the bottom.
         layer = adjustRootTaskLayer(t, mTmpHomeChildren, layer);
         layer = adjustRootTaskLayer(t, mTmpNormalChildren, layer);
-        // TODO(b/207185041): Remove this divider workaround after we full remove leagacy split and
-        //                    make app pair split only have single root then we can just attach the
-        //                    divider to the single root task in shell.
-        layer = Math.max(layer, SPLIT_DIVIDER_LAYER + 1);
         adjustRootTaskLayer(t, mTmpAlwaysOnTopChildren, layer);
-        t.setLayer(mSplitScreenDividerAnchor, SPLIT_DIVIDER_LAYER);
     }
 
     /**
@@ -769,19 +751,6 @@
                 continue;
             }
 
-            final Task childTask = child.asTask();
-            final boolean inAdjacentTask = childTask != null
-                    && child.inMultiWindowMode()
-                    && childTask.getRootTask().getAdjacentTaskFragment() != null;
-
-            if (inAdjacentTask) {
-                hasAdjacentTask = true;
-            } else if (hasAdjacentTask && startLayer < SPLIT_DIVIDER_LAYER) {
-                // Task on top of adjacent tasks should be higher than split divider layer so
-                // set it as start.
-                startLayer = SPLIT_DIVIDER_LAYER + 1;
-            }
-
             child.assignLayer(t, startLayer++);
         }
 
@@ -808,31 +777,6 @@
         return activity != null ? activity.createRemoteAnimationTarget(record) : null;
     }
 
-    SurfaceControl getSplitScreenDividerAnchor() {
-        return mSplitScreenDividerAnchor;
-    }
-
-    @Override
-    void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
-        if (getParent() != null) {
-            super.onParentChanged(newParent, oldParent, () -> {
-                mSplitScreenDividerAnchor = makeChildSurface(null)
-                        .setName("splitScreenDividerAnchor")
-                        .setCallsite("TaskDisplayArea.onParentChanged")
-                        .build();
-
-                getSyncTransaction()
-                        .show(mSplitScreenDividerAnchor);
-            });
-        } else {
-            super.onParentChanged(newParent, oldParent);
-            mWmService.mTransactionFactory.get()
-                    .remove(mSplitScreenDividerAnchor)
-                    .apply();
-            mSplitScreenDividerAnchor = null;
-        }
-    }
-
     void setBackgroundColor(@ColorInt int colorInt) {
         setBackgroundColor(colorInt, false /* restore */);
     }
@@ -878,12 +822,6 @@
             setBackgroundColor(mBackgroundColor, true /* restore */);
         }
 
-        if (mSplitScreenDividerAnchor == null) {
-            return;
-        }
-
-        // As TaskDisplayArea is getting a new surface, reparent and reorder the child surfaces.
-        t.reparent(mSplitScreenDividerAnchor, mSurfaceControl);
         reassignLayer(t);
         scheduleAnimation();
     }
@@ -1176,7 +1114,10 @@
         // If a task is launching from a created-by-organizer task, it should be launched into the
         // same created-by-organizer task as well. Unless, the candidate task is already positioned
         // in the another adjacent task.
-        if (sourceTask != null) {
+        if (sourceTask != null && (candidateTask == null
+                // A pinned task relaunching should be handled by its task organizer. Skip fallback
+                // launch target of a pinned task from source task.
+                || candidateTask.getWindowingMode() != WINDOWING_MODE_PINNED)) {
             Task launchTarget = sourceTask.getCreatedByOrganizerTask();
             if (launchTarget != null && launchTarget.getAdjacentTaskFragment() != null) {
                 if (candidateTask != null) {
@@ -1906,15 +1847,12 @@
                 task.remove(false /* withTransition */, "removeTaskDisplayArea");
             } else {
                 // Reparent task to corresponding launch root or display area.
-                final WindowContainer launchRoot =
-                        task.supportsSplitScreenWindowingModeInDisplayArea(toDisplayArea)
-                                ? toDisplayArea.getLaunchRootTask(
+                final WindowContainer launchRoot = toDisplayArea.getLaunchRootTask(
                                         task.getWindowingMode(),
                                         task.getActivityType(),
                                         null /* options */,
                                         null /* sourceTask */,
-                                        0 /* launchFlags */)
-                                : null;
+                                        0 /* launchFlags */);
                 task.reparent(launchRoot == null ? toDisplayArea : launchRoot, POSITION_TOP);
 
                 // Set the windowing mode to undefined by default to let the root task inherited the
@@ -2002,7 +1940,7 @@
                 continue;
             }
             final Task rootTask = child.asTask();
-            pw.println(doublePrefix + "* " + rootTask);
+            pw.println(doublePrefix + "* " + rootTask.toFullString());
             rootTask.dump(pw, triplePrefix, dumpAll);
         }
     }
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 1d32867..61e484a 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -175,14 +175,6 @@
     private TaskFragment mAdjacentTaskFragment;
 
     /**
-     * Whether to move adjacent task fragment together when re-positioning.
-     *
-     * @see #mAdjacentTaskFragment
-     */
-    // TODO(b/207185041): Remove this once having a single-top root for split screen.
-    boolean mMoveAdjacentTogether;
-
-    /**
      * Prevents duplicate calls to onTaskAppeared.
      */
     boolean mTaskFragmentAppearedSent;
@@ -334,15 +326,14 @@
         return service.mWindowOrganizerController.getTaskFragment(token);
     }
 
-    void setAdjacentTaskFragment(@Nullable TaskFragment taskFragment, boolean moveTogether) {
+    void setAdjacentTaskFragment(@Nullable TaskFragment taskFragment) {
         if (mAdjacentTaskFragment == taskFragment) {
             return;
         }
         resetAdjacentTaskFragment();
         if (taskFragment != null) {
             mAdjacentTaskFragment = taskFragment;
-            mMoveAdjacentTogether = moveTogether;
-            taskFragment.setAdjacentTaskFragment(this, moveTogether);
+            taskFragment.setAdjacentTaskFragment(this);
         }
     }
 
@@ -351,11 +342,9 @@
         if (mAdjacentTaskFragment != null && mAdjacentTaskFragment.mAdjacentTaskFragment == this) {
             mAdjacentTaskFragment.mAdjacentTaskFragment = null;
             mAdjacentTaskFragment.mDelayLastActivityRemoval = false;
-            mAdjacentTaskFragment.mMoveAdjacentTogether = false;
         }
         mAdjacentTaskFragment = null;
         mDelayLastActivityRemoval = false;
-        mMoveAdjacentTogether = false;
     }
 
     void setTaskFragmentOrganizer(@NonNull TaskFragmentOrganizerToken organizer, int uid,
@@ -1554,7 +1543,7 @@
         if (prev.attachedToProcess()) {
             if (shouldAutoPip) {
                 boolean didAutoPip = mAtmService.enterPictureInPictureMode(
-                        prev, prev.pictureInPictureArgs);
+                        prev, prev.pictureInPictureArgs, false /* fromClient */);
                 ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, entering PIP mode "
                         + "directly: %s, didAutoPip: %b", prev, didAutoPip);
             } else {
@@ -1592,8 +1581,11 @@
 
             } else {
                 prev.schedulePauseTimeout();
-                // Unset readiness since we now need to wait until this pause is complete.
-                mTransitionController.setReady(this, false /* ready */);
+                // All activities will be stopped when sleeping, don't need to wait for pause.
+                if (!uiSleeping) {
+                    // Unset readiness since we now need to wait until this pause is complete.
+                    mTransitionController.setReady(this, false /* ready */);
+                }
                 return true;
             }
 
@@ -1887,19 +1879,19 @@
         if (!mAtmService.mSupportsMultiWindow) {
             return false;
         }
+        if (tda == null) {
+            return false;
+        }
         final Task task = getTask();
         if (task == null) {
             return false;
         }
-        if (tda == null) {
-            return false;
-        }
-        if (!getTask().isResizeable() && !tda.supportsNonResizableMultiWindow()) {
+        if (!task.isResizeable() && !tda.supportsNonResizableMultiWindow()) {
             // Not support non-resizable in multi window.
             return false;
         }
 
-        final ActivityRecord rootActivity = getTask().getRootActivity();
+        final ActivityRecord rootActivity = task.getRootActivity();
         return tda.supportsActivityMinWidthHeightMultiWindow(mMinWidth, mMinHeight,
                 rootActivity != null ? rootActivity.info : null);
     }
@@ -2061,13 +2053,14 @@
             }
 
             if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
-                final int overrideScreenWidthDp = (int) (mTmpStableBounds.width() / density);
+                final int overrideScreenWidthDp = (int) (mTmpStableBounds.width() / density + 0.5f);
                 inOutConfig.screenWidthDp = (insideParentBounds && !customContainerPolicy)
                         ? Math.min(overrideScreenWidthDp, parentConfig.screenWidthDp)
                         : overrideScreenWidthDp;
             }
             if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
-                final int overrideScreenHeightDp = (int) (mTmpStableBounds.height() / density);
+                final int overrideScreenHeightDp =
+                        (int) (mTmpStableBounds.height() / density + 0.5f);
                 inOutConfig.screenHeightDp = (insideParentBounds && !customContainerPolicy)
                         ? Math.min(overrideScreenHeightDp, parentConfig.screenHeightDp)
                         : overrideScreenHeightDp;
@@ -2086,8 +2079,8 @@
                 if (WindowConfiguration.isFloating(windowingMode) && !inPipTransition) {
                     // For floating tasks, calculate the smallest width from the bounds of the
                     // task, because they should not be affected by insets.
-                    inOutConfig.smallestScreenWidthDp = (int) (
-                            Math.min(mTmpFullBounds.width(), mTmpFullBounds.height()) / density);
+                    inOutConfig.smallestScreenWidthDp = (int) (0.5f
+                            + Math.min(mTmpFullBounds.width(), mTmpFullBounds.height()) / density);
                 } else if (isEmbedded()) {
                     // For embedded TFs, the smallest width should be updated. Otherwise, inherit
                     // from the parent task would result in applications loaded wrong resource.
@@ -2106,8 +2099,8 @@
             // For calculating screen layout, we need to use the non-decor inset screen area for the
             // calculation for compatibility reasons, i.e. screen area without system bars that
             // could never go away in Honeycomb.
-            int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
-            int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
+            int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density + 0.5f);
+            int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density + 0.5f);
             // Use overrides if provided. If both overrides are provided, mTmpNonDecorBounds is
             // undefined so it can't be used.
             if (inOutConfig.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
@@ -2503,7 +2496,7 @@
         if (!hasChild()) {
             return false;
         }
-        return isExitAnimationRunningSelfOrChild() || inTransition();
+        return isExitAnimationRunningSelfOrChild();
     }
 
     @Override
@@ -2588,6 +2581,32 @@
         return getWindowingMode() == WINDOWING_MODE_FULLSCREEN || matchParentBounds();
     }
 
+    String toFullString() {
+        final StringBuilder sb = new StringBuilder(128);
+        sb.append(this);
+        sb.setLength(sb.length() - 1); // Remove tail '}'.
+        if (mTaskFragmentOrganizerUid != INVALID_UID) {
+            sb.append(" organizerUid=");
+            sb.append(mTaskFragmentOrganizerUid);
+        }
+        if (mTaskFragmentOrganizerProcessName != null) {
+            sb.append(" organizerProc=");
+            sb.append(mTaskFragmentOrganizerProcessName);
+        }
+        if (mAdjacentTaskFragment != null) {
+            sb.append(" adjacent=");
+            sb.append(mAdjacentTaskFragment);
+        }
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public String toString() {
+        return "TaskFragment{" + Integer.toHexString(System.identityHashCode(this))
+                + " mode=" + WindowConfiguration.windowingModeToString(getWindowingMode()) + "}";
+    }
+
     boolean dump(String prefix, FileDescriptor fd, PrintWriter pw, boolean dumpAll,
             boolean dumpClient, String dumpPackage, final boolean needSep, Runnable header) {
         boolean printed = false;
@@ -2626,7 +2645,7 @@
     }
 
     void dumpInner(String prefix, PrintWriter pw, boolean dumpAll, String dumpPackage) {
-        pw.print(prefix); pw.print("* "); pw.println(this);
+        pw.print(prefix); pw.print("* "); pw.println(toFullString());
         final Rect bounds = getRequestedOverrideBounds();
         if (!bounds.isEmpty()) {
             pw.println(prefix + "  mBounds=" + bounds);
@@ -2647,10 +2666,11 @@
         final String doublePrefix = prefix + "  ";
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final WindowContainer<?> child = mChildren.get(i);
-            pw.println(prefix + "* " + child);
+            final TaskFragment tf = child.asTaskFragment();
+            pw.println(prefix + "* " + (tf != null ? tf.toFullString() : child));
             // Only dump non-activity because full activity info is already printed by
             // RootWindowContainer#dumpActivities.
-            if (child.asActivityRecord() == null) {
+            if (tf != null) {
                 child.dump(pw, doublePrefix, dumpAll);
             }
         }
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index b4d1cf7..9aff23d 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -470,6 +470,8 @@
                 .setException(exception)
                 .build();
         mPendingTaskFragmentEvents.add(pendingEvent);
+        // Make sure the error event will be dispatched if there are no other changes.
+        mAtmService.mWindowManager.mWindowPlacerLocked.requestTraversal();
     }
 
     void onActivityReparentToTask(ActivityRecord activity) {
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 47c397d..03ca4fd 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -41,7 +41,6 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.InputConfig;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.Trace;
 import android.util.DisplayMetrics;
@@ -222,8 +221,8 @@
         mDragWindowHandle.token = mClientChannel.getToken();
         mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
         mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
-        mDragWindowHandle.ownerPid = Process.myPid();
-        mDragWindowHandle.ownerUid = Process.myUid();
+        mDragWindowHandle.ownerPid = WindowManagerService.MY_PID;
+        mDragWindowHandle.ownerUid = WindowManagerService.MY_UID;
         mDragWindowHandle.scaleFactor = 1.0f;
         // When dragging the window around, we do not want to steal focus for the window.
         mDragWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 814656d..534616f 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -47,6 +47,7 @@
 import android.hardware.HardwareBuffer;
 import android.os.Environment;
 import android.os.Handler;
+import android.os.Trace;
 import android.util.ArraySet;
 import android.util.Pair;
 import android.util.Slog;
@@ -391,8 +392,10 @@
     SurfaceControl.ScreenshotHardwareBuffer createTaskSnapshot(@NonNull Task task,
             TaskSnapshot.Builder builder) {
         Point taskSize = new Point();
+        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "createTaskSnapshot");
         final SurfaceControl.ScreenshotHardwareBuffer taskSnapshot = createTaskSnapshot(task,
                 mHighResTaskSnapshotScale, builder.getPixelFormat(), taskSize, builder);
+        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
         builder.setTaskSize(taskSize);
         return taskSnapshot;
     }
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index f6f9020..c27a3d3 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -27,6 +27,7 @@
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS;
@@ -45,6 +46,7 @@
 import static android.view.WindowManager.transitTypeToString;
 import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
 import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
+import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD;
 import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_OCCLUDES_KEYGUARD;
@@ -52,6 +54,8 @@
 import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
 import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
 
+import static com.android.server.wm.ActivityRecord.State.RESUMED;
+import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
 
@@ -127,12 +131,18 @@
      */
     private static final int STATE_ABORT = 3;
 
+    /**
+     * This transition has finished playing successfully.
+     */
+    private static final int STATE_FINISHED = 4;
+
     @IntDef(prefix = { "STATE_" }, value = {
             STATE_PENDING,
             STATE_COLLECTING,
             STATE_STARTED,
             STATE_PLAYING,
-            STATE_ABORT
+            STATE_ABORT,
+            STATE_FINISHED
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface TransitionState {}
@@ -198,6 +208,8 @@
         mFlags = flags;
         mController = controller;
         mSyncEngine = syncEngine;
+
+        controller.mTransitionTracer.logState(this);
     }
 
     void addFlag(int flag) {
@@ -210,10 +222,28 @@
             mTransientLaunches = new ArrayMap<>();
         }
         mTransientLaunches.put(activity, restoreBelow);
+        setTransientLaunchToChanges(activity);
+
+        if (restoreBelow != null) {
+            final ChangeInfo info = mChanges.get(restoreBelow);
+            if (info != null) {
+                info.mFlags |= ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH;
+            }
+        }
         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Transition %d: Set %s as "
                 + "transient-launch", mSyncId, activity);
     }
 
+    boolean isTransientHide(@NonNull Task task) {
+        if (mTransientLaunches == null) return false;
+        for (int i = 0; i < mTransientLaunches.size(); ++i) {
+            if (mTransientLaunches.valueAt(i) == task) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     boolean isTransientLaunch(@NonNull ActivityRecord activity) {
         return mTransientLaunches != null && mTransientLaunches.containsKey(activity);
     }
@@ -238,6 +268,25 @@
         info.mFlags = info.mFlags | ChangeInfo.FLAG_SEAMLESS_ROTATION;
     }
 
+    /**
+     * Only set flag to the parent tasks and activity itself.
+     */
+    private void setTransientLaunchToChanges(@NonNull WindowContainer wc) {
+        for (WindowContainer curr = wc; curr != null && mChanges.containsKey(curr);
+                curr = curr.getParent()) {
+            if (curr.asTask() == null && curr.asActivityRecord() == null) {
+                return;
+            }
+            final ChangeInfo info = mChanges.get(curr);
+            info.mFlags = info.mFlags | ChangeInfo.FLAG_TRANSIENT_LAUNCH;
+        }
+    }
+
+    @TransitionState
+    int getState() {
+        return mState;
+    }
+
     @VisibleForTesting
     int getSyncId() {
         return mSyncId;
@@ -248,6 +297,20 @@
         return mFlags;
     }
 
+    @VisibleForTesting
+    SurfaceControl.Transaction getStartTransaction() {
+        return mStartTransaction;
+    }
+
+    @VisibleForTesting
+    SurfaceControl.Transaction getFinishTransaction() {
+        return mFinishTransaction;
+    }
+
+    private boolean isCollecting() {
+        return mState == STATE_COLLECTING || mState == STATE_STARTED;
+    }
+
     /** Starts collecting phase. Once this starts, all relevant surface operations are sync. */
     void startCollecting(long timeoutMs) {
         if (mState != STATE_PENDING) {
@@ -255,6 +318,8 @@
         }
         mState = STATE_COLLECTING;
         mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, TAG);
+
+        mController.mTransitionTracer.logState(this);
     }
 
     /**
@@ -272,6 +337,8 @@
         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Starting Transition %d",
                 mSyncId);
         applyReady();
+
+        mController.mTransitionTracer.logState(this);
     }
 
     /**
@@ -281,7 +348,10 @@
         if (mState < STATE_COLLECTING) {
             throw new IllegalStateException("Transition hasn't started collecting.");
         }
-        if (mSyncId < 0) return;
+        if (!isCollecting()) {
+            // Too late, transition already started playing, so don't collect.
+            return;
+        }
         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Collecting in transition %d: %s",
                 mSyncId, wc);
         // "snapshot" all parents (as potential promotion targets). Do this before checking
@@ -296,7 +366,12 @@
             }
         }
         if (mParticipants.contains(wc)) return;
-        mSyncEngine.addToSyncSet(mSyncId, wc);
+        // Wallpaper is like in a static drawn state unless display may have changes, so exclude
+        // the case to reduce transition latency waiting for the unchanged wallpaper to redraw.
+        final boolean needSyncDraw = !isWallpaper(wc) || mParticipants.contains(wc.mDisplayContent);
+        if (needSyncDraw) {
+            mSyncEngine.addToSyncSet(mSyncId, wc);
+        }
         ChangeInfo info = mChanges.get(wc);
         if (info == null) {
             info = new ChangeInfo(wc);
@@ -326,7 +401,10 @@
      * or waiting until after the animation to close).
      */
     void collectExistenceChange(@NonNull WindowContainer wc) {
-        if (mSyncId < 0) return;
+        if (mState >= STATE_PLAYING) {
+            // Too late to collect. Don't check too-early here since `collect` will check that.
+            return;
+        }
         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Existence Changed in transition %d:"
                 + " %s", mSyncId, wc);
         collect(wc);
@@ -360,7 +438,7 @@
      */
     void setOverrideAnimation(TransitionInfo.AnimationOptions options,
             @Nullable IRemoteCallback startCallback, @Nullable IRemoteCallback finishCallback) {
-        if (mSyncId < 0) return;
+        if (!isCollecting()) return;
         mOverrideOptions = options;
         sendRemoteCallback(mClientAnimationStartCallback);
         mClientAnimationStartCallback = startCallback;
@@ -378,7 +456,7 @@
      *           The transition will wait for all groups to be ready.
      */
     void setReady(WindowContainer wc, boolean ready) {
-        if (mSyncId < 0) return;
+        if (!isCollecting() || mSyncId < 0) return;
         mReadyTracker.setReadyFrom(wc, ready);
         applyReady();
     }
@@ -396,7 +474,7 @@
      * @see ReadyTracker#setAllReady.
      */
     void setAllReady() {
-        if (mSyncId < 0) return;
+        if (!isCollecting() || mSyncId < 0) return;
         mReadyTracker.setAllReady();
         applyReady();
     }
@@ -419,7 +497,7 @@
         for (int i = mTargets.size() - 1; i >= 0; --i) {
             final WindowContainer target = mTargets.get(i);
             if (target.getParent() != null) {
-                final SurfaceControl targetLeash = getLeashSurface(target);
+                final SurfaceControl targetLeash = getLeashSurface(target, null /* t */);
                 final SurfaceControl origParent = getOrigParentSurface(target);
                 // Ensure surfaceControls are re-parented back into the hierarchy.
                 t.reparent(targetLeash, origParent);
@@ -428,14 +506,10 @@
                 t.setPosition(targetLeash, tmpPos.x, tmpPos.y);
                 final Rect clipRect;
                 // No need to clip the display in case seeing the clipped content when during the
-                // display rotation.
-                if (target.asDisplayContent() != null) {
+                // display rotation. No need to clip activities because they rely on clipping on
+                // task layers.
+                if (target.asDisplayContent() != null || target.asActivityRecord() != null) {
                     clipRect = null;
-                } else if (target.asActivityRecord() != null) {
-                    // Always use parent bounds of activity because letterbox area (e.g. fixed
-                    // aspect ratio or size compat mode) should be included.
-                    clipRect = target.getParent().getRequestedOverrideBounds();
-                    clipRect.offset(-tmpPos.x, -tmpPos.y);
                 } else {
                     clipRect = target.getRequestedOverrideBounds();
                     clipRect.offset(-tmpPos.x, -tmpPos.y);
@@ -474,6 +548,58 @@
         mCanPipOnFinish = canPipOnFinish;
     }
 
+    private boolean didCommitTransientLaunch() {
+        if (mTransientLaunches == null) return false;
+        for (int j = 0; j < mTransientLaunches.size(); ++j) {
+            if (mTransientLaunches.keyAt(j).isVisibleRequested()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check if pip-entry is possible after finishing and enter-pip if it is.
+     *
+     * @return true if we are *guaranteed* to enter-pip. This means we return false if there's
+     *         a chance we won't thus legacy-entry (via pause+userLeaving) will return false.
+     */
+    private boolean checkEnterPipOnFinish(@NonNull ActivityRecord ar) {
+        if (!mCanPipOnFinish || !ar.isVisible() || ar.getTask() == null) return false;
+
+        if (ar.pictureInPictureArgs != null && ar.pictureInPictureArgs.isAutoEnterEnabled()) {
+            if (didCommitTransientLaunch()) {
+                // force enable pip-on-task-switch now that we've committed to actually launching
+                // to the transient activity.
+                ar.supportsEnterPipOnTaskSwitch = true;
+            }
+            return mController.mAtm.enterPictureInPictureMode(ar, ar.pictureInPictureArgs,
+                    false /* fromClient */);
+        }
+
+        // Legacy pip-entry (not via isAutoEnterEnabled).
+        boolean canPip = ar.getDeferHidingClient();
+        if (!canPip && didCommitTransientLaunch()) {
+            // force enable pip-on-task-switch now that we've committed to actually launching to the
+            // transient activity, and then recalculate whether we can attempt pip.
+            ar.supportsEnterPipOnTaskSwitch = true;
+            canPip = ar.checkEnterPictureInPictureState(
+                    "finishTransition", true /* beforeStopping */)
+                    && ar.isState(RESUMED);
+        }
+        if (!canPip) return false;
+        try {
+            // Legacy PIP-enter requires pause event with user-leaving.
+            mController.mAtm.mTaskSupervisor.mUserLeaving = true;
+            ar.getTaskFragment().startPausing(false /* uiSleeping */,
+                    null /* resuming */, "finishTransition");
+        } finally {
+            mController.mAtm.mTaskSupervisor.mUserLeaving = false;
+        }
+        // Return false anyway because there's no guarantee that the app will enter pip.
+        return false;
+    }
+
     /**
      * The transition has finished animating and is ready to finalize WM state. This should not
      * be called directly; use {@link TransitionController#finishTransition} instead.
@@ -489,7 +615,6 @@
         }
 
         // Commit all going-invisible containers
-        boolean activitiesWentInvisible = false;
         for (int i = 0; i < mParticipants.size(); ++i) {
             final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
             if (ar != null) {
@@ -501,32 +626,9 @@
                 // then doing commitVisibility here would actually be out-of-order and leave the
                 // activity in a bad state.
                 if (!visibleAtTransitionEnd && !ar.isVisibleRequested()) {
-                    boolean commitVisibility = true;
-                    if (mCanPipOnFinish && ar.isVisible() && ar.getTask() != null) {
-                        if (ar.pictureInPictureArgs != null
-                                && ar.pictureInPictureArgs.isAutoEnterEnabled()) {
-                            if (mTransientLaunches != null) {
-                                for (int j = 0; j < mTransientLaunches.size(); ++j) {
-                                    if (mTransientLaunches.keyAt(j).isVisibleRequested()) {
-                                        // force enable pip-on-task-switch now that we've committed
-                                        // to actually launching to the transient activity.
-                                        ar.supportsEnterPipOnTaskSwitch = true;
-                                        break;
-                                    }
-                                }
-                            }
-                            mController.mAtm.enterPictureInPictureMode(ar, ar.pictureInPictureArgs);
-                            // Avoid commit visibility to false here, or else we will get a sudden
-                            // "flash" / surface going invisible for a split second.
-                            commitVisibility = false;
-                        } else if (ar.getDeferHidingClient()) {
-                            // Legacy PIP-enter requires pause event with user-leaving.
-                            mController.mAtm.mTaskSupervisor.mUserLeaving = true;
-                            ar.getTaskFragment().startPausing(false /* uiSleeping */,
-                                    null /* resuming */, "finishTransition");
-                            mController.mAtm.mTaskSupervisor.mUserLeaving = false;
-                        }
-                    }
+                    final boolean commitVisibility = !checkEnterPipOnFinish(ar);
+                    // Avoid commit visibility if entering pip or else we will get a sudden
+                    // "flash" / surface going invisible for a split second.
                     if (commitVisibility) {
                         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                                 "  Commit activity becoming invisible: %s", ar);
@@ -540,7 +642,6 @@
                         }
                         ar.commitVisibility(false /* visible */, false /* performLayout */,
                                 true /* fromTransition */);
-                        activitiesWentInvisible = true;
                     }
                 }
                 if (mChanges.get(ar).mVisible != visibleAtTransitionEnd) {
@@ -567,12 +668,23 @@
                 mController.dispatchLegacyAppTransitionFinished(ar);
             }
         }
-        if (activitiesWentInvisible) {
-            // Always schedule stop processing when transition finishes because activities don't
-            // stop while they are in a transition thus their stop could still be pending.
-            mController.mAtm.mTaskSupervisor
-                    .scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
+
+        // Update the input-sink (touch-blocking) state now that the animation is finished.
+        SurfaceControl.Transaction inputSinkTransaction = null;
+        for (int i = 0; i < mParticipants.size(); ++i) {
+            final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
+            if (ar == null || !ar.isVisible()) continue;
+            if (inputSinkTransaction == null) {
+                inputSinkTransaction = new SurfaceControl.Transaction();
+            }
+            ar.mActivityRecordInputSink.applyChangesToSurfaceIfChanged(inputSinkTransaction);
         }
+        if (inputSinkTransaction != null) inputSinkTransaction.apply();
+
+        // Always schedule stop processing when transition finishes because activities don't
+        // stop while they are in a transition thus their stop could still be pending.
+        mController.mAtm.mTaskSupervisor
+                .scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
 
         sendRemoteCallback(mClientAnimationFinishCallback);
 
@@ -614,6 +726,9 @@
             dc.removeImeSurfaceImmediately();
             dc.handleCompleteDeferredRemoval();
         }
+
+        mState = STATE_FINISHED;
+        mController.mTransitionTracer.logState(this);
     }
 
     void abort() {
@@ -667,6 +782,8 @@
         }
 
         mState = STATE_PLAYING;
+        mStartTransaction = transaction;
+        mFinishTransaction = mController.mAtm.mWindowManager.mTransactionFactory.get();
         mController.moveToPlaying(this);
 
         if (dc.isKeyguardLocked()) {
@@ -675,7 +792,8 @@
 
         // Resolve the animating targets from the participants
         mTargets = calculateTargets(mParticipants, mChanges);
-        final TransitionInfo info = calculateTransitionInfo(mType, mFlags, mTargets, mChanges);
+        final TransitionInfo info = calculateTransitionInfo(mType, mFlags, mTargets, mChanges,
+                transaction);
         if (mOverrideOptions != null) {
             info.setAnimationOptions(mOverrideOptions);
         }
@@ -685,8 +803,6 @@
 
         handleNonAppWindowsInTransition(dc, mType, mFlags);
 
-        reportStartReasonsToLogger();
-
         // The callback is only populated for custom activity-level client animations
         sendRemoteCallback(mClientAnimationStartCallback);
 
@@ -728,6 +844,9 @@
         for (int i = mParticipants.size() - 1; i >= 0; --i) {
             final WindowContainer wc = mParticipants.valueAt(i);
             if (wc.asWindowToken() == null || !wc.isVisibleRequested()) continue;
+            // don't include transient launches, though, since those are only temporarily visible.
+            if (mTransientLaunches != null && wc.asActivityRecord() != null
+                    && mTransientLaunches.containsKey(wc.asActivityRecord())) continue;
             mVisibleAtTransitionEndTokens.add(wc.asWindowToken());
         }
 
@@ -750,8 +869,6 @@
         if (controller != null && mTargets.contains(dc)) {
             controller.setupStartTransaction(transaction);
         }
-        mStartTransaction = transaction;
-        mFinishTransaction = mController.mAtm.mWindowManager.mTransactionFactory.get();
         buildFinishTransaction(mFinishTransaction, info.getRootLeash());
         if (mController.getTransitionPlayer() != null) {
             mController.dispatchLegacyAppTransitionStarting(info);
@@ -773,8 +890,9 @@
             // No player registered, so just finish/apply immediately
             cleanUpOnFailure();
         }
-        mSyncId = -1;
         mOverrideOptions = null;
+
+        reportStartReasonsToLogger();
     }
 
     /**
@@ -987,11 +1105,15 @@
         for (int i = mParticipants.size() - 1; i >= 0; --i) {
             ActivityRecord r = mParticipants.valueAt(i).asActivityRecord();
             if (r == null || !r.mVisibleRequested) continue;
+            int transitionReason = APP_TRANSITION_WINDOWS_DRAWN;
             // At this point, r is "ready", but if it's not "ALL ready" then it is probably only
             // ready due to starting-window.
-            reasons.put(r, (r.mStartingData instanceof SplashScreenStartingData
-                    && !r.mLastAllReadyAtSync)
-                    ? APP_TRANSITION_SPLASH_SCREEN : APP_TRANSITION_WINDOWS_DRAWN);
+            if (r.mStartingData instanceof SplashScreenStartingData && !r.mLastAllReadyAtSync) {
+                transitionReason = APP_TRANSITION_SPLASH_SCREEN;
+            } else if (r.isActivityTypeHomeOrRecents() && isTransientLaunch(r)) {
+                transitionReason = APP_TRANSITION_RECENTS_ANIM;
+            }
+            reasons.put(r, transitionReason);
         }
         mController.mAtm.mTaskSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
                 reasons);
@@ -1020,6 +1142,10 @@
         return wc.asWallpaperToken() != null;
     }
 
+    private static boolean isInputMethod(WindowContainer wc) {
+        return wc.getWindowType() == TYPE_INPUT_METHOD;
+    }
+
     private static boolean occludesKeyguard(WindowContainer wc) {
         final ActivityRecord ar = wc.asActivityRecord();
         if (ar != null) {
@@ -1226,8 +1352,15 @@
         }
     }
 
-    /** Gets the leash surface for a window container */
-    private static SurfaceControl getLeashSurface(WindowContainer wc) {
+    /**
+     * Gets the leash surface for a window container.
+     * @param t a transaction to create leashes on when necessary (fixed rotation at token-level).
+     *          If t is null, then this will not create any leashes, just use one if it is there --
+     *          this is relevant for building the finishTransaction since it needs to match the
+     *          start state and not erroneously create a leash of its own.
+     */
+    private static SurfaceControl getLeashSurface(WindowContainer wc,
+            @Nullable SurfaceControl.Transaction t) {
         final DisplayContent asDC = wc.asDisplayContent();
         if (asDC != null) {
             // DisplayContent is the "root", so we use the windowing layer instead to avoid
@@ -1239,7 +1372,8 @@
             if (asToken != null) {
                 // WindowTokens can have a fixed-rotation applied to them. In the current
                 // implementation this fact is hidden from the player, so we must create a leash.
-                final SurfaceControl leash = asToken.getOrCreateFixedRotationLeash();
+                final SurfaceControl leash = t != null ? asToken.getOrCreateFixedRotationLeash(t)
+                        : asToken.getFixedRotationLeash();
                 if (leash != null) return leash;
             }
         }
@@ -1268,12 +1402,14 @@
      * Construct a TransitionInfo object from a set of targets and changes. Also populates the
      * root surface.
      * @param sortedTargets The targets sorted by z-order from top (index 0) to bottom.
+     * @param startT The start transaction - used to set-up new leashes.
      */
     @VisibleForTesting
     @NonNull
     static TransitionInfo calculateTransitionInfo(@TransitionType int type, int flags,
             ArrayList<WindowContainer> sortedTargets,
-            ArrayMap<WindowContainer, ChangeInfo> changes) {
+            ArrayMap<WindowContainer, ChangeInfo> changes,
+            @Nullable SurfaceControl.Transaction startT) {
         final TransitionInfo out = new TransitionInfo(type, flags);
 
         WindowContainer<?> topApp = null;
@@ -1311,10 +1447,7 @@
         }
         final SurfaceControl rootLeash = leashReference.makeAnimationLeash().setName(
                 "Transition Root: " + leashReference.getName()).build();
-        SurfaceControl.Transaction t = ancestor.mWmService.mTransactionFactory.get();
-        t.setLayer(rootLeash, leashReference.getLastLayer());
-        t.apply();
-        t.close();
+        startT.setLayer(rootLeash, leashReference.getLastLayer());
         out.setRootLeash(rootLeash, ancestor.getBounds().left, ancestor.getBounds().top);
 
         // Convert all the resolved ChangeInfos into TransactionInfo.Change objects in order.
@@ -1324,7 +1457,7 @@
             final ChangeInfo info = changes.get(target);
             final TransitionInfo.Change change = new TransitionInfo.Change(
                     target.mRemoteToken != null ? target.mRemoteToken.toWindowContainerToken()
-                            : null, getLeashSurface(target));
+                            : null, getLeashSurface(target, startT));
             // TODO(shell-transitions): Use leash for non-organized windows.
             if (info.mParent != null) {
                 change.setParent(info.mParent.mRemoteToken.toWindowContainerToken());
@@ -1481,7 +1614,7 @@
     }
 
     boolean getLegacyIsReady() {
-        return (mState == STATE_STARTED || mState == STATE_COLLECTING) && mSyncId >= 0;
+        return isCollecting() && mSyncId >= 0;
     }
 
     static Transition fromBinder(IBinder binder) {
@@ -1497,10 +1630,14 @@
          * seamless rotation. This is currently only used by DisplayContent during fixed-rotation.
          */
         private static final int FLAG_SEAMLESS_ROTATION = 1;
+        private static final int FLAG_TRANSIENT_LAUNCH = 2;
+        private static final int FLAG_ABOVE_TRANSIENT_LAUNCH = 4;
 
         @IntDef(prefix = { "FLAG_" }, value = {
                 FLAG_NONE,
-                FLAG_SEAMLESS_ROTATION
+                FLAG_SEAMLESS_ROTATION,
+                FLAG_TRANSIENT_LAUNCH,
+                FLAG_ABOVE_TRANSIENT_LAUNCH
         })
         @Retention(RetentionPolicy.SOURCE)
         @interface Flag {}
@@ -1537,6 +1674,11 @@
         }
 
         boolean hasChanged(@NonNull WindowContainer newState) {
+            // the task including transient launch must promote to root task
+            if ((mFlags & ChangeInfo.FLAG_TRANSIENT_LAUNCH) != 0
+                    || (mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) {
+                return true;
+            }
             // If it's invisible and hasn't changed visibility, always return false since even if
             // something changed, it wouldn't be a visible change.
             final boolean currVisible = newState.isVisibleRequested();
@@ -1552,6 +1694,9 @@
 
         @TransitionInfo.TransitionMode
         int getTransitMode(@NonNull WindowContainer wc) {
+            if ((mFlags & ChangeInfo.FLAG_ABOVE_TRANSIENT_LAUNCH) != 0) {
+                return TRANSIT_CLOSE;
+            }
             final boolean nowVisible = wc.isVisibleRequested();
             if (nowVisible == mVisible) {
                 return TRANSIT_CHANGE;
@@ -1602,6 +1747,9 @@
             if (isWallpaper(wc)) {
                 flags |= FLAG_IS_WALLPAPER;
             }
+            if (isInputMethod(wc)) {
+                flags |= FLAG_IS_INPUT_METHOD;
+            }
             if (occludesKeyguard(wc)) {
                 flags |= FLAG_OCCLUDES_KEYGUARD;
             }
@@ -1610,6 +1758,19 @@
     }
 
     /**
+     * This transition will be considered not-ready until a corresponding call to
+     * {@link #continueTransitionReady}
+     */
+    void deferTransitionReady() {
+        ++mReadyTracker.mDeferReadyDepth;
+    }
+
+    /** This undoes one call to {@link #deferTransitionReady}. */
+    void continueTransitionReady() {
+        --mReadyTracker.mDeferReadyDepth;
+    }
+
+    /**
      * The transition sync mechanism has 2 parts:
      *   1. Whether all WM operations for a particular transition are "ready" (eg. did the app
      *      launch or stop or get a new configuration?).
@@ -1639,6 +1800,14 @@
         private boolean mReadyOverride = false;
 
         /**
+         * When non-zero, this transition is forced not-ready (even over setAllReady()). Use this
+         * (via deferTransitionReady/continueTransitionReady) for situations where we want to do
+         * bulk operations which could trigger surface-placement but the existing ready-state
+         * isn't known.
+         */
+        private int mDeferReadyDepth = 0;
+
+        /**
          * Adds a ready-group. Any setReady calls in this subtree will be tracked together. For
          * now these are only DisplayContents.
          */
@@ -1678,8 +1847,15 @@
         /** @return true if all tracked subtrees are ready. */
         boolean allReady() {
             ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " allReady query: used=%b "
-                    + "override=%b states=[%s]", mUsed, mReadyOverride, groupsToString());
+                    + "override=%b defer=%d states=[%s]", mUsed, mReadyOverride, mDeferReadyDepth,
+                    groupsToString());
+            // If the readiness has never been touched, mUsed will be false. We never want to
+            // consider a transition ready if nothing has been reported on it.
             if (!mUsed) return false;
+            // If we are deferring readiness, we never report ready. This is usually temporary.
+            if (mDeferReadyDepth > 0) return false;
+            // Next check all the ready groups to see if they are ready. We can short-cut this if
+            // ready-override is set (which is treated as "everything is marked ready").
             if (mReadyOverride) return true;
             for (int i = mReadyGroups.size() - 1; i >= 0; --i) {
                 final WindowContainer wc = mReadyGroups.keyAt(i);
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index c1c390e..6d31e93 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -75,6 +75,7 @@
 
     private ITransitionPlayer mTransitionPlayer;
     final TransitionMetricsReporter mTransitionMetricsReporter = new TransitionMetricsReporter();
+    final TransitionTracer mTransitionTracer;
 
     private IApplicationThread mTransitionPlayerThread;
     final ActivityTaskManagerService mAtm;
@@ -100,10 +101,12 @@
     final StatusBarManagerInternal mStatusBar;
 
     TransitionController(ActivityTaskManagerService atm,
-            TaskSnapshotController taskSnapshotController) {
+            TaskSnapshotController taskSnapshotController,
+            TransitionTracer transitionTracer) {
         mAtm = atm;
         mStatusBar = LocalServices.getService(StatusBarManagerInternal.class);
         mTaskSnapshotController = taskSnapshotController;
+        mTransitionTracer = transitionTracer;
         mTransitionPlayerDeath = () -> {
             synchronized (mAtm.mGlobalLock) {
                 // Clean-up/finish any playing transitions.
@@ -207,6 +210,18 @@
     }
 
     /**
+     * @return {@code true} if transition is actively collecting changes and `wc` is one of them
+     *                      or a descendant of one of them. {@code false} once playing.
+     */
+    boolean inCollectingTransition(@NonNull WindowContainer wc) {
+        if (!isCollecting()) return false;
+        for (WindowContainer p = wc; p != null; p = p.getParent()) {
+            if (mCollectingTransition.mParticipants.contains(p)) return true;
+        }
+        return false;
+    }
+
+    /**
      * @return {@code true} if transition is actively playing. This is not necessarily {@code true}
      * during collection.
      */
@@ -214,6 +229,18 @@
         return !mPlayingTransitions.isEmpty();
     }
 
+    /**
+     * @return {@code true} if one of the playing transitions contains `wc`.
+     */
+    boolean inPlayingTransition(@NonNull WindowContainer wc) {
+        for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
+            for (WindowContainer p = wc; p != null; p = p.getParent()) {
+                if (mPlayingTransitions.get(i).mParticipants.contains(p)) return true;
+            }
+        }
+        return false;
+    }
+
     /** @return {@code true} if a transition is running */
     boolean inTransition() {
         // TODO(shell-transitions): eventually properly support multiple
@@ -222,19 +249,7 @@
 
     /** @return {@code true} if a transition is running in a participant subtree of wc */
     boolean inTransition(@NonNull WindowContainer wc) {
-        if (isCollecting()) {
-            for (WindowContainer p = wc; p != null; p = p.getParent()) {
-                if (isCollecting(p)) return true;
-            }
-        }
-        for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
-            for (WindowContainer p = wc; p != null; p = p.getParent()) {
-                if (mPlayingTransitions.get(i).mParticipants.contains(p)) {
-                    return true;
-                }
-            }
-        }
-        return false;
+        return inCollectingTransition(wc) || inPlayingTransition(wc);
     }
 
     boolean inRecentsTransition(@NonNull WindowContainer wc) {
@@ -270,6 +285,16 @@
         return false;
     }
 
+    boolean isTransientHide(@NonNull Task task) {
+        if (mCollectingTransition != null && mCollectingTransition.isTransientHide(task)) {
+            return true;
+        }
+        for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
+            if (mPlayingTransitions.get(i).isTransientHide(task)) return true;
+        }
+        return false;
+    }
+
     /**
      * @return {@code true} if {@param ar} is part of a transient-launch activity in an active
      * transition.
@@ -455,6 +480,24 @@
         setReady(wc, true);
     }
 
+    /** @see Transition#deferTransitionReady */
+    void deferTransitionReady() {
+        if (!isShellTransitionsEnabled()) return;
+        if (mCollectingTransition == null) {
+            throw new IllegalStateException("No collecting transition to defer readiness for.");
+        }
+        mCollectingTransition.deferTransitionReady();
+    }
+
+    /** @see Transition#continueTransitionReady */
+    void continueTransitionReady() {
+        if (!isShellTransitionsEnabled()) return;
+        if (mCollectingTransition == null) {
+            throw new IllegalStateException("No collecting transition to defer readiness for.");
+        }
+        mCollectingTransition.continueTransitionReady();
+    }
+
     /** @see Transition#finishTransition */
     void finishTransition(@NonNull IBinder token) {
         // It is usually a no-op but make sure that the metric consumer is removed.
@@ -484,6 +527,7 @@
             setAnimationRunning(true /* running */);
         }
         mPlayingTransitions.add(transition);
+        mTransitionTracer.logState(transition);
     }
 
     private void setAnimationRunning(boolean running) {
@@ -502,6 +546,7 @@
         }
         transition.abort();
         mCollectingTransition = null;
+        mTransitionTracer.logState(transition);
     }
 
     /**
@@ -526,6 +571,12 @@
         }
     }
 
+    /** @see Transition#setCanPipOnFinish */
+    void setCanPipOnFinish(boolean canPipOnFinish) {
+        if (mCollectingTransition == null) return;
+        mCollectingTransition.setCanPipOnFinish(canPipOnFinish);
+    }
+
     void legacyDetachNavigationBarFromApp(@NonNull IBinder token) {
         final Transition transition = Transition.fromBinder(token);
         if (transition == null || !mPlayingTransitions.contains(transition)) {
diff --git a/services/core/java/com/android/server/wm/TransitionTracer.java b/services/core/java/com/android/server/wm/TransitionTracer.java
new file mode 100644
index 0000000..c1927d8
--- /dev/null
+++ b/services/core/java/com/android/server/wm/TransitionTracer.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.os.Build.IS_USER;
+
+import static com.android.server.wm.shell.ChangeInfo.CHANGE_FLAGS;
+import static com.android.server.wm.shell.ChangeInfo.HAS_CHANGED;
+import static com.android.server.wm.shell.ChangeInfo.TRANSIT_MODE;
+import static com.android.server.wm.shell.ChangeInfo.WINDOW_IDENTIFIER;
+import static com.android.server.wm.shell.Transition.CHANGE;
+import static com.android.server.wm.shell.Transition.FINISH_TRANSACTION_ID;
+import static com.android.server.wm.shell.Transition.FLAGS;
+import static com.android.server.wm.shell.Transition.ID;
+import static com.android.server.wm.shell.Transition.START_TRANSACTION_ID;
+import static com.android.server.wm.shell.Transition.STATE;
+import static com.android.server.wm.shell.Transition.TIMESTAMP;
+import static com.android.server.wm.shell.Transition.TRANSITION_TYPE;
+import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER;
+import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER_H;
+import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER_L;
+import static com.android.server.wm.shell.TransitionTraceProto.TRANSITION;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.Log;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.util.TraceBuffer;
+import com.android.server.wm.Transition.ChangeInfo;
+import com.android.server.wm.shell.TransitionTraceProto;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * Helper class to collect and dump transition traces.
+ */
+public class TransitionTracer {
+
+    private static final String LOG_TAG = "TransitionTracer";
+
+    /**
+     * Maximum buffer size, currently defined as 5 MB
+     */
+    private static final int BUFFER_CAPACITY = 5120 * 1024; // 5 MB
+    static final String WINSCOPE_EXT = ".winscope";
+    private static final String TRACE_FILE = "/data/misc/wmtrace/transition_trace" + WINSCOPE_EXT;
+    private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
+
+    private final TransitionTraceBuffer mTraceBuffer = new TransitionTraceBuffer();
+
+    private final Object mEnabledLock = new Object();
+    private volatile boolean mEnabled = false;
+
+    private long mTraceStartTimestamp;
+
+    private class TransitionTraceBuffer {
+        private final TraceBuffer mBuffer = new TraceBuffer(BUFFER_CAPACITY);
+
+        private void pushTransitionState(Transition transition) {
+            final ProtoOutputStream outputStream = new ProtoOutputStream();
+            final long transitionEntryToken = outputStream.start(TRANSITION);
+
+            outputStream.write(ID, transition.getSyncId());
+            outputStream.write(TIMESTAMP, SystemClock.elapsedRealtimeNanos());
+            outputStream.write(TRANSITION_TYPE, transition.mType);
+            outputStream.write(STATE, transition.getState());
+            outputStream.write(FLAGS, transition.getFlags());
+            if (transition.getStartTransaction() != null) {
+                outputStream.write(START_TRANSACTION_ID, transition.getStartTransaction().getId());
+            }
+            if (transition.getFinishTransaction() != null) {
+                outputStream.write(FINISH_TRANSACTION_ID,
+                        transition.getFinishTransaction().getId());
+            }
+
+            for (int i = 0; i < transition.mChanges.size(); ++i) {
+                final WindowContainer window = transition.mChanges.keyAt(i);
+                final ChangeInfo changeInfo = transition.mChanges.valueAt(i);
+                writeChange(outputStream, window, changeInfo);
+            }
+
+            outputStream.end(transitionEntryToken);
+
+            mBuffer.add(outputStream);
+        }
+
+        private void writeChange(ProtoOutputStream outputStream, WindowContainer window,
+                ChangeInfo changeInfo) {
+            Trace.beginSection("TransitionProto#addChange");
+            final long changeEntryToken = outputStream.start(CHANGE);
+
+            final int transitMode = changeInfo.getTransitMode(window);
+            final boolean hasChanged = changeInfo.hasChanged(window);
+            final int changeFlags = changeInfo.getChangeFlags(window);
+
+            outputStream.write(TRANSIT_MODE, transitMode);
+            outputStream.write(HAS_CHANGED, hasChanged);
+            outputStream.write(CHANGE_FLAGS, changeFlags);
+            window.writeIdentifierToProto(outputStream, WINDOW_IDENTIFIER);
+
+            outputStream.end(changeEntryToken);
+            Trace.endSection();
+        }
+
+        public void writeToFile(File file, ProtoOutputStream proto) throws IOException {
+            mBuffer.writeTraceToFile(file, proto);
+        }
+
+        public void reset() {
+            mBuffer.resetBuffer();
+        }
+    }
+
+    /**
+     * Records the current state of a transition in the transition trace (if it is running).
+     * @param transition the transition that we want to record the state of.
+     */
+    public void logState(com.android.server.wm.Transition transition) {
+        if (!mEnabled) {
+            return;
+        }
+
+        Log.d(LOG_TAG, "Logging state of transition " + transition);
+        mTraceBuffer.pushTransitionState(transition);
+    }
+
+    /**
+     * Starts collecting transitions for the trace.
+     * If called while a trace is already running, this will reset the trace.
+     */
+    public void startTrace(@Nullable PrintWriter pw) {
+        if (IS_USER) {
+            LogAndPrintln.e(pw, "Tracing is not supported on user builds.");
+            return;
+        }
+        Trace.beginSection("TransitionTracer#startTrace");
+        LogAndPrintln.i(pw, "Starting shell transition trace.");
+        synchronized (mEnabledLock) {
+            mTraceStartTimestamp = SystemClock.elapsedRealtime();
+            mEnabled = true;
+            mTraceBuffer.reset();
+        }
+        Trace.endSection();
+    }
+
+    /**
+     * Stops collecting the transition trace and dump to trace to file.
+     *
+     * Dumps the trace to @link{TRACE_FILE}.
+     */
+    public void stopTrace(@Nullable PrintWriter pw) {
+        stopTrace(pw, new File(TRACE_FILE));
+    }
+
+    /**
+     * Stops collecting the transition trace and dump to trace to file.
+     * @param outputFile The file to dump the transition trace to.
+     */
+    public void stopTrace(@Nullable PrintWriter pw, File outputFile) {
+        if (IS_USER) {
+            LogAndPrintln.e(pw, "Tracing is not supported on user builds.");
+            return;
+        }
+        Trace.beginSection("TransitionTracer#stopTrace");
+        LogAndPrintln.i(pw, "Stopping shell transition trace.");
+        synchronized (mEnabledLock) {
+            if (!mEnabled) {
+                LogAndPrintln.e(pw,
+                        "Error: Tracing can't be stopped because it hasn't been started.");
+                return;
+            }
+
+            mEnabled = false;
+            writeTraceToFileLocked(pw, outputFile);
+        }
+        Trace.endSection();
+    }
+
+    boolean isEnabled() {
+        return mEnabled;
+    }
+
+    private void writeTraceToFileLocked(@Nullable PrintWriter pw, File file) {
+        Trace.beginSection("TransitionTracer#writeTraceToFileLocked");
+        try {
+            ProtoOutputStream proto = new ProtoOutputStream();
+            proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
+            proto.write(TransitionTraceProto.TIMESTAMP, mTraceStartTimestamp);
+            int pid = android.os.Process.myPid();
+            LogAndPrintln.i(pw, "Writing file to " + file.getAbsolutePath()
+                    + " from process " + pid);
+            mTraceBuffer.writeToFile(file, proto);
+        } catch (IOException e) {
+            LogAndPrintln.e(pw, "Unable to write buffer to file", e);
+        }
+        Trace.endSection();
+    }
+
+    private static class LogAndPrintln {
+        private static void i(@Nullable PrintWriter pw, String msg) {
+            Log.i(LOG_TAG, msg);
+            if (pw != null) {
+                pw.println(msg);
+                pw.flush();
+            }
+        }
+
+        private static void e(@Nullable PrintWriter pw, String msg) {
+            Log.e(LOG_TAG, msg);
+            if (pw != null) {
+                pw.println("ERROR: " + msg);
+                pw.flush();
+            }
+        }
+
+        private static void e(@Nullable PrintWriter pw, String msg, @NonNull Exception e) {
+            Log.e(LOG_TAG, msg, e);
+            if (pw != null) {
+                pw.println("ERROR: " + msg + " ::\n " + e);
+                pw.flush();
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
index 5e963cc..41c1e79 100644
--- a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
+++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
@@ -69,6 +69,10 @@
         return mUnknownApps.isEmpty();
     }
 
+    boolean isVisibilityUnknown(ActivityRecord r) {
+        return mUnknownApps.containsKey(r);
+    }
+
     void clear() {
         mUnknownApps.clear();
     }
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index a32a608..6245005 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -21,6 +21,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
 
@@ -181,15 +182,11 @@
             mFindResults.setUseTopWallpaperAsTarget(true);
         }
 
-        final RecentsAnimationController recentsAnimationController =
-                mService.getRecentsAnimationController();
         final boolean animationWallpaper = animatingContainer != null
                 && animatingContainer.getAnimation() != null
                 && animatingContainer.getAnimation().getShowWallpaper();
         final boolean hasWallpaper = w.hasWallpaper() || animationWallpaper;
-        final boolean isRecentsTransitionTarget = (recentsAnimationController != null
-                && recentsAnimationController.isWallpaperVisible(w));
-        if (isRecentsTransitionTarget) {
+        if (isRecentsTransitionTarget(w)) {
             if (DEBUG_WALLPAPER) Slog.v(TAG, "Found recents animation wallpaper target: " + w);
             mFindResults.setWallpaperTarget(w);
             return true;
@@ -213,6 +210,22 @@
         return false;
     };
 
+    private boolean isRecentsTransitionTarget(WindowState w) {
+        if (w.mTransitionController.isShellTransitionsEnabled()) {
+            // Because the recents activity is invisible in background while keyguard is occluded
+            // (the activity window is on screen while keyguard is locked) with recents animation,
+            // the task animating by recents needs to be wallpaper target to make wallpaper visible.
+            // While for unlocked case, because recents activity will be moved to top, it can be
+            // the wallpaper target naturally.
+            return w.mActivityRecord != null && w.mAttrs.type == TYPE_BASE_APPLICATION
+                    && mDisplayContent.isKeyguardLocked()
+                    && w.mTransitionController.isTransientHide(w.getTask());
+        }
+        // The window is either the recents activity or is in the task animating by the recents.
+        final RecentsAnimationController controller = mService.getRecentsAnimationController();
+        return controller != null && controller.isWallpaperVisible(w);
+    }
+
     /**
      * @see #computeLastWallpaperZoomOut()
      */
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index d725718..66cc216 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -48,6 +48,7 @@
 import static com.android.server.wm.IdentifierProto.USER_ID;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -1159,6 +1160,19 @@
     }
 
     /**
+     * Returns {@code true} if self or the parent container of the window is in transition, e.g.
+     * the app or recents transition. This method is only used when legacy and shell transition
+     * have the same condition to check the animation state.
+     */
+    boolean inTransitionSelfOrParent() {
+        if (!mTransitionController.isShellTransitionsEnabled()) {
+            return isAnimating(PARENTS | TRANSITION,
+                    ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS);
+        }
+        return inTransition();
+    }
+
+    /**
      * @return Whether our own container running an animation at the moment.
      */
     final boolean isAnimating() {
@@ -1180,7 +1194,8 @@
         if (!mTransitionController.isShellTransitionsEnabled()) {
             return isAnimating(TRANSITION | CHILDREN, WindowState.EXIT_ANIMATING_TYPES);
         }
-        if (mTransitionController.isCollecting(this)) {
+        // Only check leaf containers because inTransition() includes parent.
+        if (mChildren.isEmpty() && inTransition()) {
             return true;
         }
 
@@ -2679,9 +2694,7 @@
      * will be applied.
      */
     void scheduleAnimation() {
-        if (mParent != null) {
-            mParent.scheduleAnimation();
-        }
+        mWmService.scheduleAnimationLocked();
     }
 
     /**
@@ -2925,18 +2938,34 @@
         getAnimationPosition(mTmpPoint);
         mTmpRect.offsetTo(0, 0);
 
-        final RemoteAnimationController controller =
-                getDisplayContent().mAppTransition.getRemoteAnimationController();
+        final AppTransition appTransition = getDisplayContent().mAppTransition;
+        final RemoteAnimationController controller = appTransition.getRemoteAnimationController();
         final boolean isChanging = AppTransition.isChangeTransitOld(transit) && enter
                 && isChangingAppTransition();
 
         // Delaying animation start isn't compatible with remote animations at all.
         if (controller != null && !mSurfaceAnimator.isAnimationStartDelayed()) {
+            // Here we load App XML in order to read com.android.R.styleable#Animation_showBackdrop.
+            boolean showBackdrop = false;
+            // Optionally set backdrop color if App explicitly provides it through
+            // {@link Activity#overridePendingTransition(int, int, int)}.
+            @ColorInt int backdropColor = 0;
+            if (controller.isFromActivityEmbedding()) {
+                final int animAttr = AppTransition.mapOpenCloseTransitTypes(transit, enter);
+                final Animation a = animAttr != 0
+                        ? appTransition.loadAnimationAttr(lp, animAttr, transit) : null;
+                showBackdrop = a != null && a.getShowBackdrop();
+                backdropColor = appTransition.getNextAppTransitionBackgroundColor();
+            }
             final Rect localBounds = new Rect(mTmpRect);
             localBounds.offsetTo(mTmpPoint.x, mTmpPoint.y);
             final RemoteAnimationController.RemoteAnimationRecord adapters =
-                    controller.createRemoteAnimationRecord(this, mTmpPoint, localBounds,
-                            screenBounds, (isChanging ? mSurfaceFreezer.mFreezeBounds : null));
+                    controller.createRemoteAnimationRecord(
+                            this, mTmpPoint, localBounds, screenBounds,
+                            (isChanging ? mSurfaceFreezer.mFreezeBounds : null), showBackdrop);
+            if (backdropColor != 0) {
+                adapters.setBackDropColor(backdropColor);
+            }
             if (!isChanging) {
                 adapters.setMode(enter
                         ? RemoteAnimationTarget.MODE_OPENING
@@ -3664,10 +3693,6 @@
             mChildren.get(i).finishSync(outMergedTransaction, cancel);
         }
         if (cancel && mSyncGroup != null) mSyncGroup.onCancelSync(this);
-        clearSyncState();
-    }
-
-    void clearSyncState() {
         mSyncState = SYNC_STATE_NONE;
         mSyncGroup = null;
     }
diff --git a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
index 9b6f4d9..b000a98 100644
--- a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
+++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
@@ -33,7 +33,6 @@
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.hardware.HardwareBuffer;
-import android.os.Process;
 import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Builder;
@@ -91,7 +90,7 @@
                 .setBLASTLayer()
                 .setFormat(PixelFormat.TRANSLUCENT)
                 .setMetadata(METADATA_WINDOW_TYPE, mWindowContainer.getWindowingMode())
-                .setMetadata(METADATA_OWNER_UID, Process.myUid())
+                .setMetadata(METADATA_OWNER_UID, WindowManagerService.MY_UID)
                 .setCallsite("WindowContainerThumbnail")
                 .build();
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 52af39e..b5abd32 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -48,6 +48,7 @@
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
 import static android.provider.Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR;
 import static android.provider.Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH;
+import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
@@ -89,6 +90,7 @@
 import static android.view.WindowManager.TRANSIT_NONE;
 import static android.view.WindowManager.TRANSIT_RELAUNCH;
 import static android.view.WindowManagerGlobal.ADD_OKAY;
+import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
 import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_MULTIPLIER;
@@ -238,10 +240,10 @@
 import android.view.Gravity;
 import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.ICrossWindowBlurEnabledListener;
+import android.view.IDisplayChangeWindowController;
 import android.view.IDisplayFoldListener;
 import android.view.IDisplayWindowInsetsController;
 import android.view.IDisplayWindowListener;
-import android.view.IDisplayWindowRotationController;
 import android.view.IInputFilter;
 import android.view.IOnKeyguardExitResult;
 import android.view.IPinnedTaskListener;
@@ -287,6 +289,7 @@
 import android.window.ClientWindowFrames;
 import android.window.ITaskFpsCallback;
 import android.window.TaskSnapshot;
+import android.window.WindowContainerToken;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -397,9 +400,8 @@
 
     private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
 
-    // Used to indicate that if there is already a transition set, it should be preserved when
-    // trying to apply a new one.
-    private static final boolean ALWAYS_KEEP_CURRENT = true;
+    static final int MY_PID = myPid();
+    static final int MY_UID = myUid();
 
     static final int LOGTAG_INPUT_FOCUS = 62001;
 
@@ -460,6 +462,7 @@
     final WindowManagerConstants mConstants;
 
     final WindowTracing mWindowTracing;
+    final TransitionTracer mTransitionTracer;
 
     private final DisplayAreaPolicy.Provider mDisplayAreaPolicyProvider;
 
@@ -682,9 +685,9 @@
     final WallpaperVisibilityListeners mWallpaperVisibilityListeners =
             new WallpaperVisibilityListeners();
 
-    IDisplayWindowRotationController mDisplayRotationController = null;
-    private final DeathRecipient mDisplayRotationControllerDeath =
-            () -> mDisplayRotationController = null;
+    IDisplayChangeWindowController mDisplayChangeController = null;
+    private final DeathRecipient mDisplayChangeControllerDeath =
+            () -> mDisplayChangeController = null;
 
     final DisplayWindowListenerController mDisplayNotificationController;
     final TaskSystemBarsListenerController mTaskSystemBarsListenerController;
@@ -1067,7 +1070,6 @@
 
     Function<SurfaceSession, SurfaceControl.Builder> mSurfaceControlFactory;
     Supplier<SurfaceControl.Transaction> mTransactionFactory;
-    final Supplier<Surface> mSurfaceFactory;
 
     private final SurfaceControl.Transaction mTransaction;
 
@@ -1150,7 +1152,7 @@
             final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
             ActivityTaskManagerService atm) {
         return main(context, im, showBootMsgs, onlyCore, policy, atm,
-                new DisplayWindowSettingsProvider(), SurfaceControl.Transaction::new, Surface::new,
+                new DisplayWindowSettingsProvider(), SurfaceControl.Transaction::new,
                 SurfaceControl.Builder::new);
     }
 
@@ -1163,12 +1165,11 @@
             final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
             ActivityTaskManagerService atm, DisplayWindowSettingsProvider
             displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory,
-            Supplier<Surface> surfaceFactory,
             Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
         final WindowManagerService[] wms = new WindowManagerService[1];
         DisplayThread.getHandler().runWithScissors(() ->
                 wms[0] = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
-                        atm, displayWindowSettingsProvider, transactionFactory, surfaceFactory,
+                        atm, displayWindowSettingsProvider, transactionFactory,
                         surfaceControlFactory), 0);
         return wms[0];
     }
@@ -1178,7 +1179,7 @@
             @Override
             public void run() {
                 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
-                mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
+                mPolicy.init(mContext, WindowManagerService.this);
             }
         }, 0);
     }
@@ -1193,7 +1194,6 @@
             boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
             ActivityTaskManagerService atm, DisplayWindowSettingsProvider
             displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory,
-            Supplier<Surface> surfaceFactory,
             Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
         installLock(this, INDEX_WINDOW);
         mGlobalLock = atm.getGlobalLock();
@@ -1208,8 +1208,7 @@
                 com.android.internal.R.bool.config_hasPermanentDpad);
         mInTouchMode = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_defaultInTouchMode);
-        inputManager.setInTouchMode(
-                mInTouchMode, myPid(), myUid(), /* hasPermission = */ true);
+        inputManager.setInTouchMode(mInTouchMode, MY_PID, MY_UID, true /* hasPermission */);
         mDrawLockTimeoutMillis = context.getResources().getInteger(
                 com.android.internal.R.integer.config_drawLockTimeoutMillis);
         mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
@@ -1233,7 +1232,6 @@
 
         mSurfaceControlFactory = surfaceControlFactory;
         mTransactionFactory = transactionFactory;
-        mSurfaceFactory = surfaceFactory;
         mTransaction = mTransactionFactory.get();
 
         mPolicy = policy;
@@ -1251,6 +1249,7 @@
 
         mWindowTracing = WindowTracing.createDefaultAndStartLooper(this,
                 Choreographer.getInstance());
+        mTransitionTracer = new TransitionTracer();
 
         LocalServices.addService(WindowManagerPolicy.class, mPolicy);
 
@@ -1449,7 +1448,7 @@
     public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
             int displayId, int requestUserId, InsetsVisibilities requestedVisibilities,
             InputChannel outInputChannel, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
+            InsetsSourceControl[] outActiveControls, Rect outAttachedFrame) {
         Arrays.fill(outActiveControls, null);
         int[] appOp = new int[1];
         final boolean isRoundedCornerOverlay = (attrs.privateFlags
@@ -1864,6 +1863,13 @@
 
             outInsetsState.set(win.getCompatInsetsState(), win.isClientLocal());
             getInsetsSourceControls(win, outActiveControls);
+
+            if (win.mLayoutAttached) {
+                outAttachedFrame.set(win.getParentWindow().getCompatFrame());
+            } else {
+                // Make this invalid which indicates a null attached frame.
+                outAttachedFrame.set(0, 0, -1, -1);
+            }
         }
 
         Binder.restoreCallingIdentity(origId);
@@ -2216,6 +2222,20 @@
                         == PackageManager.PERMISSION_GRANTED;
     }
 
+    /**
+     * Returns whether this window can proceed with drawing or needs to retry later.
+     */
+    public boolean cancelDraw(Session session, IWindow client) {
+        synchronized (mGlobalLock) {
+            final WindowState win = windowForClientLocked(session, client, false);
+            if (win == null) {
+                return false;
+            }
+
+            return win.cancelAndRedraw();
+        }
+    }
+
     public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewVisibility, int flags,
             ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
@@ -2232,6 +2252,11 @@
             if (win == null) {
                 return 0;
             }
+
+            if (win.cancelAndRedraw() && win.mPrepareSyncSeqId <= win.mLastSeqIdSentToRelayout) {
+                result |= RELAYOUT_RES_CANCEL_AND_REDRAW;
+            }
+
             final DisplayContent displayContent = win.getDisplayContent();
             final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
 
@@ -2258,9 +2283,21 @@
                     throw new IllegalArgumentException(
                             "Window type can not be changed after the window is added.");
                 }
-                if (!Arrays.equals(win.mAttrs.providesInsetsTypes, attrs.providesInsetsTypes)) {
-                    throw new IllegalArgumentException(
-                            "Insets types can not be changed after the window is added.");
+                if (!(win.mAttrs.providedInsets == null && attrs.providedInsets == null)) {
+                    if (win.mAttrs.providedInsets == null || attrs.providedInsets == null
+                            || (win.mAttrs.providedInsets.length != attrs.providedInsets.length)) {
+                        throw new IllegalArgumentException(
+                                "Insets types can not be changed after the window is added.");
+                    } else {
+                        final int insetsTypes = attrs.providedInsets.length;
+                        for (int i = 0; i < insetsTypes; i++) {
+                            if (win.mAttrs.providedInsets[i].type != attrs.providedInsets[i].type) {
+                                throw new IllegalArgumentException(
+                                        "Insets types can not be changed after the window is "
+                                                + "added.");
+                            }
+                        }
+                    }
                 }
 
                 flagChanges = win.mAttrs.flags ^ attrs.flags;
@@ -2634,29 +2671,6 @@
         return result;
     }
 
-    int updateViewVisibility(Session session, IWindow client, LayoutParams attrs,
-            int viewVisibility, MergedConfiguration outMergedConfiguration,
-            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
-            InsetsSourceControl[] outActiveControls) {
-        // TODO(b/161810301): Finish the implementation.
-        return 0;
-    }
-
-    void updateWindowLayout(Session session, IWindow client, LayoutParams attrs, int flags,
-            ClientWindowFrames clientWindowFrames, int requestedWidth, int requestedHeight) {
-        final long origId = Binder.clearCallingIdentity();
-        synchronized (mGlobalLock) {
-            final WindowState win = windowForClientLocked(session, client, false);
-            if (win == null) {
-                return;
-            }
-            win.setFrames(clientWindowFrames, requestedWidth, requestedHeight);
-
-            // TODO(b/161810301): Finish the implementation.
-        }
-        Binder.restoreCallingIdentity(origId);
-    }
-
     public boolean outOfMemoryWindow(Session session, IWindow client) {
         final long origId = Binder.clearCallingIdentity();
 
@@ -2704,7 +2718,7 @@
     }
 
     boolean checkCallingPermission(String permission, String func, boolean printLog) {
-        if (Binder.getCallingPid() == myPid()) {
+        if (Binder.getCallingPid() == MY_PID) {
             return true;
         }
 
@@ -2864,7 +2878,7 @@
                 // registration in DisplayContent#onParentChanged at DisplayContent initialization.
                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
                 if (dc == null) {
-                    if (Binder.getCallingPid() != myPid()) {
+                    if (Binder.getCallingPid() != MY_PID) {
                         throw new WindowManager.InvalidDisplayException("attachToDisplayContent: "
                                 + "trying to attach to a non-existing display:" + displayId);
                     }
@@ -4260,12 +4274,13 @@
                                 .notifyOnActivityRotation(displayContent.mDisplayId);
                     }
 
-                    final boolean pendingRemoteRotation = rotationChanged
-                            && (displayContent.getDisplayRotation().isWaitingForRemoteRotation()
+                    final boolean pendingRemoteDisplayChange = rotationChanged
+                            && (displayContent.mRemoteDisplayChangeController
+                                    .isWaitingForRemoteDisplayChange()
                             || displayContent.mTransitionController.isCollecting());
                     // Even if alwaysSend, we are waiting for a transition or remote to provide
-                    // rotated configuration, so we can't update configuration yet.
-                    if (!pendingRemoteRotation) {
+                    // updated configuration, so we can't update configuration yet.
+                    if (!pendingRemoteDisplayChange) {
                         if (!rotationChanged || forceRelayout) {
                             displayContent.setLayoutNeeded();
                             layoutNeeded = true;
@@ -4297,17 +4312,17 @@
     }
 
     @Override
-    public void setDisplayWindowRotationController(IDisplayWindowRotationController controller) {
+    public void setDisplayChangeWindowController(IDisplayChangeWindowController controller) {
         mAtmService.enforceTaskPermission("setDisplayWindowRotationController");
         try {
             synchronized (mGlobalLock) {
-                if (mDisplayRotationController != null) {
-                    mDisplayRotationController.asBinder().unlinkToDeath(
-                            mDisplayRotationControllerDeath, 0);
-                    mDisplayRotationController = null;
+                if (mDisplayChangeController != null) {
+                    mDisplayChangeController.asBinder().unlinkToDeath(
+                            mDisplayChangeControllerDeath, 0);
+                    mDisplayChangeController = null;
                 }
-                controller.asBinder().linkToDeath(mDisplayRotationControllerDeath, 0);
-                mDisplayRotationController = controller;
+                controller.asBinder().linkToDeath(mDisplayChangeControllerDeath, 0);
+                mDisplayChangeController = controller;
             }
         } catch (RemoteException e) {
             throw new RuntimeException("Unable to set rotation controller");
@@ -5694,6 +5709,25 @@
         }
     }
 
+    void setSandboxDisplayApis(int displayId, boolean sandboxDisplayApis) {
+        if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
+        }
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+                if (displayContent != null) {
+                    displayContent.setSandboxDisplayApis(sandboxDisplayApis);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     /** The global settings only apply to default display. */
     private boolean applyForcedPropertiesForDefaultDisplay() {
         boolean changed = false;
@@ -5874,6 +5908,21 @@
     }
 
     @Override
+    public void startTransitionTrace() {
+        mTransitionTracer.startTrace(null /* printwriter */);
+    }
+
+    @Override
+    public void stopTransitionTrace() {
+        mTransitionTracer.stopTrace(null /* printwriter */);
+    }
+
+    @Override
+    public boolean isTransitionTraceEnabled() {
+        return mTransitionTracer.isEnabled();
+    }
+
+    @Override
     public boolean registerCrossWindowBlurEnabledListener(
                 ICrossWindowBlurEnabledListener listener) {
         return mBlurController.registerCrossWindowBlurEnabledListener(listener);
@@ -5998,9 +6047,7 @@
 
     /** Note that Locked in this case is on mLayoutToAnim */
     void scheduleAnimationLocked() {
-        if (mAnimator != null) {
-            mAnimator.scheduleAnimation();
-        }
+        mAnimator.scheduleAnimation();
     }
 
     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
@@ -6087,24 +6134,24 @@
         final DisplayContent displayContent = mRoot.getDisplayContent(mFrozenDisplayId);
         final int numOpeningApps;
         final boolean waitingForConfig;
-        final boolean waitingForRemoteRotation;
+        final boolean waitingForRemoteDisplayChange;
         if (displayContent != null) {
             numOpeningApps = displayContent.mOpeningApps.size();
             waitingForConfig = displayContent.mWaitingForConfig;
-            waitingForRemoteRotation =
-                    displayContent.getDisplayRotation().isWaitingForRemoteRotation();
+            waitingForRemoteDisplayChange = displayContent.mRemoteDisplayChangeController
+                    .isWaitingForRemoteDisplayChange();
         } else {
-            waitingForConfig = waitingForRemoteRotation = false;
+            waitingForConfig = waitingForRemoteDisplayChange = false;
             numOpeningApps = 0;
         }
-        if (waitingForConfig || waitingForRemoteRotation || mAppsFreezingScreen > 0
+        if (waitingForConfig || waitingForRemoteDisplayChange || mAppsFreezingScreen > 0
                 || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE
                 || mClientFreezingScreen || numOpeningApps > 0) {
             ProtoLog.d(WM_DEBUG_ORIENTATION, "stopFreezingDisplayLocked: Returning "
-                    + "waitingForConfig=%b, waitingForRemoteRotation=%b, "
+                    + "waitingForConfig=%b, waitingForRemoteDisplayChange=%b, "
                     + "mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, "
                     + "mClientFreezingScreen=%b, mOpeningApps.size()=%d",
-                    waitingForConfig, waitingForRemoteRotation,
+                    waitingForConfig, waitingForRemoteDisplayChange,
                     mAppsFreezingScreen, mWindowsFreezingScreen,
                     mClientFreezingScreen, numOpeningApps);
             return;
@@ -8236,6 +8283,26 @@
         @Override
         public void setContentRecordingSession(@Nullable ContentRecordingSession incomingSession) {
             synchronized (mGlobalLock) {
+                // Allow the controller to handle teardown or a non-task session.
+                if (incomingSession == null
+                        || incomingSession.getContentToRecord() != RECORD_CONTENT_TASK) {
+                    mContentRecordingController.setContentRecordingSessionLocked(incomingSession,
+                            WindowManagerService.this);
+                    return;
+                }
+                // For a task session, find the activity identified by the launch cookie.
+                final WindowContainerToken wct = getTaskWindowContainerTokenForLaunchCookie(
+                        incomingSession.getTokenToRecord());
+                if (wct == null) {
+                    Slog.w(TAG, "Handling a new recording session; unable to find the "
+                            + "WindowContainerToken");
+                    mContentRecordingController.setContentRecordingSessionLocked(null,
+                            WindowManagerService.this);
+                    return;
+                }
+                // Replace the launch cookie in the session details with the task's
+                // WindowContainerToken.
+                incomingSession.setTokenToRecord(wct.asBinder());
                 mContentRecordingController.setContentRecordingSessionLocked(incomingSession,
                         WindowManagerService.this);
             }
@@ -8494,6 +8561,38 @@
     }
 
     /**
+     * Retrieve the {@link WindowContainerToken} of the task that contains the activity started
+     * with the given launch cookie.
+     *
+     * @param launchCookie the launch cookie set on the {@link ActivityOptions} when starting an
+     *                     activity
+     * @return a token representing the task containing the activity started with the given launch
+     * cookie, or {@code null} if the token couldn't be found.
+     */
+    @VisibleForTesting
+    @Nullable
+    WindowContainerToken getTaskWindowContainerTokenForLaunchCookie(@NonNull IBinder launchCookie) {
+        // Find the activity identified by the launch cookie.
+        final ActivityRecord targetActivity = mRoot.getActivity(
+                activity -> activity.mLaunchCookie == launchCookie);
+        if (targetActivity == null) {
+            Slog.w(TAG, "Unable to find the activity for this launch cookie");
+            return null;
+        }
+        if (targetActivity.getTask() == null) {
+            Slog.w(TAG, "Unable to find the task for this launch cookie");
+            return null;
+        }
+        WindowContainerToken taskWindowContainerToken =
+                targetActivity.getTask().mRemoteToken.toWindowContainerToken();
+        if (taskWindowContainerToken == null) {
+            Slog.w(TAG, "Unable to find the WindowContainerToken for " + targetActivity.getName());
+            return null;
+        }
+        return taskWindowContainerToken;
+    }
+
+    /**
      * You need ALLOW_SLIPPERY_TOUCHES permission to be able to set FLAG_SLIPPERY.
      */
     private int sanitizeFlagSlippery(int flags, String windowName, int callingUid, int callingPid) {
@@ -8753,7 +8852,7 @@
     @Override
     public boolean getWindowInsets(WindowManager.LayoutParams attrs, int displayId,
             InsetsState outInsetsState) {
-        final boolean fromLocal = Binder.getCallingPid() == myPid();
+        final boolean fromLocal = Binder.getCallingPid() == MY_PID;
         final int uid = Binder.getCallingUid();
         final long origId = Binder.clearCallingIdentity();
         try {
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 34c9348..ff43a96 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -19,6 +19,19 @@
 import static android.os.Build.IS_USER;
 import static android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED;
 
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
+import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
+
+import android.content.res.Resources.NotFoundException;
+import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.ParcelFileDescriptor;
@@ -36,6 +49,9 @@
 import com.android.internal.protolog.ProtoLogImpl;
 import com.android.server.LocalServices;
 import com.android.server.statusbar.StatusBarManagerInternal;
+import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
+import com.android.server.wm.LetterboxConfiguration.LetterboxHorizontalReachabilityPosition;
+import com.android.server.wm.LetterboxConfiguration.LetterboxVerticalReachabilityPosition;
 
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -58,10 +74,12 @@
 
     // Internal service impl -- must perform security checks before touching.
     private final WindowManagerService mInternal;
+    private final LetterboxConfiguration mLetterboxConfiguration;
 
     public WindowManagerShellCommand(WindowManagerService service) {
         mInterface = service;
         mInternal = service;
+        mLetterboxConfiguration = service.mLetterboxConfiguration;
     }
 
     @Override
@@ -113,6 +131,14 @@
                     return runGetIgnoreOrientationRequest(pw);
                 case "dump-visible-window-views":
                     return runDumpVisibleWindowViews(pw);
+                case "set-letterbox-style":
+                    return runSetLetterboxStyle(pw);
+                case "get-letterbox-style":
+                    return runGetLetterboxStyle(pw);
+                case "reset-letterbox-style":
+                    return runResetLetterboxStyle(pw);
+                case "set-sandbox-display-apis":
+                    return runSandboxDisplayApis(pw);
                 case "set-multi-window-config":
                     return runSetMultiWindowConfig();
                 case "get-multi-window-config":
@@ -123,6 +149,8 @@
                     return runReset(pw);
                 case "disable-blur":
                     return runSetBlurDisabled(pw);
+                case "shell":
+                    return runWmShellCommand(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -331,6 +359,37 @@
         return 0;
     }
 
+    /**
+     * Override display size and metrics to reflect the DisplayArea of the calling activity.
+     */
+    private int runSandboxDisplayApis(PrintWriter pw) throws RemoteException {
+        int displayId = Display.DEFAULT_DISPLAY;
+        String arg = getNextArgRequired();
+        if ("-d".equals(arg)) {
+            displayId = Integer.parseInt(getNextArgRequired());
+            arg = getNextArgRequired();
+        }
+
+        final boolean sandboxDisplayApis;
+        switch (arg) {
+            case "true":
+            case "1":
+                sandboxDisplayApis = true;
+                break;
+            case "false":
+            case "0":
+                sandboxDisplayApis = false;
+                break;
+            default:
+                getErrPrintWriter().println("Error: expecting true, 1, false, 0, but we "
+                        + "get " + arg);
+                return -1;
+        }
+
+        mInternal.setSandboxDisplayApis(displayId, sandboxDisplayApis);
+        return 0;
+    }
+
     private int runDismissKeyguard(PrintWriter pw) throws RemoteException {
         mInterface.dismissKeyguard(null /* callback */, null /* message */);
         return 0;
@@ -553,6 +612,497 @@
         return 0;
     }
 
+    private int runSetFixedOrientationLetterboxAspectRatio(PrintWriter pw) throws RemoteException {
+        final float aspectRatio;
+        try {
+            String arg = getNextArgRequired();
+            aspectRatio = Float.parseFloat(arg);
+        } catch (NumberFormatException  e) {
+            getErrPrintWriter().println("Error: bad aspect ratio format " + e);
+            return -1;
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: aspect ratio should be provided as an argument " + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(aspectRatio);
+        }
+        return 0;
+    }
+
+    private int runSetDefaultMinAspectRatioForUnresizableApps(PrintWriter pw)
+            throws RemoteException {
+        final float aspectRatio;
+        try {
+            String arg = getNextArgRequired();
+            aspectRatio = Float.parseFloat(arg);
+        } catch (NumberFormatException  e) {
+            getErrPrintWriter().println("Error: bad aspect ratio format " + e);
+            return -1;
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: aspect ratio should be provided as an argument " + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setDefaultMinAspectRatioForUnresizableApps(aspectRatio);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxActivityCornersRadius(PrintWriter pw) throws RemoteException {
+        final int cornersRadius;
+        try {
+            String arg = getNextArgRequired();
+            cornersRadius = Integer.parseInt(arg);
+        } catch (NumberFormatException  e) {
+            getErrPrintWriter().println("Error: bad corners radius format " + e);
+            return -1;
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: corners radius should be provided as an argument " + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setLetterboxActivityCornersRadius(cornersRadius);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxBackgroundType(PrintWriter pw) throws RemoteException {
+        @LetterboxBackgroundType final int backgroundType;
+        try {
+            String arg = getNextArgRequired();
+            switch (arg) {
+                case "solid_color":
+                    backgroundType = LETTERBOX_BACKGROUND_SOLID_COLOR;
+                    break;
+                case "app_color_background":
+                    backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
+                    break;
+                case "app_color_background_floating":
+                    backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
+                    break;
+                case "wallpaper":
+                    backgroundType = LETTERBOX_BACKGROUND_WALLPAPER;
+                    break;
+                default:
+                    getErrPrintWriter().println(
+                            "Error: 'solid_color', 'app_color_background' or "
+                            + "'wallpaper' should be provided as an argument");
+                    return -1;
+            }
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: 'solid_color', 'app_color_background' or "
+                        + "'wallpaper' should be provided as an argument" + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setLetterboxBackgroundType(backgroundType);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxBackgroundColorResource(PrintWriter pw) throws RemoteException {
+        final int colorId;
+        try {
+            String arg = getNextArgRequired();
+            colorId = mInternal.mContext.getResources()
+                    .getIdentifier(arg, "color", "com.android.internal");
+        } catch (NotFoundException e) {
+            getErrPrintWriter().println(
+                    "Error: color in '@android:color/resource_name' format should be provided as "
+                            + "an argument " + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setLetterboxBackgroundColorResourceId(colorId);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxBackgroundColor(PrintWriter pw) throws RemoteException {
+        final Color color;
+        try {
+            String arg = getNextArgRequired();
+            color = Color.valueOf(Color.parseColor(arg));
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: color in #RRGGBB format should be provided as "
+                            + "an argument " + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setLetterboxBackgroundColor(color);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxBackgroundWallpaperBlurRadius(PrintWriter pw)
+            throws RemoteException {
+        final int radius;
+        try {
+            String arg = getNextArgRequired();
+            radius = Integer.parseInt(arg);
+        } catch (NumberFormatException  e) {
+            getErrPrintWriter().println("Error: blur radius format " + e);
+            return -1;
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: blur radius should be provided as an argument " + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setLetterboxBackgroundWallpaperBlurRadius(radius);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxBackgroundWallpaperDarkScrimAlpha(PrintWriter pw)
+            throws RemoteException {
+        final float alpha;
+        try {
+            String arg = getNextArgRequired();
+            alpha = Float.parseFloat(arg);
+        } catch (NumberFormatException  e) {
+            getErrPrintWriter().println("Error: bad alpha format " + e);
+            return -1;
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: alpha should be provided as an argument " + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setLetterboxBackgroundWallpaperDarkScrimAlpha(alpha);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxHorizontalPositionMultiplier(PrintWriter pw) throws RemoteException {
+        final float multiplier;
+        try {
+            String arg = getNextArgRequired();
+            multiplier = Float.parseFloat(arg);
+        } catch (NumberFormatException  e) {
+            getErrPrintWriter().println("Error: bad multiplier format " + e);
+            return -1;
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: multiplier should be provided as an argument " + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(multiplier);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxVerticalPositionMultiplier(PrintWriter pw) throws RemoteException {
+        final float multiplier;
+        try {
+            String arg = getNextArgRequired();
+            multiplier = Float.parseFloat(arg);
+        } catch (NumberFormatException  e) {
+            getErrPrintWriter().println("Error: bad multiplier format " + e);
+            return -1;
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: multiplier should be provided as an argument " + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(multiplier);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxIsHorizontalReachabilityEnabled(PrintWriter pw)
+            throws RemoteException {
+        String arg = getNextArg();
+        final boolean enabled;
+        switch (arg) {
+            case "true":
+            case "1":
+                enabled = true;
+                break;
+            case "false":
+            case "0":
+                enabled = false;
+                break;
+            default:
+                getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg);
+                return -1;
+        }
+
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(enabled);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxIsVerticalReachabilityEnabled(PrintWriter pw)
+            throws RemoteException {
+        String arg = getNextArg();
+        final boolean enabled;
+        switch (arg) {
+            case "true":
+            case "1":
+                enabled = true;
+                break;
+            case "false":
+            case "0":
+                enabled = false;
+                break;
+            default:
+                getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg);
+                return -1;
+        }
+
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setIsVerticalReachabilityEnabled(enabled);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxDefaultPositionForHorizontalReachability(PrintWriter pw)
+            throws RemoteException {
+        @LetterboxHorizontalReachabilityPosition final int position;
+        try {
+            String arg = getNextArgRequired();
+            switch (arg) {
+                case "left":
+                    position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
+                    break;
+                case "center":
+                    position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
+                    break;
+                case "right":
+                    position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
+                    break;
+                default:
+                    getErrPrintWriter().println(
+                            "Error: 'left', 'center' or 'right' are expected as an argument");
+                    return -1;
+            }
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: 'left', 'center' or 'right' are expected as an argument" + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setDefaultPositionForHorizontalReachability(position);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxDefaultPositionForVerticalReachability(PrintWriter pw)
+            throws RemoteException {
+        @LetterboxVerticalReachabilityPosition final int position;
+        try {
+            String arg = getNextArgRequired();
+            switch (arg) {
+                case "top":
+                    position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
+                    break;
+                case "center":
+                    position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
+                    break;
+                case "bottom":
+                    position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM;
+                    break;
+                default:
+                    getErrPrintWriter().println(
+                            "Error: 'top', 'center' or 'bottom' are expected as an argument");
+                    return -1;
+            }
+        } catch (IllegalArgumentException  e) {
+            getErrPrintWriter().println(
+                    "Error: 'top', 'center' or 'bottom' are expected as an argument" + e);
+            return -1;
+        }
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setDefaultPositionForVerticalReachability(position);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxIsEducationEnabled(PrintWriter pw) throws RemoteException {
+        String arg = getNextArg();
+        final boolean enabled;
+        switch (arg) {
+            case "true":
+            case "1":
+                enabled = true;
+                break;
+            case "false":
+            case "0":
+                enabled = false;
+                break;
+            default:
+                getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg);
+                return -1;
+        }
+
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setIsEducationEnabled(enabled);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled(PrintWriter pw)
+            throws RemoteException {
+        String arg = getNextArg();
+        final boolean enabled;
+        switch (arg) {
+            case "true":
+            case "1":
+                enabled = true;
+                break;
+            case "false":
+            case "0":
+                enabled = false;
+                break;
+            default:
+                getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg);
+                return -1;
+        }
+
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.setIsSplitScreenAspectRatioForUnresizableAppsEnabled(enabled);
+        }
+        return 0;
+    }
+
+    private int runSetLetterboxStyle(PrintWriter pw) throws RemoteException {
+        if (peekNextArg() == null) {
+            getErrPrintWriter().println("Error: No arguments provided.");
+        }
+        while (peekNextArg() != null) {
+            String arg = getNextArg();
+            switch (arg) {
+                case "--aspectRatio":
+                    runSetFixedOrientationLetterboxAspectRatio(pw);
+                    break;
+                case "--minAspectRatioForUnresizable":
+                    runSetDefaultMinAspectRatioForUnresizableApps(pw);
+                    break;
+                case "--cornerRadius":
+                    runSetLetterboxActivityCornersRadius(pw);
+                    break;
+                case "--backgroundType":
+                    runSetLetterboxBackgroundType(pw);
+                    break;
+                case "--backgroundColor":
+                    runSetLetterboxBackgroundColor(pw);
+                    break;
+                case "--backgroundColorResource":
+                    runSetLetterboxBackgroundColorResource(pw);
+                    break;
+                case "--wallpaperBlurRadius":
+                    runSetLetterboxBackgroundWallpaperBlurRadius(pw);
+                    break;
+                case "--wallpaperDarkScrimAlpha":
+                    runSetLetterboxBackgroundWallpaperDarkScrimAlpha(pw);
+                    break;
+                case "--horizontalPositionMultiplier":
+                    runSetLetterboxHorizontalPositionMultiplier(pw);
+                    break;
+                case "--verticalPositionMultiplier":
+                    runSetLetterboxVerticalPositionMultiplier(pw);
+                    break;
+                case "--isHorizontalReachabilityEnabled":
+                    runSetLetterboxIsHorizontalReachabilityEnabled(pw);
+                    break;
+                case "--isVerticalReachabilityEnabled":
+                    runSetLetterboxIsVerticalReachabilityEnabled(pw);
+                    break;
+                case "--defaultPositionForHorizontalReachability":
+                    runSetLetterboxDefaultPositionForHorizontalReachability(pw);
+                    break;
+                case "--defaultPositionForVerticalReachability":
+                    runSetLetterboxDefaultPositionForVerticalReachability(pw);
+                    break;
+                case "--isEducationEnabled":
+                    runSetLetterboxIsEducationEnabled(pw);
+                    break;
+                case "--isSplitScreenAspectRatioForUnresizableAppsEnabled":
+                    runSetLetterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled(pw);
+                    break;
+                default:
+                    getErrPrintWriter().println(
+                            "Error: Unrecognized letterbox style option: " + arg);
+                    return -1;
+            }
+        }
+        return 0;
+    }
+
+    private int runResetLetterboxStyle(PrintWriter pw) throws RemoteException {
+        if (peekNextArg() == null) {
+            resetLetterboxStyle();
+        }
+        synchronized (mInternal.mGlobalLock) {
+            while (peekNextArg() != null) {
+                String arg = getNextArg();
+                switch (arg) {
+                    case "aspectRatio":
+                        mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
+                        break;
+                    case "minAspectRatioForUnresizable":
+                        mLetterboxConfiguration.resetDefaultMinAspectRatioForUnresizableApps();
+                        break;
+                    case "cornerRadius":
+                        mLetterboxConfiguration.resetLetterboxActivityCornersRadius();
+                        break;
+                    case "backgroundType":
+                        mLetterboxConfiguration.resetLetterboxBackgroundType();
+                        break;
+                    case "backgroundColor":
+                        mLetterboxConfiguration.resetLetterboxBackgroundColor();
+                        break;
+                    case "wallpaperBlurRadius":
+                        mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
+                        break;
+                    case "wallpaperDarkScrimAlpha":
+                        mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
+                        break;
+                    case "horizontalPositionMultiplier":
+                        mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
+                        break;
+                    case "verticalPositionMultiplier":
+                        mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier();
+                        break;
+                    case "isHorizontalReachabilityEnabled":
+                        mLetterboxConfiguration.getIsHorizontalReachabilityEnabled();
+                        break;
+                    case "isVerticalReachabilityEnabled":
+                        mLetterboxConfiguration.getIsVerticalReachabilityEnabled();
+                        break;
+                    case "defaultPositionForHorizontalReachability":
+                        mLetterboxConfiguration.getDefaultPositionForHorizontalReachability();
+                        break;
+                    case "defaultPositionForVerticalReachability":
+                        mLetterboxConfiguration.getDefaultPositionForVerticalReachability();
+                        break;
+                    case "isEducationEnabled":
+                        mLetterboxConfiguration.getIsEducationEnabled();
+                        break;
+                    case "isSplitScreenAspectRatioForUnresizableAppsEnabled":
+                        mLetterboxConfiguration
+                                .getIsSplitScreenAspectRatioForUnresizableAppsEnabled();
+                        break;
+                    default:
+                        getErrPrintWriter().println(
+                                "Error: Unrecognized letterbox style option: " + arg);
+                        return -1;
+                }
+            }
+        }
+        return 0;
+    }
+
     private int runSetMultiWindowConfig() {
         if (peekNextArg() == null) {
             getErrPrintWriter().println("Error: No arguments provided.");
@@ -627,6 +1177,107 @@
         return 0;
     }
 
+    private void resetLetterboxStyle() {
+        synchronized (mInternal.mGlobalLock) {
+            mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
+            mLetterboxConfiguration.resetDefaultMinAspectRatioForUnresizableApps();
+            mLetterboxConfiguration.resetLetterboxActivityCornersRadius();
+            mLetterboxConfiguration.resetLetterboxBackgroundType();
+            mLetterboxConfiguration.resetLetterboxBackgroundColor();
+            mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius();
+            mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha();
+            mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
+            mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled();
+            mLetterboxConfiguration.resetIsVerticalReachabilityEnabled();
+            mLetterboxConfiguration.resetDefaultPositionForHorizontalReachability();
+            mLetterboxConfiguration.resetDefaultPositionForVerticalReachability();
+            mLetterboxConfiguration.resetIsEducationEnabled();
+            mLetterboxConfiguration.resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
+        }
+    }
+
+    private int runGetLetterboxStyle(PrintWriter pw) throws RemoteException {
+        synchronized (mInternal.mGlobalLock) {
+            pw.println("Corner radius: "
+                    + mLetterboxConfiguration.getLetterboxActivityCornersRadius());
+            pw.println("Horizontal position multiplier: "
+                    + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier());
+            pw.println("Vertical position multiplier: "
+                    + mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier());
+            pw.println("Aspect ratio: "
+                    + mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio());
+            pw.println("Default min aspect ratio for unresizable apps: "
+                    + mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps());
+            pw.println("Is horizontal reachability enabled: "
+                    + mLetterboxConfiguration.getIsHorizontalReachabilityEnabled());
+            pw.println("Is vertical reachability enabled: "
+                    + mLetterboxConfiguration.getIsVerticalReachabilityEnabled());
+            pw.println("Default position for horizontal reachability: "
+                    + LetterboxConfiguration.letterboxHorizontalReachabilityPositionToString(
+                            mLetterboxConfiguration.getDefaultPositionForHorizontalReachability()));
+            pw.println("Default position for vertical reachability: "
+                    + LetterboxConfiguration.letterboxVerticalReachabilityPositionToString(
+                    mLetterboxConfiguration.getDefaultPositionForVerticalReachability()));
+            pw.println("Is education enabled: "
+                    + mLetterboxConfiguration.getIsEducationEnabled());
+            pw.println("Is using split screen aspect ratio as aspect ratio for unresizable apps: "
+                    + mLetterboxConfiguration
+                            .getIsSplitScreenAspectRatioForUnresizableAppsEnabled());
+
+            pw.println("Background type: "
+                    + LetterboxConfiguration.letterboxBackgroundTypeToString(
+                            mLetterboxConfiguration.getLetterboxBackgroundType()));
+            pw.println("    Background color: " + Integer.toHexString(
+                    mLetterboxConfiguration.getLetterboxBackgroundColor().toArgb()));
+            pw.println("    Wallpaper blur radius: "
+                    + mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius());
+            pw.println("    Wallpaper dark scrim alpha: "
+                    + mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha());
+        }
+        return 0;
+    }
+
+    private int runWmShellCommand(PrintWriter pw) {
+        String arg = getNextArg();
+
+        switch (arg) {
+            case "tracing":
+                return runWmShellTracing(pw);
+            case "help":
+            default:
+                return runHelp(pw);
+        }
+    }
+
+    private int runHelp(PrintWriter pw) {
+        pw.println("Window Manager Shell commands:");
+        pw.println("  help");
+        pw.println("    Print this help text.");
+        pw.println("  tracing <start/stop>");
+        pw.println("    Start/stop shell transition tracing.");
+
+        return 0;
+    }
+
+    private int runWmShellTracing(PrintWriter pw) {
+        String arg = getNextArg();
+
+        switch (arg) {
+            case "start":
+                mInternal.mTransitionTracer.startTrace(pw);
+                break;
+            case "stop":
+                mInternal.mTransitionTracer.stopTrace(pw);
+                break;
+            default:
+                getErrPrintWriter()
+                        .println("Error: expected 'start' or 'stop', but got '" + arg + "'");
+                return -1;
+        }
+
+        return 0;
+    }
+
     private int runReset(PrintWriter pw) throws RemoteException {
         int displayId = getDisplayId(getNextArg());
 
@@ -651,6 +1302,12 @@
         // set-ignore-orientation-request
         mInterface.setIgnoreOrientationRequest(displayId, false /* ignoreOrientationRequest */);
 
+        // set-letterbox-style
+        resetLetterboxStyle();
+
+        // set-sandbox-display-apis
+        mInternal.setSandboxDisplayApis(displayId, /* sandboxDisplayApis= */ true);
+
         // set-multi-window-config
         runResetMultiWindowConfig();
 
@@ -685,7 +1342,12 @@
         pw.println("  set-ignore-orientation-request [-d DISPLAY_ID] [true|1|false|0]");
         pw.println("  get-ignore-orientation-request [-d DISPLAY_ID] ");
         pw.println("    If app requested orientation should be ignored.");
+        pw.println("  set-sandbox-display-apis [true|1|false|0]");
+        pw.println("    Sets override of Display APIs getRealSize / getRealMetrics to reflect ");
+        pw.println("    DisplayArea of the activity, or the window bounds if in letterbox or");
+        pw.println("    Size Compat Mode.");
 
+        printLetterboxHelp(pw);
         printMultiWindowConfigHelp(pw);
 
         pw.println("  reset [-d DISPLAY_ID]");
@@ -698,6 +1360,84 @@
         }
     }
 
+    private void printLetterboxHelp(PrintWriter pw) {
+        pw.println("  set-letterbox-style");
+        pw.println("    Sets letterbox style using the following options:");
+        pw.println("      --aspectRatio aspectRatio");
+        pw.println("        Aspect ratio of letterbox for fixed orientation. If aspectRatio <= "
+                + LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO);
+        pw.println("        both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will");
+        pw.println("        be ignored and framework implementation will determine aspect ratio.");
+        pw.println("      --minAspectRatioForUnresizable aspectRatio");
+        pw.println("        Default min aspect ratio for unresizable apps which is used when an");
+        pw.println("        app is eligible for the size compat mode.  If aspectRatio <= "
+                + LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO);
+        pw.println("        both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will");
+        pw.println("        be ignored and framework implementation will determine aspect ratio.");
+        pw.println("      --cornerRadius radius");
+        pw.println("        Corners radius for activities in the letterbox mode. If radius < 0,");
+        pw.println("        both it and R.integer.config_letterboxActivityCornersRadius will be");
+        pw.println("        ignored and corners of the activity won't be rounded.");
+        pw.println("      --backgroundType [reset|solid_color|app_color_background");
+        pw.println("          |app_color_background_floating|wallpaper]");
+        pw.println("        Type of background used in the letterbox mode.");
+        pw.println("      --backgroundColor color");
+        pw.println("        Color of letterbox which is be used when letterbox background type");
+        pw.println("        is 'solid-color'. Use (set)get-letterbox-style to check and control");
+        pw.println("        letterbox background type. See Color#parseColor for allowed color");
+        pw.println("        formats (#RRGGBB and some colors by name, e.g. magenta or olive).");
+        pw.println("      --backgroundColorResource resource_name");
+        pw.println("        Color resource name of letterbox background which is used when");
+        pw.println("        background type is 'solid-color'. Use (set)get-letterbox-style to");
+        pw.println("        check and control background type. Parameter is a color resource");
+        pw.println("        name, for example, @android:color/system_accent2_50.");
+        pw.println("      --wallpaperBlurRadius radius");
+        pw.println("        Blur radius for 'wallpaper' letterbox background. If radius <= 0");
+        pw.println("        both it and R.dimen.config_letterboxBackgroundWallpaperBlurRadius");
+        pw.println("        are ignored and 0 is used.");
+        pw.println("      --wallpaperDarkScrimAlpha alpha");
+        pw.println("        Alpha of a black translucent scrim shown over 'wallpaper'");
+        pw.println("        letterbox background. If alpha < 0 or >= 1 both it and");
+        pw.println("        R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha are ignored");
+        pw.println("        and 0.0 (transparent) is used instead.");
+        pw.println("      --horizontalPositionMultiplier multiplier");
+        pw.println("        Horizontal position of app window center. If multiplier < 0 or > 1,");
+        pw.println("        both it and R.dimen.config_letterboxHorizontalPositionMultiplier");
+        pw.println("        are ignored and central position (0.5) is used.");
+        pw.println("      --verticalPositionMultiplier multiplier");
+        pw.println("        Vertical position of app window center. If multiplier < 0 or > 1,");
+        pw.println("        both it and R.dimen.config_letterboxVerticalPositionMultiplier");
+        pw.println("        are ignored and central position (0.5) is used.");
+        pw.println("      --isHorizontalReachabilityEnabled [true|1|false|0]");
+        pw.println("        Whether horizontal reachability repositioning is allowed for ");
+        pw.println("        letterboxed fullscreen apps in landscape device orientation.");
+        pw.println("      --isVerticalReachabilityEnabled [true|1|false|0]");
+        pw.println("        Whether vertical reachability repositioning is allowed for ");
+        pw.println("        letterboxed fullscreen apps in portrait device orientation.");
+        pw.println("      --defaultPositionForHorizontalReachability [left|center|right]");
+        pw.println("        Default position of app window when horizontal reachability is.");
+        pw.println("        enabled.");
+        pw.println("      --defaultPositionForVerticalReachability [top|center|bottom]");
+        pw.println("        Default position of app window when vertical reachability is.");
+        pw.println("        enabled.");
+        pw.println("      --isEducationEnabled [true|1|false|0]");
+        pw.println("        Whether education is allowed for letterboxed fullscreen apps.");
+        pw.println("      --isSplitScreenAspectRatioForUnresizableAppsEnabled [true|1|false|0]");
+        pw.println("        Whether using split screen aspect ratio as a default aspect ratio for");
+        pw.println("        unresizable apps.");
+        pw.println("  reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
+        pw.println("      |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
+        pw.println("      |horizontalPositionMultiplier|verticalPositionMultiplier");
+        pw.println("      |isHorizontalReachabilityEnabled|isVerticalReachabilityEnabled");
+        pw.println("      isEducationEnabled||defaultPositionMultiplierForHorizontalReachability");
+        pw.println("      ||defaultPositionMultiplierForVerticalReachability]");
+        pw.println("    Resets overrides to default values for specified properties separated");
+        pw.println("    by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
+        pw.println("    If no arguments provided, all values will be reset.");
+        pw.println("  get-letterbox-style");
+        pw.println("    Prints letterbox style configuration.");
+    }
+
     private void printMultiWindowConfigHelp(PrintWriter pw) {
         pw.println("  set-multi-window-config");
         pw.println("    Sets options to determine if activity should be shown in multi window:");
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 22d6237..1d93c89 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.app.ActivityManager.isStartResultSuccessful;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER;
@@ -43,6 +44,7 @@
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
 import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED;
 import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
@@ -147,7 +149,8 @@
     }
 
     void setWindowManager(WindowManagerService wms) {
-        mTransitionController = new TransitionController(mService, wms.mTaskSnapshotController);
+        mTransitionController = new TransitionController(mService, wms.mTaskSnapshotController,
+                wms.mTransitionTracer);
         mTransitionController.registerLegacyListener(wms.mActivityManagerAppTransitionNotifier);
     }
 
@@ -325,7 +328,8 @@
                 }
                 adapter.setCallingPidUid(caller.mPid, caller.mUid);
                 dc.prepareAppTransition(type);
-                dc.mAppTransition.overridePendingAppTransitionRemote(adapter, true /* sync */);
+                dc.mAppTransition.overridePendingAppTransitionRemote(adapter, true /* sync */,
+                        false /* isActivityEmbedding */);
                 syncId = startSyncWithOrganizer(callback);
                 applyTransaction(t, syncId, null /* transition */, caller);
                 setSyncReady(syncId);
@@ -397,6 +401,8 @@
                     effects |= TRANSACT_EFFECTS_LIFECYCLE;
                 }
             }
+            final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
+            final int hopSize = hops.size();
             ArraySet<WindowContainer> haveConfigChanges = new ArraySet<>();
             Iterator<Map.Entry<IBinder, WindowContainerTransaction.Change>> entries =
                     t.getChanges().entrySet().iterator();
@@ -415,18 +421,43 @@
                 }
                 if (transition != null) transition.collect(wc);
 
-                if (finishTransition != null) {
-                    // Deal with edge-cases in recents where it pretends to finish itself.
-                    if ((entry.getValue().getChangeMask()
-                            & WindowContainerTransaction.Change.CHANGE_FORCE_NO_PIP) != 0) {
+                if ((entry.getValue().getChangeMask()
+                        & WindowContainerTransaction.Change.CHANGE_FORCE_NO_PIP) != 0) {
+                    // Disable entering pip (eg. when recents pretends to finish itself)
+                    if (finishTransition != null) {
                         finishTransition.setCanPipOnFinish(false /* canPipOnFinish */);
+                    } else if (transition != null) {
+                        transition.setCanPipOnFinish(false /* canPipOnFinish */);
                     }
                 }
+                // A bit hacky, but we need to detect "remove PiP" so that we can "wrap" the
+                // setWindowingMode call in force-hidden.
+                boolean forceHiddenForPip = false;
+                if (wc.asTask() != null && wc.inPinnedWindowingMode()
+                        && entry.getValue().getWindowingMode() == WINDOWING_MODE_UNDEFINED) {
+                    // We are in pip and going to undefined. Now search hierarchy ops to determine
+                    // whether we are removing pip or expanding pip.
+                    for (int i = 0; i < hopSize; ++i) {
+                        final WindowContainerTransaction.HierarchyOp hop = hops.get(i);
+                        if (hop.getType() != HIERARCHY_OP_TYPE_REORDER) continue;
+                        final WindowContainer hopWc = WindowContainer.fromBinder(
+                                hop.getContainer());
+                        if (!wc.equals(hopWc)) continue;
+                        forceHiddenForPip = !hop.getToTop();
+                    }
+                }
+                if (forceHiddenForPip) {
+                    wc.asTask().setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, true /* set */);
+                }
 
                 int containerEffect = applyWindowContainerChange(wc, entry.getValue(),
                         t.getErrorCallbackToken());
                 effects |= containerEffect;
 
+                if (forceHiddenForPip) {
+                    wc.asTask().setForceHidden(FLAG_FORCE_HIDDEN_FOR_PINNED_TASK, false /* set */);
+                }
+
                 // Lifecycle changes will trigger ensureConfig for everything.
                 if ((effects & TRANSACT_EFFECTS_LIFECYCLE) == 0
                         && (containerEffect & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
@@ -434,8 +465,6 @@
                 }
             }
             // Hierarchy changes
-            final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
-            final int hopSize = hops.size();
             if (hopSize > 0) {
                 final boolean isInLockTaskMode = mService.isInLockTaskMode();
                 for (int i = 0; i < hopSize; ++i) {
@@ -497,7 +526,7 @@
                 }
             }
 
-            if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) == 0) {
+            if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
                 mService.addWindowLayoutReasons(LAYOUT_REASON_CONFIG_CHANGED);
             }
         } finally {
@@ -551,6 +580,13 @@
                         + " windowing mode during locked task mode.");
             }
 
+            if (windowingMode == WindowConfiguration.WINDOWING_MODE_PINNED) {
+                // Do not directly put the container into PINNED mode as it may not support it or
+                // the app may not want to enter it. Instead, send a signal to request PIP
+                // mode to the app if they wish to support it below in #applyTaskChanges.
+                return effects;
+            }
+
             final int prevMode = container.getWindowingMode();
             container.setWindowingMode(windowingMode);
             if (prevMode != container.getWindowingMode()) {
@@ -607,6 +643,28 @@
             tr.mDisplayContent.mPinnedTaskController.setEnterPipBounds(enterPipBounds);
         }
 
+        if (c.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_PINNED
+                && !tr.inPinnedWindowingMode()) {
+            final ActivityRecord activity = tr.getTopNonFinishingActivity();
+            if (activity != null) {
+                final boolean lastSupportsEnterPipOnTaskSwitch =
+                        activity.supportsEnterPipOnTaskSwitch;
+                // Temporarily force enable enter PIP on task switch so that PIP is requested
+                // regardless of whether the activity is resumed or paused.
+                activity.supportsEnterPipOnTaskSwitch = true;
+                boolean canEnterPip = activity.checkEnterPictureInPictureState(
+                        "applyTaskChanges", true /* beforeStopping */);
+                if (canEnterPip) {
+                    canEnterPip = mService.mActivityClientController
+                            .requestPictureInPictureMode(activity);
+                }
+                if (!canEnterPip) {
+                    // Restore the flag to its previous state when the activity cannot enter PIP.
+                    activity.supportsEnterPipOnTaskSwitch = lastSupportsEnterPipOnTaskSwitch;
+                }
+            }
+        }
+
         return effects;
     }
 
@@ -798,7 +856,7 @@
                     sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
                     break;
                 }
-                tf1.setAdjacentTaskFragment(tf2, false /* moveAdjacentTogether */);
+                tf1.setAdjacentTaskFragment(tf2);
                 effects |= TRANSACT_EFFECTS_LIFECYCLE;
 
                 final Bundle bundle = hop.getLaunchOptions();
@@ -840,22 +898,22 @@
                 tf.getDisplayContent().setFocusedApp(targetFocus);
                 break;
             }
-            default: {
-                // The other operations may change task order so they are skipped while in lock
-                // task mode. The above operations are still allowed because they don't move
-                // tasks. And it may be necessary such as clearing launch root after entering
-                // lock task mode.
-                if (isInLockTaskMode) {
-                    Slog.w(TAG, "Skip applying hierarchy operation " + hop
-                            + " while in lock task mode");
-                    return effects;
-                }
-            }
-        }
-
-        switch (type) {
             case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: {
-                effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId);
+                effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId,
+                        isInLockTaskMode);
+                break;
+            }
+            case HIERARCHY_OP_TYPE_LAUNCH_TASK: {
+                mService.mAmInternal.enforceCallingPermission(START_TASKS_FROM_RECENTS,
+                        "launchTask HierarchyOp");
+                final Bundle launchOpts = hop.getLaunchOptions();
+                final int taskId = launchOpts.getInt(
+                        WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
+                launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
+                final SafeActivityOptions safeOptions =
+                        SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid);
+                waitAsyncStart(() -> mService.mTaskSupervisor.startActivityFromRecents(
+                        caller.mPid, caller.mUid, taskId, safeOptions));
                 break;
             }
             case HIERARCHY_OP_TYPE_REORDER:
@@ -865,6 +923,16 @@
                     Slog.e(TAG, "Attempt to operate on detached container: " + wc);
                     break;
                 }
+                // There is no use case to ask the reparent operation in lock-task mode now, so keep
+                // skipping this operation as usual.
+                if (isInLockTaskMode && type == HIERARCHY_OP_TYPE_REPARENT) {
+                    Slog.w(TAG, "Skip applying hierarchy operation " + hop
+                            + " while in lock task mode");
+                    break;
+                }
+                if (isLockTaskModeViolation(wc.getParent(), wc.asTask(), isInLockTaskMode)) {
+                    break;
+                }
                 if (syncId >= 0) {
                     addToSyncSet(syncId, wc);
                 }
@@ -890,19 +958,20 @@
                 effects |= sanitizeAndApplyHierarchyOp(wc, hop);
                 break;
             }
-            case HIERARCHY_OP_TYPE_LAUNCH_TASK: {
-                mService.mAmInternal.enforceCallingPermission(START_TASKS_FROM_RECENTS,
-                        "launchTask HierarchyOp");
-                final Bundle launchOpts = hop.getLaunchOptions();
-                final int taskId = launchOpts.getInt(
-                        WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
-                launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
-                final SafeActivityOptions safeOptions =
-                        SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid);
-                waitAsyncStart(() -> mService.mTaskSupervisor.startActivityFromRecents(
-                        caller.mPid, caller.mUid, taskId, safeOptions));
-                break;
+            default: {
+                // The other operations may change task order so they are skipped while in lock
+                // task mode. The above operations are still allowed because they don't move
+                // tasks. And it may be necessary such as clearing launch root after entering
+                // lock task mode.
+                if (isInLockTaskMode) {
+                    Slog.w(TAG, "Skip applying hierarchy operation " + hop
+                            + " while in lock task mode");
+                    return effects;
+                }
             }
+        }
+
+        switch (type) {
             case HIERARCHY_OP_TYPE_PENDING_INTENT: {
                 String resolvedType = hop.getActivityIntent() != null
                         ? hop.getActivityIntent().resolveTypeIfNeeded(
@@ -1094,8 +1163,25 @@
         return TRANSACT_EFFECTS_LIFECYCLE;
     }
 
+    private boolean isLockTaskModeViolation(WindowContainer parent, Task task,
+            boolean isInLockTaskMode) {
+        if (!isInLockTaskMode || parent == null || task == null) {
+            return false;
+        }
+        final LockTaskController lockTaskController = mService.getLockTaskController();
+        boolean taskViolation = lockTaskController.isLockTaskModeViolation(task);
+        if (!taskViolation && parent.asTask() != null) {
+            taskViolation = lockTaskController.isLockTaskModeViolation(parent.asTask());
+        }
+        if (taskViolation) {
+            Slog.w(TAG, "Can't support the operation since in lock task mode violation. "
+                    + " Task: " + task + " Parent : " + parent);
+        }
+        return taskViolation;
+    }
+
     private int reparentChildrenTasksHierarchyOp(WindowContainerTransaction.HierarchyOp hop,
-            @Nullable Transition transition, int syncId) {
+            @Nullable Transition transition, int syncId, boolean isInLockTaskMode) {
         WindowContainer<?> currentParent = hop.getContainer() != null
                 ? WindowContainer.fromBinder(hop.getContainer()) : null;
         WindowContainer newParent = hop.getNewParent() != null
@@ -1133,6 +1219,7 @@
                 ? newParent.asTask().getDisplayArea()
                 : newParent.asTaskDisplayArea();
         final WindowContainer finalCurrentParent = currentParent;
+        final WindowContainer finalNewParent = newParent;
         Slog.i(TAG, "reparentChildrenTasksHierarchyOp"
                 + " currentParent=" + currentParent + " newParent=" + newParent + " hop=" + hop);
 
@@ -1156,6 +1243,9 @@
                     || !ArrayUtils.contains(hop.getWindowingModes(), task.getWindowingMode())) {
                 return false;
             }
+            if (isLockTaskModeViolation(finalNewParent, task, isInLockTaskMode)) {
+                return false;
+            }
 
             if (hop.getToTop()) {
                 tasksToReparent.add(0, task);
@@ -1200,7 +1290,7 @@
             Slog.e(TAG, "Attempt to set adjacent TaskFragment in PIP Task");
             return 0;
         }
-        root1.setAdjacentTaskFragment(root2, hop.getMoveAdjacentTogether());
+        root1.setAdjacentTaskFragment(root2);
         return TRANSACT_EFFECTS_LIFECYCLE;
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowOrientationListener.java b/services/core/java/com/android/server/wm/WindowOrientationListener.java
index de87ab9..3e165e4 100644
--- a/services/core/java/com/android/server/wm/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/wm/WindowOrientationListener.java
@@ -296,9 +296,9 @@
 
     /**
      * Whether the device is in the lock screen.
-     * @return returns true if the screen is locked. Otherwise, returns false.
+     * @return returns true if the key guard is showing on the lock screen.
      */
-    public abstract boolean isKeyguardLocked();
+    public abstract boolean isKeyguardShowingAndNotOccluded();
 
     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
@@ -1151,7 +1151,7 @@
                     FrameworkStatsLog.DEVICE_ROTATED__ROTATION_EVENT_TYPE__ACTUAL_EVENT);
 
             if (isRotationResolverEnabled()) {
-                if (isKeyguardLocked()) {
+                if (isKeyguardShowingAndNotOccluded()) {
                     if (mLastRotationResolution != ROTATION_UNSET
                             && SystemClock.uptimeMillis() - mLastRotationResolutionTimeStamp
                             < mRotationMemorizationTimeoutMillis) {
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 40417a4..3ff912c 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED;
@@ -24,7 +25,6 @@
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
 import static com.android.internal.util.Preconditions.checkArgument;
-import static com.android.server.am.ActivityManagerService.MY_PID;
 import static com.android.server.wm.ActivityRecord.State.DESTROYED;
 import static com.android.server.wm.ActivityRecord.State.DESTROYING;
 import static com.android.server.wm.ActivityRecord.State.PAUSED;
@@ -39,6 +39,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MILLIS;
 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
+import static com.android.server.wm.WindowManagerService.MY_PID;
 
 import android.Manifest;
 import android.annotation.NonNull;
@@ -195,6 +196,11 @@
     /** Whether the process configuration is waiting to be dispatched to the process. */
     private boolean mHasPendingConfigurationChange;
 
+    /** If the process state is in (<=) the cached state, then defer delivery of the config. */
+    private static final int CACHED_CONFIG_PROC_STATE = PROCESS_STATE_CACHED_ACTIVITY;
+    /** Whether {@link #mLastReportedConfiguration} is deferred by the cached state. */
+    private volatile boolean mHasCachedConfiguration;
+
     /**
      * Registered {@link DisplayArea} as a listener to override config changes. {@code null} if not
      * registered.
@@ -316,8 +322,27 @@
         return mCurProcState;
     }
 
+    /**
+     * Sets the computed process state from the oom adjustment calculation. This is frequently
+     * called in activity manager's lock, so don't use window manager lock here.
+     */
+    @HotPath(caller = HotPath.OOM_ADJUSTMENT)
     public void setReportedProcState(int repProcState) {
+        final int prevProcState = mRepProcState;
         mRepProcState = repProcState;
+
+        // Deliver the cached config if the app changes from cached state to non-cached state.
+        final IApplicationThread thread = mThread;
+        if (prevProcState >= CACHED_CONFIG_PROC_STATE && repProcState < CACHED_CONFIG_PROC_STATE
+                && thread != null && mHasCachedConfiguration) {
+            final Configuration config;
+            synchronized (mLastReportedConfiguration) {
+                config = new Configuration(mLastReportedConfiguration);
+            }
+            // Schedule immediately to make sure the app component (e.g. receiver, service) can get
+            // the latest configuration in their lifecycle callbacks (e.g. onReceive, onCreate).
+            scheduleConfigurationChange(thread, config);
+        }
     }
 
     int getReportedProcState() {
@@ -1126,6 +1151,13 @@
         mAtm.mH.sendMessage(m);
     }
 
+    /** Refreshes oom adjustment and process state of this process. */
+    void scheduleUpdateOomAdj() {
+        mAtm.mH.sendMessage(PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
+                mListener, false /* updateServiceConnectionActivities */,
+                false /* activityChange */, true /* updateOomAdj */));
+    }
+
     /** Makes the process have top state before oom-adj is computed from a posted message. */
     void addToPendingTop() {
         mAtm.mAmInternal.addPendingTopUid(mUid, mPid, mThread);
@@ -1328,12 +1360,22 @@
     @Override
     public void onConfigurationChanged(Configuration newGlobalConfig) {
         super.onConfigurationChanged(newGlobalConfig);
-        updateConfiguration();
-    }
+        final Configuration config = getConfiguration();
+        if (mLastReportedConfiguration.equals(config)) {
+            // Nothing changed.
+            if (Build.IS_DEBUGGABLE && mHasImeService) {
+                // TODO (b/135719017): Temporary log for debugging IME service.
+                Slog.w(TAG_CONFIGURATION, "Current config: " + config
+                        + " unchanged for IME proc " + mName);
+            }
+            return;
+        }
 
-    @Override
-    public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
-        super.onRequestedOverrideConfigurationChanged(overrideConfiguration);
+        if (mPauseConfigurationDispatchCount > 0) {
+            mHasPendingConfigurationChange = true;
+            return;
+        }
+        dispatchConfiguration(config);
     }
 
     @Override
@@ -1359,25 +1401,6 @@
         resolvedConfig.seq = newParentConfig.seq;
     }
 
-    private void updateConfiguration() {
-        final Configuration config = getConfiguration();
-        if (mLastReportedConfiguration.diff(config) == 0) {
-            // Nothing changed.
-            if (Build.IS_DEBUGGABLE && mHasImeService) {
-                // TODO (b/135719017): Temporary log for debugging IME service.
-                Slog.w(TAG_CONFIGURATION, "Current config: " + config
-                        + " unchanged for IME proc " + mName);
-            }
-            return;
-        }
-
-        if (mPauseConfigurationDispatchCount > 0) {
-            mHasPendingConfigurationChange = true;
-            return;
-        }
-        dispatchConfiguration(config);
-    }
-
     void dispatchConfiguration(Configuration config) {
         mHasPendingConfigurationChange = false;
         if (mThread == null) {
@@ -1388,29 +1411,47 @@
             }
             return;
         }
+
+        config.seq = mAtm.increaseConfigurationSeqLocked();
+        setLastReportedConfiguration(config);
+
+        // A cached process doesn't have running application components, so it is unnecessary to
+        // notify the configuration change. The last-reported-configuration is still set because
+        // setReportedProcState() should not write any fields that require WM lock.
+        if (mRepProcState >= CACHED_CONFIG_PROC_STATE) {
+            mHasCachedConfiguration = true;
+            // Because there are 2 volatile accesses in setReportedProcState(): mRepProcState and
+            // mHasCachedConfiguration, check again in case mRepProcState is changed but hasn't
+            // read the change of mHasCachedConfiguration.
+            if (mRepProcState >= CACHED_CONFIG_PROC_STATE) {
+                return;
+            }
+        }
+
+        scheduleConfigurationChange(mThread, config);
+    }
+
+    private void scheduleConfigurationChange(IApplicationThread thread, Configuration config) {
         ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending to proc %s new config %s", mName,
                 config);
         if (Build.IS_DEBUGGABLE && mHasImeService) {
             // TODO (b/135719017): Temporary log for debugging IME service.
             Slog.v(TAG_CONFIGURATION, "Sending to IME proc " + mName + " new config " + config);
         }
-
+        mHasCachedConfiguration = false;
         try {
-            config.seq = mAtm.increaseConfigurationSeqLocked();
-            mAtm.getLifecycleManager().scheduleTransaction(mThread,
+            mAtm.getLifecycleManager().scheduleTransaction(thread,
                     ConfigurationChangeItem.obtain(config));
-            setLastReportedConfiguration(config);
         } catch (Exception e) {
-            Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
+            Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change: " + mOwner, e);
         }
     }
 
     void setLastReportedConfiguration(Configuration config) {
-        mLastReportedConfiguration.setTo(config);
-    }
-
-    Configuration getLastReportedConfiguration() {
-        return mLastReportedConfiguration;
+        // Synchronize for the access from setReportedProcState().
+        synchronized (mLastReportedConfiguration) {
+            mLastReportedConfiguration.setTo(config);
+        }
     }
 
     void pauseConfigurationDispatch() {
@@ -1461,6 +1502,8 @@
             // config seq. This increment ensures that the client won't ignore the configuration.
             config.seq = mAtm.increaseConfigurationSeqLocked();
         }
+        // LaunchActivityItem includes the latest process configuration.
+        mHasCachedConfiguration = false;
         return config;
     }
 
@@ -1688,7 +1731,8 @@
         }
         pw.println(prefix + " Configuration=" + getConfiguration());
         pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration());
-        pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
+        pw.println(prefix + " mLastReportedConfiguration=" + (mHasCachedConfiguration
+                ? ("(cached) " + mLastReportedConfiguration) : mLastReportedConfiguration));
 
         final int stateFlags = mActivityStateFlags;
         if (stateFlags != ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4c32edc..46091d8 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -115,8 +115,8 @@
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RESIZE;
 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.server.am.ActivityManagerService.MY_PID;
 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;
@@ -151,6 +151,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.H.WINDOW_STATE_BLAST_SYNC_TIMEOUT;
 import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
+import static com.android.server.wm.WindowManagerService.MY_PID;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_REMOVING_FOCUS;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
@@ -392,6 +393,9 @@
     int mSyncSeqId = 0;
     int mLastSeqIdSentToRelayout = 0;
 
+    /** The last syncId associated with a prepareSync or 0 when no sync is active. */
+    int mPrepareSyncSeqId = 0;
+
     /**
      * {@code true} when the client was still drawing for sync when the sync-set was finished or
      * cancelled. This can happen if the window goes away during a sync. In this situation we need
@@ -616,11 +620,6 @@
     int mLastVisibleLayoutRotation = -1;
 
     /**
-     * Set when we need to report the orientation change to client to trigger a relayout.
-     */
-    boolean mReportOrientationChanged;
-
-    /**
      * How long we last kept the screen frozen.
      */
     int mLastFreezeDuration;
@@ -814,7 +813,8 @@
     };
 
     private final Consumer<SurfaceControl.Transaction> mSetSurfacePositionConsumer = t -> {
-        if (mSurfaceControl != null && mSurfaceControl.isValid()) {
+        // Only apply the position to the surface when there's no leash created.
+        if (mSurfaceControl != null && mSurfaceControl.isValid() && !mSurfaceAnimator.hasLeash()) {
             t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y);
         }
     };
@@ -1251,7 +1251,7 @@
         mSession.windowAddedLocked();
     }
 
-    boolean updateGlobalScale() {
+    void updateGlobalScale() {
         if (hasCompatScale()) {
             if (mOverrideScale != 1f) {
                 mGlobalScale = mToken.hasSizeCompatBounds()
@@ -1261,11 +1261,10 @@
                 mGlobalScale = mToken.getSizeCompatScale();
             }
             mInvGlobalScale = 1f / mGlobalScale;
-            return true;
+            return;
         }
 
         mGlobalScale = mInvGlobalScale = 1f;
-        return false;
     }
 
     /**
@@ -1481,15 +1480,6 @@
         return mAttrs;
     }
 
-    WindowManager.LayoutParams getLayoutingAttrs(int rotation) {
-        final WindowManager.LayoutParams[] paramsForRotation = mAttrs.paramsForRotation;
-        if (paramsForRotation == null || paramsForRotation.length != 4
-                || paramsForRotation[rotation] == null) {
-            return mAttrs;
-        }
-        return paramsForRotation[rotation];
-    }
-
     /** Retrieves the flags used to disable system UI functions. */
     int getDisableFlags() {
         return mDisableFlags;
@@ -1527,29 +1517,27 @@
         final boolean dragResizingChanged = isDragResizeChanged()
                 && !isDragResizingChangeReported();
 
+        final boolean attachedFrameChanged = LOCAL_LAYOUT
+                && mLayoutAttached && getParentWindow().frameChanged();
+
         if (DEBUG) {
             Slog.v(TAG_WM, "Resizing " + this + ": configChanged=" + configChanged
                     + " dragResizingChanged=" + dragResizingChanged
                     + " last=" + mWindowFrames.mLastFrame + " frame=" + mWindowFrames.mFrame);
         }
 
-        // We update mLastFrame always rather than in the conditional with the last inset
-        // variables, because mFrameSizeChanged only tracks the width and height changing.
-        updateLastFrames();
-
         // Add a window that is using blastSync to the resizing list if it hasn't been reported
         // already. This because the window is waiting on a finishDrawing from the client.
         if (didFrameInsetsChange
                 || configChanged
                 || insetsChanged
                 || dragResizingChanged
-                || mReportOrientationChanged
-                || shouldSendRedrawForSync()) {
+                || shouldSendRedrawForSync()
+                || attachedFrameChanged) {
             ProtoLog.v(WM_DEBUG_RESIZE,
-                        "Resize reasons for w=%s:  %s configChanged=%b "
-                                + "dragResizingChanged=%b reportOrientationChanged=%b",
+                        "Resize reasons for w=%s:  %s configChanged=%b dragResizingChanged=%b",
                         this, mWindowFrames.getInsetsChangedInfo(),
-                        configChanged, dragResizingChanged, mReportOrientationChanged);
+                        configChanged, dragResizingChanged);
 
             if (insetsChanged) {
                 mWindowFrames.setInsetsChanged(false);
@@ -1601,6 +1589,10 @@
         }
     }
 
+    private boolean frameChanged() {
+        return !mWindowFrames.mFrame.equals(mWindowFrames.mLastFrame);
+    }
+
     boolean getOrientationChanging() {
         // In addition to the local state flag, we must also consider the difference in the last
         // reported configuration vs. the current state. If the client code has not been informed of
@@ -2180,6 +2172,7 @@
             return;
         }
         if (mActivityRecord != null) {
+            if (!mActivityRecord.mVisibleRequested) return;
             if (mActivityRecord.allDrawn) {
                 // The allDrawn of activity is reset when the visibility is changed to visible, so
                 // the content should be ready if allDrawn is set.
@@ -3579,10 +3572,6 @@
         mAnimatingExit = false;
         ProtoLog.d(WM_DEBUG_ANIM, "Clear animatingExit: reason=destroySurface win=%s", this);
 
-        // Clear the flag so the buffer requested for the next new surface won't be dropped by
-        // mistaking the surface size needs to update.
-        mReportOrientationChanged = false;
-
         if (useBLASTSync()) {
             immediatelyNotifyBlastSync();
         }
@@ -3855,6 +3844,12 @@
         if (mInvGlobalScale != 1.0f && hasCompatScale()) {
             outFrames.displayFrame.scale(mInvGlobalScale);
         }
+        if (mLayoutAttached) {
+            if (outFrames.attachedFrame == null) {
+                outFrames.attachedFrame = new Rect();
+            }
+            outFrames.attachedFrame.set(getParentWindow().getCompatFrame());
+        }
 
         // Note: in the cases where the window is tied to an activity, we should not send a
         // configuration update when the window has requested to be hidden. Doing so can lead to
@@ -3899,21 +3894,25 @@
             ProtoLog.i(WM_DEBUG_ORIENTATION, "Resizing %s WITH DRAW PENDING", this);
         }
 
-        final boolean reportOrientation = mReportOrientationChanged;
         // Always reset these states first, so if {@link IWindow#resized} fails, this
         // window won't be added to {@link WindowManagerService#mResizingWindows} and set
         // {@link #mOrientationChanging} to true again by {@link #updateResizingWindowIfNeeded}
         // that may cause WINDOW_FREEZE_TIMEOUT because resizing the client keeps failing.
-        mReportOrientationChanged = false;
         mDragResizingChangeReported = true;
         mWindowFrames.clearReportResizeHints();
 
+        // We update mLastFrame always rather than in the conditional with the last inset
+        // variables, because mFrameSizeChanged only tracks the width and height changing.
+        updateLastFrames();
+
+        final int prevRotation = mLastReportedConfiguration
+                .getMergedConfiguration().windowConfiguration.getRotation();
         fillClientWindowFramesAndConfiguration(mClientWindowFrames, mLastReportedConfiguration,
                 true /* useLatestConfig */, false /* relayoutVisible */);
         final boolean syncRedraw = shouldSendRedrawForSync();
         final boolean reportDraw = syncRedraw || drawPending;
         final boolean isDragResizeChanged = isDragResizeChanged();
-        final boolean forceRelayout = syncRedraw || reportOrientation || isDragResizeChanged;
+        final boolean forceRelayout = syncRedraw || isDragResizeChanged;
         final DisplayContent displayContent = getDisplayContent();
         final boolean alwaysConsumeSystemBars =
                 displayContent.getDisplayPolicy().areSystemBarsForcedShownLw();
@@ -3940,7 +3939,8 @@
             mClient.resized(mClientWindowFrames, reportDraw, mLastReportedConfiguration,
                     getCompatInsetsState(), forceRelayout, alwaysConsumeSystemBars, displayId,
                     mSyncSeqId, resizeMode);
-            if (drawPending && reportOrientation && mOrientationChanging) {
+            if (drawPending && prevRotation >= 0 && prevRotation != mLastReportedConfiguration
+                    .getMergedConfiguration().windowConfiguration.getRotation()) {
                 mOrientationChangeRedrawRequestTime = SystemClock.elapsedRealtime();
                 ProtoLog.v(WM_DEBUG_ORIENTATION,
                         "Requested redraw for orientation change: %s", this);
@@ -4365,12 +4365,11 @@
                     + " mDestroying=" + mDestroying
                     + " mRemoved=" + mRemoved);
         }
-        if (getOrientationChanging() || mAppFreezing || mReportOrientationChanged) {
+        if (getOrientationChanging() || mAppFreezing) {
             pw.println(prefix + "mOrientationChanging=" + mOrientationChanging
                     + " configOrientationChanging="
                     + (getLastReportedConfiguration().orientation != getConfiguration().orientation)
-                    + " mAppFreezing=" + mAppFreezing
-                    + " mReportOrientationChanged=" + mReportOrientationChanged);
+                    + " mAppFreezing=" + mAppFreezing);
         }
         if (mLastFreezeDuration != 0) {
             pw.print(prefix + "mLastFreezeDuration=");
@@ -4424,6 +4423,8 @@
                 pw.println(prefix + "Requested visibilities: " + visibilityString);
             }
         }
+
+        pw.println(prefix + "mPrepareSyncSeqId=" + mPrepareSyncSeqId);
     }
 
     @Override
@@ -4977,18 +4978,6 @@
         return isAnimating(CHILDREN, ANIMATION_TYPE_WINDOW_ANIMATION);
     }
 
-    /**
-     * @return {@code true} if self or the parent container of the window is in transition.
-     * (e.g. The app or recents transition)
-     */
-    boolean inTransitionSelfOrParent() {
-        if (!mTransitionController.isShellTransitionsEnabled()) {
-            return isAnimating(PARENTS | TRANSITION,
-                    ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS);
-        }
-        return mTransitionController.inTransition(this);
-    }
-
     private boolean shouldFinishAnimatingExit() {
         // Exit animation might be applied soon.
         if (inTransition()) {
@@ -5575,7 +5564,7 @@
                 mLastSurfaceInsets.set(mAttrs.surfaceInsets);
             }
             if (surfaceSizeChanged && mWinAnimator.getShown() && !canPlayMoveAnimation()
-                    && okToDisplay()) {
+                    && okToDisplay() && mSyncState == SYNC_STATE_NONE) {
                 applyWithNextDraw(mSetSurfacePositionConsumer);
             } else {
                 mSetSurfacePositionConsumer.accept(t);
@@ -5927,8 +5916,18 @@
         return mWinAnimator.getSurfaceControl();
     }
 
+    /** Drops a buffer for this window's view-root from a transaction */
+    private void dropBufferFrom(Transaction t) {
+        SurfaceControl viewSurface = getClientViewRootSurface();
+        if (viewSurface == null) return;
+        t.setBuffer(viewSurface, (android.hardware.HardwareBuffer) null);
+    }
+
     @Override
     boolean prepareSync() {
+        if (!mDrawHandlers.isEmpty()) {
+            Slog.w(TAG, "prepareSync with mDrawHandlers, " + this + ", " + Debug.getCallers(8));
+        }
         if (!super.prepareSync()) {
             return false;
         }
@@ -5939,7 +5938,18 @@
         // to draw even if the children draw first or don't need to sync, so we start
         // in WAITING state rather than READY.
         mSyncState = SYNC_STATE_WAITING_FOR_DRAW;
+
+        if (mPrepareSyncSeqId > 0) {
+            // another prepareSync during existing sync (eg. reparented), so pre-emptively
+            // drop buffer (if exists). If the buffer hasn't been received yet, it will be
+            // dropped in finishDrawing.
+            ProtoLog.d(WM_DEBUG_SYNC_ENGINE, "Preparing to sync a window that was already in the"
+                            + " sync, so try dropping buffer. win=%s", this);
+            dropBufferFrom(mSyncTransaction);
+        }
+
         mSyncSeqId++;
+        mPrepareSyncSeqId = mSyncSeqId;
         requestRedrawForSync();
         return true;
     }
@@ -5960,6 +5970,13 @@
         if (mSyncState == SYNC_STATE_WAITING_FOR_DRAW && mRedrawForSyncReported) {
             mClientWasDrawingForSync = true;
         }
+        mPrepareSyncSeqId = 0;
+        if (cancel) {
+            // This is leaving sync so any buffers left in the sync have a chance of
+            // being applied out-of-order and can also block the buffer queue for this
+            // window. To prevent this, drop the buffer.
+            dropBufferFrom(mSyncTransaction);
+        }
         super.finishSync(outMergedTransaction, cancel);
     }
 
@@ -5981,6 +5998,17 @@
                     .notifyStartingWindowDrawn(mActivityRecord);
         }
 
+        final boolean syncActive = mPrepareSyncSeqId > 0;
+        final boolean syncStillPending = syncActive && mPrepareSyncSeqId > syncSeqId;
+        if (syncStillPending && postDrawTransaction != null) {
+            ProtoLog.d(WM_DEBUG_SYNC_ENGINE, "Got a buffer for request id=%d but latest request is"
+                    + " id=%d. Since the buffer is out-of-date, drop it. win=%s", syncSeqId,
+                    mPrepareSyncSeqId, this);
+            // sync is waiting for a newer seqId, so this buffer is obsolete and can be dropped
+            // to free up the buffer queue.
+            dropBufferFrom(postDrawTransaction);
+        }
+
         final boolean hasSyncHandlers = executeDrawHandlers(postDrawTransaction, syncSeqId);
 
         boolean skipLayout = false;
@@ -5990,15 +6018,18 @@
         if (asyncRotationController != null
                 && asyncRotationController.handleFinishDrawing(this, postDrawTransaction)) {
             // Consume the transaction because the controller will apply it with fade animation.
-            // Layout is not needed because the window will be hidden by the fade leash. Clear
-            // sync state because its sync transaction doesn't need to be merged to sync group.
+            // Layout is not needed because the window will be hidden by the fade leash.
             postDrawTransaction = null;
             skipLayout = true;
-            clearSyncState();
-        } else if (onSyncFinishedDrawing() && postDrawTransaction != null) {
-            mSyncTransaction.merge(postDrawTransaction);
-            // Consume the transaction because the sync group will merge it.
-            postDrawTransaction = null;
+        } else if (syncActive) {
+            if (!syncStillPending) {
+                onSyncFinishedDrawing();
+            }
+            if (postDrawTransaction != null) {
+                mSyncTransaction.merge(postDrawTransaction);
+                // Consume the transaction because the sync group will merge it.
+                postDrawTransaction = null;
+            }
         }
 
         final boolean layoutNeeded =
@@ -6012,7 +6043,6 @@
         // We could be more subtle with Integer.MAX_VALUE and track a seqId in the timeout.
         finishDrawing(null, Integer.MAX_VALUE);
         mWmService.mH.removeMessages(WINDOW_STATE_BLAST_SYNC_TIMEOUT, this);
-        if (!useBLASTSync()) return;
     }
 
     @Override
@@ -6049,6 +6079,12 @@
         if (mRedrawForSyncReported) {
             return false;
         }
+        // TODO(b/233286785): Remove mIsWallpaper once WallpaperService handles syncId of relayout.
+        if (mInRelayout && !mIsWallpaper) {
+            // The last sync seq id will return to the client, so there is no need to request the
+            // client to redraw.
+            return false;
+        }
         return useBLASTSync();
     }
 
@@ -6081,6 +6117,10 @@
      * See {@link WindowState#mDrawHandlers}
      */
     void applyWithNextDraw(Consumer<SurfaceControl.Transaction> consumer) {
+        if (mSyncState != SYNC_STATE_NONE) {
+            Slog.w(TAG, "applyWithNextDraw with mSyncState=" + mSyncState + ", " + this
+                    + ", " + Debug.getCallers(8));
+        }
         mSyncSeqId++;
         mDrawHandlers.add(new DrawHandler(mSyncSeqId, consumer));
 
@@ -6219,4 +6259,9 @@
                           @WindowTraceLogLevel int logLevel) {
         dumpDebug(proto, fieldId, logLevel);
     }
+
+    public boolean cancelAndRedraw() {
+        // Cancel any draw requests during a sync.
+        return mPrepareSyncSeqId > 0;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 5f43800..fd379bf 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -139,6 +139,12 @@
                 "Destroying surface %s called by %s", this, Debug.getCallers(8));
         try {
             if (mSurfaceControl != null) {
+                if (mAnimator.mIsWallpaper && !mAnimator.mWin.mWindowRemovalAllowed
+                        && !mAnimator.mWin.mRemoveOnExit) {
+                    // The wallpaper surface should have the same lifetime as its window.
+                    Slog.e(TAG, "Unexpected removing wallpaper surface of " + mAnimator.mWin
+                            + " by " + Debug.getCallers(8));
+                }
                 t.remove(mSurfaceControl);
             }
         } catch (RuntimeException e) {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 18f60b1..437c934 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -18,15 +18,12 @@
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT;
-import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
-import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowContainerChildProto.WINDOW_TOKEN;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -37,6 +34,7 @@
 import static com.android.server.wm.WindowTokenProto.WINDOW_CONTAINER;
 
 import android.annotation.CallSuper;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -363,11 +361,7 @@
 
     @Override
     void assignLayer(SurfaceControl.Transaction t, int layer) {
-        if (windowType == TYPE_DOCK_DIVIDER) {
-            // See {@link DisplayContent#mSplitScreenDividerAnchor}
-            super.assignRelativeLayer(t,
-                    mDisplayContent.getDefaultTaskDisplayArea().getSplitScreenDividerAnchor(), 1);
-        } else if (mRoundedCornerOverlay) {
+        if (mRoundedCornerOverlay) {
             super.assignLayer(t, WindowManagerPolicy.SCREEN_DECOR_DISPLAY_OVERLAY_LAYER);
         } else {
             super.assignLayer(t, layer);
@@ -454,8 +448,14 @@
         if (mFixedRotationTransformState != null) {
             mFixedRotationTransformState.disassociate(this);
         }
+        // TODO(b/233855302): Remove TaskFragment override if the DisplayContent uses the same
+        //  bounds for screenLayout calculation.
+        final Configuration overrideConfig = new Configuration(config);
+        overrideConfig.screenLayout = TaskFragment.computeScreenLayoutOverride(
+                overrideConfig.screenLayout, overrideConfig.screenWidthDp,
+                overrideConfig.screenHeightDp);
         mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
-                new Configuration(config), mDisplayContent.getRotation());
+                overrideConfig, mDisplayContent.getRotation());
         mFixedRotationTransformState.mAssociatedTokens.add(this);
         mDisplayContent.getDisplayPolicy().simulateLayoutDisplay(displayFrames);
         onFixedRotationStatePrepared();
@@ -505,7 +505,7 @@
         for (int i = mFixedRotationTransformState.mAssociatedTokens.size() - 1; i >= 0; i--) {
             final ActivityRecord r =
                     mFixedRotationTransformState.mAssociatedTokens.get(i).asActivityRecord();
-            if (r != null && r.isAnimating(TRANSITION | PARENTS)) {
+            if (r != null && r.isInTransition()) {
                 return true;
             }
         }
@@ -569,13 +569,12 @@
      * the same rotation.
      */
     @Nullable
-    SurfaceControl getOrCreateFixedRotationLeash() {
+    SurfaceControl getOrCreateFixedRotationLeash(@NonNull SurfaceControl.Transaction t) {
         if (!mTransitionController.isShellTransitionsEnabled()) return null;
         final int rotation = getRelativeDisplayRotation();
         if (rotation == Surface.ROTATION_0) return mFixedRotationTransformLeash;
         if (mFixedRotationTransformLeash != null) return mFixedRotationTransformLeash;
 
-        final SurfaceControl.Transaction t = getSyncTransaction();
         final SurfaceControl leash = makeSurface().setContainerLayer()
                 .setParent(getParentSurfaceControl())
                 .setName(getSurfaceControl() + " - rotation-leash")
@@ -591,6 +590,15 @@
         return mFixedRotationTransformLeash;
     }
 
+    /**
+     * @return the leash which represents this window as if it was non-rotated. Will be null if
+     *         there isn't one.
+     */
+    @Nullable
+    SurfaceControl getFixedRotationLeash() {
+        return mFixedRotationTransformLeash;
+    }
+
     void removeFixedRotationLeash() {
         if (mFixedRotationTransformLeash == null) return;
         final SurfaceControl.Transaction t = getSyncTransaction();
@@ -664,6 +672,15 @@
         }
     }
 
+    @Override
+    boolean prepareSync() {
+        if (mDisplayContent != null && mDisplayContent.isRotationChanging()
+                && AsyncRotationController.canBeAsync(this)) {
+            return false;
+        }
+        return super.prepareSync();
+    }
+
     @CallSuper
     @Override
     public void dumpDebug(ProtoOutputStream proto, long fieldId,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 9d708ad..06fb4b0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -12533,8 +12533,8 @@
                 .setContentIntent(locationSettingsIntent)
                 .setAutoCancel(true)
                 .build();
-        mInjector.getNotificationManager().notify(SystemMessage.NOTE_LOCATION_CHANGED,
-                notification);
+        mHandler.post(() -> mInjector.getNotificationManager().notify(
+                SystemMessage.NOTE_LOCATION_CHANGED, notification));
     }
 
     private String getLocationChangedTitle() {
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
index 09565b4..d675b0a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
@@ -19,6 +19,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
@@ -49,6 +50,7 @@
 import android.hardware.power.Mode;
 import android.os.Bundle;
 import android.os.PowerManagerInternal;
+import android.os.UserManager;
 import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
 import android.provider.DeviceConfig;
@@ -69,6 +71,8 @@
 import org.mockito.MockitoSession;
 import org.mockito.quality.Strictness;
 
+import java.io.File;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -79,7 +83,7 @@
 @Presubmit
 public class GameManagerServiceTests {
     @Mock MockContext mMockContext;
-    private static final String TAG = "GameServiceTests";
+    private static final String TAG = "GameManagerServiceTests";
     private static final String PACKAGE_NAME_INVALID = "com.android.app";
     private static final int USER_ID_1 = 1001;
     private static final int USER_ID_2 = 1002;
@@ -91,6 +95,8 @@
     private PackageManager mMockPackageManager;
     @Mock
     private PowerManagerInternal mMockPowerManager;
+    @Mock
+    private UserManager mMockUserManager;
 
     // Stolen from ConnectivityServiceTest.MockContext
     class MockContext extends ContextWrapper {
@@ -150,6 +156,15 @@
         public PackageManager getPackageManager() {
             return mMockPackageManager;
         }
+
+        @Override
+        public Object getSystemService(String name) {
+            switch (name) {
+                case Context.USER_SERVICE:
+                    return mMockUserManager;
+            }
+            throw new UnsupportedOperationException("Couldn't find system service: " + name);
+        }
     }
 
     @Before
@@ -198,6 +213,19 @@
         mTestLooper.dispatchAll();
     }
 
+    private void switchUser(GameManagerService gameManagerService, int from, int to) {
+        UserInfo userInfoFrom = new UserInfo(from, "name", 0);
+        UserInfo userInfoTo = new UserInfo(to, "name", 0);
+        gameManagerService.onUserSwitching(/* from */ new SystemService.TargetUser(userInfoFrom),
+                /* to */ new SystemService.TargetUser(userInfoTo));
+        mTestLooper.dispatchAll();
+    }
+
+    private void mockManageUsersGranted() {
+        mMockContext.setPermission(Manifest.permission.MANAGE_USERS,
+                PackageManager.PERMISSION_GRANTED);
+    }
+
     private void mockModifyGameModeGranted() {
         mMockContext.setPermission(Manifest.permission.MANAGE_GAME_MODE,
                 PackageManager.PERMISSION_GRANTED);
@@ -819,6 +847,7 @@
         GameManagerService gameManagerService = new GameManagerService(
                 mMockContext, mTestLooper.getLooper());
         startUser(gameManagerService, USER_ID_1);
+
         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
                 GameManager.GAME_MODE_PERFORMANCE, "120", "0.3");
         gameManagerService.setGameModeConfigOverride(mPackageName, USER_ID_1,
@@ -1246,4 +1275,133 @@
     public void testSetGameStateNotLoading() {
         setGameState(false);
     }
+
+    private List<String> readGameModeInterventionList() throws Exception {
+        final File interventionFile = new File(InstrumentationRegistry.getContext().getFilesDir(),
+                "system/game_mode_intervention.list");
+        assertNotNull(interventionFile);
+        List<String> output = Files.readAllLines(interventionFile.toPath());
+        return output;
+    }
+
+    private void mockInterventionListForMultipleUsers() {
+        final String[] packageNames = new String[] {"com.android.app0",
+                "com.android.app1", "com.android.app2"};
+
+        final ApplicationInfo[] applicationInfos = new ApplicationInfo[3];
+        final PackageInfo[] pis = new PackageInfo[3];
+        for (int i = 0; i < 3; ++i) {
+            applicationInfos[i] = new ApplicationInfo();
+            applicationInfos[i].category = ApplicationInfo.CATEGORY_GAME;
+            applicationInfos[i].packageName = packageNames[i];
+
+            pis[i] = new PackageInfo();
+            pis[i].packageName = packageNames[i];
+            pis[i].applicationInfo = applicationInfos[i];
+        }
+
+        final List<PackageInfo> userOnePackages = new ArrayList<>();
+        final List<PackageInfo> userTwoPackages = new ArrayList<>();
+        userOnePackages.add(pis[1]);
+        userTwoPackages.add(pis[0]);
+        userTwoPackages.add(pis[2]);
+
+        final List<UserInfo> userInfos = new ArrayList<>(2);
+        userInfos.add(new UserInfo());
+        userInfos.add(new UserInfo());
+        userInfos.get(0).id = USER_ID_1;
+        userInfos.get(1).id = USER_ID_2;
+
+        when(mMockPackageManager.getInstalledPackagesAsUser(anyInt(), eq(USER_ID_1)))
+                .thenReturn(userOnePackages);
+        when(mMockPackageManager.getInstalledPackagesAsUser(anyInt(), eq(USER_ID_2)))
+                .thenReturn(userTwoPackages);
+        when(mMockUserManager.getUsers()).thenReturn(userInfos);
+    }
+
+    @Test
+    public void testVerifyInterventionList() throws Exception {
+        mockDeviceConfigAll();
+        mockInterventionListForMultipleUsers();
+        mockManageUsersGranted();
+        mockModifyGameModeGranted();
+        final Context context = InstrumentationRegistry.getContext();
+        GameManagerService gameManagerService =
+                new GameManagerService(mMockContext,
+                                       mTestLooper.getLooper(),
+                                       context.getFilesDir());
+        startUser(gameManagerService, USER_ID_1);
+        startUser(gameManagerService, USER_ID_2);
+
+        gameManagerService.setGameModeConfigOverride("com.android.app0", USER_ID_2,
+                GameManager.GAME_MODE_PERFORMANCE, "120", "0.6");
+        gameManagerService.setGameModeConfigOverride("com.android.app2", USER_ID_2,
+                GameManager.GAME_MODE_BATTERY, "60", "0.5");
+        mTestLooper.dispatchAll();
+
+        /* Expected fileOutput (order may vary)
+         com.android.app2 <UID>   0   2   angle=0,scaling=0.5,fps=90  3   angle=0,scaling=0.5,fps=60
+         com.android.app1 <UID>   1   2   angle=0,scaling=0.5,fps=90  3   angle=0,scaling=0.7,fps=30
+         com.android.app0 <UID>   0   2   angle=0,scaling=0.6,fps=120 3   angle=0,scaling=0.7,fps=30
+
+         The current game mode would only be set to non-zero if the current user have that game
+         installed.
+        */
+
+        List<String> fileOutput = readGameModeInterventionList();
+        assertEquals(fileOutput.size(), 3);
+
+        String[] splitLine = fileOutput.get(0).split("\\s+");
+        assertEquals(splitLine[0], "com.android.app2");
+        assertEquals(splitLine[2], "3");
+        assertEquals(splitLine[3], "2");
+        assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
+        assertEquals(splitLine[5], "3");
+        assertEquals(splitLine[6], "angle=0,scaling=0.5,fps=60");
+        splitLine = fileOutput.get(1).split("\\s+");
+        assertEquals(splitLine[0], "com.android.app1");
+        assertEquals(splitLine[2], "0");
+        assertEquals(splitLine[3], "2");
+        assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
+        assertEquals(splitLine[5], "3");
+        assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
+        splitLine = fileOutput.get(2).split("\\s+");
+        assertEquals(splitLine[0], "com.android.app0");
+        assertEquals(splitLine[2], "2");
+        assertEquals(splitLine[3], "2");
+        assertEquals(splitLine[4], "angle=0,scaling=0.6,fps=120");
+        assertEquals(splitLine[5], "3");
+        assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
+
+        switchUser(gameManagerService, USER_ID_2, USER_ID_1);
+        gameManagerService.setGameMode("com.android.app1",
+                GameManager.GAME_MODE_BATTERY, USER_ID_1);
+        mTestLooper.dispatchAll();
+
+        fileOutput = readGameModeInterventionList();
+        assertEquals(fileOutput.size(), 3);
+
+        splitLine = fileOutput.get(0).split("\\s+");
+        assertEquals(splitLine[0], "com.android.app2");
+        assertEquals(splitLine[2], "0");
+        assertEquals(splitLine[3], "2");
+        assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
+        assertEquals(splitLine[5], "3");
+        assertEquals(splitLine[6], "angle=0,scaling=0.5,fps=60");
+        splitLine = fileOutput.get(1).split("\\s+");
+        assertEquals(splitLine[0], "com.android.app1");
+        assertEquals(splitLine[2], "3");
+        assertEquals(splitLine[3], "2");
+        assertEquals(splitLine[4], "angle=0,scaling=0.5,fps=90");
+        assertEquals(splitLine[5], "3");
+        assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
+        splitLine = fileOutput.get(2).split("\\s+");
+        assertEquals(splitLine[0], "com.android.app0");
+        assertEquals(splitLine[2], "0");
+        assertEquals(splitLine[3], "2");
+        assertEquals(splitLine[4], "angle=0,scaling=0.6,fps=120");
+        assertEquals(splitLine[5], "3");
+        assertEquals(splitLine[6], "angle=0,scaling=0.7,fps=30");
+
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
index 91c45b4..adcbe6b 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
@@ -15,12 +15,18 @@
  */
 package com.android.server.audio;
 
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import android.app.AppOpsManager;
 import android.content.Context;
+import android.media.AudioSystem;
 import android.os.Looper;
 import android.os.UserHandle;
 import android.util.Log;
@@ -33,6 +39,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.Spy;
 
 @MediumTest
@@ -46,6 +53,7 @@
     private AudioSystemAdapter mAudioSystem;
     @Spy private SystemServerAdapter mSpySystemServer;
     private SettingsAdapter mSettingsAdapter;
+    @Mock private AppOpsManager mMockAppOpsManager;
     // the class being unit-tested here
     private AudioService mAudioService;
 
@@ -61,8 +69,11 @@
         mAudioSystem = new NoOpAudioSystemAdapter();
         mSpySystemServer = spy(new NoOpSystemServerAdapter());
         mSettingsAdapter = new NoOpSettingsAdapter();
+        mMockAppOpsManager = mock(AppOpsManager.class);
+        when(mMockAppOpsManager.noteOp(anyInt(), anyInt(), anyString(), anyString(), anyString()))
+                .thenReturn(AppOpsManager.MODE_ALLOWED);
         mAudioService = new AudioService(mContext, mAudioSystem, mSpySystemServer,
-                mSettingsAdapter, null);
+                mSettingsAdapter, null, mMockAppOpsManager);
     }
 
     /**
@@ -113,4 +124,33 @@
             reset(mSpySystemServer);
         }
     }
+
+    @Test
+    public void testRingNotifAlias() throws Exception {
+        Log.i(TAG, "running testRingNotifAlias");
+        Assert.assertNotNull(mAudioService);
+        // TODO add initialization message that can be caught here instead of sleeping
+        Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS); // wait for full AudioService initialization
+
+        // test with aliasing RING and NOTIFICATION
+        mAudioService.setNotifAliasRingForTest(true);
+        final int ringMaxVol = mAudioService.getStreamMaxVolume(AudioSystem.STREAM_RING);
+        final int ringMinVol = mAudioService.getStreamMinVolume(AudioSystem.STREAM_RING);
+        final int ringVol = ringMinVol + 1;
+        // set a value for NOTIFICATION so it's not at the target test value (ringMaxVol)
+        mAudioService.setStreamVolume(AudioSystem.STREAM_NOTIFICATION,
+                ringVol, 0, "bla");
+        mAudioService.setStreamVolume(AudioSystem.STREAM_RING, ringMaxVol, 0, "bla");
+        Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS);
+        Assert.assertEquals(ringMaxVol,
+                mAudioService.getStreamVolume(AudioSystem.STREAM_NOTIFICATION));
+
+        // test with no aliasing between RING and NOTIFICATION
+        mAudioService.setNotifAliasRingForTest(false);
+        mAudioService.setStreamVolume(AudioSystem.STREAM_RING, ringVol, 0, "bla");
+        mAudioService.setStreamVolume(AudioSystem.STREAM_NOTIFICATION, ringMaxVol, 0, "bla");
+        Assert.assertEquals(ringVol, mAudioService.getStreamVolume(AudioSystem.STREAM_RING));
+        Assert.assertEquals(ringMaxVol, mAudioService.getStreamVolume(
+                AudioSystem.STREAM_NOTIFICATION));
+    }
 }
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 f242fda..c80547c 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
@@ -213,7 +213,7 @@
                 mContext.getSystemService(WindowManager.class), threadVerifier);
 
         mAssociationInfo = new AssociationInfo(1, 0, null,
-                MacAddress.BROADCAST_ADDRESS, "", null, true, false, 0, 0);
+                MacAddress.BROADCAST_ADDRESS, "", null, true, false, false, 0, 0);
 
         VirtualDeviceParams params = new VirtualDeviceParams
                 .Builder()
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index fe3034d..038cbc0 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -76,12 +76,15 @@
     private TestDeviceStatePolicy mPolicy;
     private TestDeviceStateProvider mProvider;
     private DeviceStateManagerService mService;
+    private TestSystemPropertySetter mSysPropSetter;
 
     @Before
     public void setup() {
         mProvider = new TestDeviceStateProvider();
         mPolicy = new TestDeviceStatePolicy(mProvider);
-        mService = new DeviceStateManagerService(InstrumentationRegistry.getContext(), mPolicy);
+        mSysPropSetter = new TestSystemPropertySetter();
+        mService = new DeviceStateManagerService(InstrumentationRegistry.getContext(), mPolicy,
+                mSysPropSetter);
 
         // Necessary to allow us to check for top app process id in tests
         mService.mActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
@@ -107,6 +110,8 @@
     public void baseStateChanged() {
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.empty());
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 DEFAULT_DEVICE_STATE.getIdentifier());
@@ -115,6 +120,8 @@
         flushHandler();
         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.empty());
+        assertEquals(mSysPropSetter.getValue(),
+                OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE));
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 OTHER_DEVICE_STATE.getIdentifier());
@@ -128,6 +135,8 @@
         flushHandler();
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.of(OTHER_DEVICE_STATE));
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE));
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 OTHER_DEVICE_STATE.getIdentifier());
@@ -136,6 +145,8 @@
         flushHandler();
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.of(OTHER_DEVICE_STATE));
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 OTHER_DEVICE_STATE.getIdentifier());
@@ -157,6 +168,8 @@
 
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.empty());
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 DEFAULT_DEVICE_STATE.getIdentifier());
@@ -170,6 +183,8 @@
 
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.empty());
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 DEFAULT_DEVICE_STATE.getIdentifier());
@@ -182,6 +197,8 @@
 
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.empty());
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE,
                 OTHER_DEVICE_STATE);
@@ -193,6 +210,8 @@
         // supported.
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.empty());
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE);
 
@@ -211,6 +230,8 @@
 
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.empty());
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE,
                 OTHER_DEVICE_STATE);
@@ -223,6 +244,8 @@
         // supported.
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.empty());
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertThat(mService.getSupportedStates()).asList().containsExactly(DEFAULT_DEVICE_STATE,
                 OTHER_DEVICE_STATE);
@@ -315,6 +338,8 @@
                 TestDeviceStateManagerCallback.STATUS_ACTIVE);
         // Committed state changes as there is a requested override.
         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
+        assertEquals(mSysPropSetter.getValue(),
+                OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getOverrideState().get(), OTHER_DEVICE_STATE);
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
@@ -333,6 +358,8 @@
                 TestDeviceStateManagerCallback.STATUS_CANCELED);
         // Committed state is set back to the requested state once the override is cleared.
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertFalse(mService.getOverrideState().isPresent());
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
@@ -385,9 +412,10 @@
         // callback.
         assertEquals(callback.getLastNotifiedStatus(secondRequestToken),
                 TestDeviceStateManagerCallback.STATUS_UNKNOWN);
-
         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.of(DEFAULT_DEVICE_STATE));
+        assertEquals(mSysPropSetter.getValue(),
+                OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 DEFAULT_DEVICE_STATE.getIdentifier());
@@ -397,6 +425,8 @@
 
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.empty());
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 DEFAULT_DEVICE_STATE.getIdentifier());
@@ -412,6 +442,8 @@
 
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getPendingState(), Optional.empty());
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 DEFAULT_DEVICE_STATE.getIdentifier());
@@ -458,6 +490,8 @@
         // Committed state changes as there is a requested override.
         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
+        assertEquals(mSysPropSetter.getValue(),
+                OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
         assertEquals(mService.getOverrideState().get(), OTHER_DEVICE_STATE);
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 OTHER_DEVICE_STATE.getIdentifier());
@@ -471,6 +505,8 @@
         // Committed state is set back to the requested state once the override is cleared.
         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
         assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE));
+        assertEquals(mSysPropSetter.getValue(),
+                OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
         assertFalse(mService.getOverrideState().isPresent());
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
                 OTHER_DEVICE_STATE.getIdentifier());
@@ -495,6 +531,8 @@
                 TestDeviceStateManagerCallback.STATUS_ACTIVE);
         // Committed state changes as there is a requested override.
         assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
+        assertEquals(mSysPropSetter.getValue(),
+                OTHER_DEVICE_STATE.getIdentifier() + ":" + OTHER_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertEquals(mService.getOverrideState().get(), OTHER_DEVICE_STATE);
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
@@ -509,6 +547,8 @@
         // Committed state is set back to the requested state as the override state is no longer
         // supported.
         assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
+        assertEquals(mSysPropSetter.getValue(),
+                DEFAULT_DEVICE_STATE.getIdentifier() + ":" + DEFAULT_DEVICE_STATE.getName());
         assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
         assertFalse(mService.getOverrideState().isPresent());
         assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
@@ -673,4 +713,18 @@
             return mLastNotifiedStatus.getOrDefault(requestToken, STATUS_UNKNOWN);
         }
     }
+
+    private static final class TestSystemPropertySetter implements
+            DeviceStateManagerService.SystemPropertySetter {
+        private String mValue;
+
+        @Override
+        public void setDebugTracingDeviceStateProperty(String value) {
+            mValue = value;
+        }
+
+        public String getValue() {
+            return mValue;
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessThrottlerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessThrottlerTest.java
index 0ed90d2..6a6cd6c 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessThrottlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessThrottlerTest.java
@@ -16,13 +16,11 @@
 
 package com.android.server.display;
 
-import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -34,17 +32,18 @@
 import android.os.IThermalService;
 import android.os.Message;
 import android.os.PowerManager;
-import android.os.Temperature.ThrottlingStatus;
 import android.os.Temperature;
+import android.os.Temperature.ThrottlingStatus;
 import android.os.test.TestLooper;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.os.BackgroundThread;
 import com.android.server.display.BrightnessThrottler.Injector;
-import com.android.server.display.DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel;
 import com.android.server.display.DisplayDeviceConfig.BrightnessThrottlingData;
+import com.android.server.display.DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -55,7 +54,6 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 @SmallTest
@@ -70,6 +68,8 @@
     @Mock IThermalService mThermalServiceMock;
     @Mock Injector mInjectorMock;
 
+    DisplayModeDirectorTest.FakeDeviceConfig mDeviceConfigFake;
+
     @Captor ArgumentCaptor<IThermalEventListener> mThermalEventListenerCaptor;
 
     @Before
@@ -83,6 +83,8 @@
                 return true;
             }
         });
+        mDeviceConfigFake = new DisplayModeDirectorTest.FakeDeviceConfig();
+        when(mInjectorMock.getDeviceConfig()).thenReturn(mDeviceConfigFake);
 
     }
 
@@ -292,6 +294,170 @@
         assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE, throttler.getBrightnessMaxReason());
     }
 
+    @Test public void testUpdateThrottlingData() throws Exception {
+        // Initialise brightness throttling levels
+        // Ensure that they are overridden by setting the data through device config.
+        final ThrottlingLevel level = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
+                0.25f);
+        List<ThrottlingLevel> levels = new ArrayList<>();
+        levels.add(level);
+        final BrightnessThrottlingData data = BrightnessThrottlingData.create(levels);
+        mDeviceConfigFake.setBrightnessThrottlingData("123,1,critical,0.4");
+        final BrightnessThrottler throttler = createThrottlerSupported(data);
+
+        verify(mThermalServiceMock).registerThermalEventListenerWithType(
+                mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
+        final IThermalEventListener listener = mThermalEventListenerCaptor.getValue();
+
+        // Set status too low to trigger throttling
+        listener.notifyThrottling(getSkinTemp(level.thermalStatus - 1));
+        mTestLooper.dispatchAll();
+        assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f);
+        assertFalse(throttler.isThrottled());
+
+        // Set status high enough to trigger throttling
+        listener.notifyThrottling(getSkinTemp(level.thermalStatus));
+        mTestLooper.dispatchAll();
+        assertEquals(0.4f, throttler.getBrightnessCap(), 0f);
+        assertTrue(throttler.isThrottled());
+
+        // Update thresholds
+        // This data is equivalent to the string "123,1,critical,0.8", passed below
+        final ThrottlingLevel newLevel = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
+                0.8f);
+        // Set new (valid) data from device config
+        mDeviceConfigFake.setBrightnessThrottlingData("123,1,critical,0.8");
+
+        // Set status too low to trigger throttling
+        listener.notifyThrottling(getSkinTemp(newLevel.thermalStatus - 1));
+        mTestLooper.dispatchAll();
+        assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f);
+        assertFalse(throttler.isThrottled());
+
+        // Set status high enough to trigger throttling
+        listener.notifyThrottling(getSkinTemp(newLevel.thermalStatus));
+        mTestLooper.dispatchAll();
+        assertEquals(newLevel.brightness, throttler.getBrightnessCap(), 0f);
+        assertTrue(throttler.isThrottled());
+    }
+
+    @Test public void testInvalidThrottlingStrings() throws Exception {
+        // Initialise brightness throttling levels
+        // Ensure that they are not overridden by invalid data through device config.
+        final ThrottlingLevel level = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
+                0.25f);
+        List<ThrottlingLevel> levels = new ArrayList<>();
+        levels.add(level);
+        final BrightnessThrottlingData data = BrightnessThrottlingData.create(levels);
+        final BrightnessThrottler throttler = createThrottlerSupported(data);
+        verify(mThermalServiceMock).registerThermalEventListenerWithType(
+                mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
+        final IThermalEventListener listener = mThermalEventListenerCaptor.getValue();
+
+        // None of these are valid so shouldn't override the original data
+        mDeviceConfigFake.setBrightnessThrottlingData("321,1,critical,0.4");  // Not the current id
+        testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
+        mDeviceConfigFake.setBrightnessThrottlingData("123,0,critical,0.4");  // Incorrect number
+        testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
+        mDeviceConfigFake.setBrightnessThrottlingData("123,2,critical,0.4");  // Incorrect number
+        testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
+        mDeviceConfigFake.setBrightnessThrottlingData("123,1,invalid,0.4");   // Invalid level
+        testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
+        mDeviceConfigFake.setBrightnessThrottlingData("123,1,critical,none"); // Invalid brightness
+        testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
+        mDeviceConfigFake.setBrightnessThrottlingData("123,1,critical,-3");   // Invalid brightness
+        testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
+        mDeviceConfigFake.setBrightnessThrottlingData("invalid string");      // Invalid format
+        testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
+        mDeviceConfigFake.setBrightnessThrottlingData("");                    // Invalid format
+        testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f);
+    }
+
+    private void testThrottling(BrightnessThrottler throttler, IThermalEventListener listener,
+            float tooLowCap, float tooHighCap) throws Exception {
+        final ThrottlingLevel level = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
+                tooHighCap);
+
+        // Set status too low to trigger throttling
+        listener.notifyThrottling(getSkinTemp(level.thermalStatus - 1));
+        mTestLooper.dispatchAll();
+        assertEquals(tooLowCap, throttler.getBrightnessCap(), 0f);
+        assertFalse(throttler.isThrottled());
+
+        // Set status high enough to trigger throttling
+        listener.notifyThrottling(getSkinTemp(level.thermalStatus));
+        mTestLooper.dispatchAll();
+        assertEquals(tooHighCap, throttler.getBrightnessCap(), 0f);
+        assertTrue(throttler.isThrottled());
+    }
+
+    @Test public void testMultipleConfigPoints() throws Exception {
+        // Initialise brightness throttling levels
+        final ThrottlingLevel level = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL,
+                0.25f);
+        List<ThrottlingLevel> levels = new ArrayList<>();
+        levels.add(level);
+        final BrightnessThrottlingData data = BrightnessThrottlingData.create(levels);
+
+        // These are identical to the string set below
+        final ThrottlingLevel levelSevere = new ThrottlingLevel(PowerManager.THERMAL_STATUS_SEVERE,
+                0.9f);
+        final ThrottlingLevel levelCritical = new ThrottlingLevel(
+                PowerManager.THERMAL_STATUS_CRITICAL, 0.5f);
+        final ThrottlingLevel levelEmergency = new ThrottlingLevel(
+                PowerManager.THERMAL_STATUS_EMERGENCY, 0.1f);
+
+        mDeviceConfigFake.setBrightnessThrottlingData(
+                "123,3,severe,0.9,critical,0.5,emergency,0.1");
+        final BrightnessThrottler throttler = createThrottlerSupported(data);
+
+        verify(mThermalServiceMock).registerThermalEventListenerWithType(
+                mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN));
+        final IThermalEventListener listener = mThermalEventListenerCaptor.getValue();
+
+        // Ensure that the multiple levels set via the string through the device config correctly
+        // override the original display device config ones.
+
+        // levelSevere
+        // Set status too low to trigger throttling
+        listener.notifyThrottling(getSkinTemp(levelSevere.thermalStatus - 1));
+        mTestLooper.dispatchAll();
+        assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f);
+        assertFalse(throttler.isThrottled());
+
+        // Set status high enough to trigger throttling
+        listener.notifyThrottling(getSkinTemp(levelSevere.thermalStatus));
+        mTestLooper.dispatchAll();
+        assertEquals(0.9f, throttler.getBrightnessCap(), 0f);
+        assertTrue(throttler.isThrottled());
+
+        // levelCritical
+        // Set status too low to trigger throttling
+        listener.notifyThrottling(getSkinTemp(levelCritical.thermalStatus - 1));
+        mTestLooper.dispatchAll();
+        assertEquals(0.9f, throttler.getBrightnessCap(), 0f);
+        assertTrue(throttler.isThrottled());
+
+        // Set status high enough to trigger throttling
+        listener.notifyThrottling(getSkinTemp(levelCritical.thermalStatus));
+        mTestLooper.dispatchAll();
+        assertEquals(0.5f, throttler.getBrightnessCap(), 0f);
+        assertTrue(throttler.isThrottled());
+
+        //levelEmergency
+        // Set status too low to trigger throttling
+        listener.notifyThrottling(getSkinTemp(levelEmergency.thermalStatus - 1));
+        mTestLooper.dispatchAll();
+        assertEquals(0.5f, throttler.getBrightnessCap(), 0f);
+        assertTrue(throttler.isThrottled());
+
+        // Set status high enough to trigger throttling
+        listener.notifyThrottling(getSkinTemp(levelEmergency.thermalStatus));
+        mTestLooper.dispatchAll();
+        assertEquals(0.1f, throttler.getBrightnessCap(), 0f);
+        assertTrue(throttler.isThrottled());
+    }
+
     private void assertThrottlingLevelsEquals(
             List<ThrottlingLevel> expected,
             List<ThrottlingLevel> actual) {
@@ -307,12 +473,13 @@
     }
 
     private BrightnessThrottler createThrottlerUnsupported() {
-        return new BrightnessThrottler(mInjectorMock, mHandler, null, () -> {});
+        return new BrightnessThrottler(mInjectorMock, mHandler, mHandler, null, () -> {}, null);
     }
 
     private BrightnessThrottler createThrottlerSupported(BrightnessThrottlingData data) {
         assertNotNull(data);
-        return new BrightnessThrottler(mInjectorMock, mHandler, data, () -> {});
+        return new BrightnessThrottler(mInjectorMock, mHandler, BackgroundThread.getHandler(),
+                data, () -> {}, "123");
     }
 
     private Temperature getSkinTemp(@ThrottlingStatus int status) {
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index 5f1ff6b..1e97c1c 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -287,7 +287,7 @@
 
         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
 
-        final int[] displayIds = bs.getDisplayIds(/* includeDisabled= */ false);
+        final int displayIds[] = bs.getDisplayIds();
         final int size = displayIds.length;
         assertTrue(size > 0);
 
@@ -297,9 +297,7 @@
         );
         for (int i = 0; i < size; i++) {
             DisplayInfo info = bs.getDisplayInfo(displayIds[i]);
-            if (info != null) {
-                assertTrue(expectedDisplayTypeToViewPortTypeMapping.keySet().contains(info.type));
-            }
+            assertTrue(expectedDisplayTypeToViewPortTypeMapping.keySet().contains(info.type));
         }
 
         displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
@@ -1176,8 +1174,7 @@
             DisplayManagerService.BinderService displayManagerBinderService,
             FakeDisplayDevice displayDevice) {
 
-        final int[] displayIds = displayManagerBinderService.getDisplayIds(
-                /* includeDisabled= */ false);
+        final int[] displayIds = displayManagerBinderService.getDisplayIds();
         assertTrue(displayIds.length > 0);
         int displayId = Display.INVALID_DISPLAY;
         for (int i = 0; i < displayIds.length; i++) {
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index 864f315..968e1d8 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.display;
 
+import static android.hardware.display.DisplayManager.DeviceConfig.KEY_BRIGHTNESS_THROTTLING_DATA;
 import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_HIGH_AMBIENT_BRIGHTNESS_THRESHOLDS;
 import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_HIGH_DISPLAY_BRIGHTNESS_THRESHOLDS;
 import static android.hardware.display.DisplayManager.DeviceConfig.KEY_FIXED_REFRESH_RATE_LOW_AMBIENT_BRIGHTNESS_THRESHOLDS;
@@ -1902,6 +1903,11 @@
                     KEY_REFRESH_RATE_IN_HBM_HDR, String.valueOf(fps));
         }
 
+        void setBrightnessThrottlingData(String brightnessThrottlingData) {
+            putPropertyAndNotify(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
+                    KEY_BRIGHTNESS_THROTTLING_DATA, brightnessThrottlingData);
+        }
+
         void setLowDisplayBrightnessThresholds(int[] brightnessThresholds) {
             String thresholds = toPropertyValue(brightnessThresholds);
 
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
index 5b13145..cc68ba8 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -33,7 +33,6 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -54,8 +53,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.server.display.layout.Layout;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -82,7 +79,6 @@
     private TestLooper mLooper;
     private Handler mHandler;
     private PowerManager mPowerManager;
-    private DeviceStateToLayoutMap mDeviceStateToLayoutMapSpy;
 
     @Mock LogicalDisplayMapper.Listener mListenerMock;
     @Mock Context mContextMock;
@@ -137,11 +133,8 @@
 
         mLooper = new TestLooper();
         mHandler = new Handler(mLooper.getLooper());
-
-        mDeviceStateToLayoutMapSpy = spy(new DeviceStateToLayoutMap());
         mLogicalDisplayMapper = new LogicalDisplayMapper(mContextMock, mDisplayDeviceRepo,
-                mListenerMock, new DisplayManagerService.SyncRoot(), mHandler,
-                mDeviceStateToLayoutMapSpy);
+                mListenerMock, new DisplayManagerService.SyncRoot(), mHandler);
     }
 
 
@@ -420,86 +413,6 @@
                 /* isBootCompleted= */true));
     }
 
-    @Test public void testEnabledAndDisabledDisplays() {
-        DisplayAddress displayAddressOne = new TestUtils.TestDisplayAddress();
-        DisplayAddress displayAddressTwo = new TestUtils.TestDisplayAddress();
-        DisplayAddress displayAddressThree = new TestUtils.TestDisplayAddress();
-
-        TestDisplayDevice device1 = createDisplayDevice(displayAddressOne, Display.TYPE_INTERNAL,
-                600, 800,
-                DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
-        TestDisplayDevice device2 = createDisplayDevice(displayAddressTwo, Display.TYPE_INTERNAL,
-                200, 800,
-                DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
-        TestDisplayDevice device3 = createDisplayDevice(displayAddressThree, Display.TYPE_INTERNAL,
-                600, 900, DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
-
-        Layout threeDevicesEnabledLayout = new Layout();
-        threeDevicesEnabledLayout.createDisplayLocked(
-                displayAddressOne,
-                /* isDefault= */ true,
-                /* isEnabled= */ true);
-
-        threeDevicesEnabledLayout.createDisplayLocked(
-                displayAddressTwo,
-                /* isDefault= */ false,
-                /* isEnabled= */ true);
-        threeDevicesEnabledLayout.createDisplayLocked(
-                displayAddressThree,
-                /* isDefault= */ false,
-                /* isEnabled= */ true);
-
-        when(mDeviceStateToLayoutMapSpy.get(DeviceStateToLayoutMap.STATE_DEFAULT))
-                .thenReturn(threeDevicesEnabledLayout);
-
-        LogicalDisplay display1 = add(device1);
-        LogicalDisplay display2 = add(device2);
-        LogicalDisplay display3 = add(device3);
-
-        // ensure 3 displays are returned
-        int [] ids = mLogicalDisplayMapper.getDisplayIdsLocked(Process.SYSTEM_UID);
-        assertEquals(3, ids.length);
-        Arrays.sort(ids);
-        assertEquals(DEFAULT_DISPLAY, ids[0]);
-
-        Layout oneDeviceEnabledLayout = new Layout();
-        oneDeviceEnabledLayout.createDisplayLocked(
-                display1.getDisplayInfoLocked().address,
-                /* isDefault= */ true,
-                /* isEnabled= */ true);
-        oneDeviceEnabledLayout.createDisplayLocked(
-                display2.getDisplayInfoLocked().address,
-                /* isDefault= */ false,
-                /* isEnabled= */ false);
-        oneDeviceEnabledLayout.createDisplayLocked(
-                display3.getDisplayInfoLocked().address,
-                /* isDefault= */ false,
-                /* isEnabled= */ false);
-
-        when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(oneDeviceEnabledLayout);
-        when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(threeDevicesEnabledLayout);
-
-        mLogicalDisplayMapper
-                .setDeviceStateLocked(0, false);
-        mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED);
-        final int[] allDisplayIds = mLogicalDisplayMapper.getDisplayIdsLocked(
-                Process.SYSTEM_UID, false);
-        mLooper.dispatchAll();
-
-        // ensure only one display is returned
-        assertEquals(1, allDisplayIds.length);
-
-        mLogicalDisplayMapper
-                .setDeviceStateLocked(1, false);
-        mDisplayDeviceRepo.onDisplayDeviceEvent(device3, DISPLAY_DEVICE_EVENT_CHANGED);
-        final int[] threeDisplaysEnabled = mLogicalDisplayMapper.getDisplayIdsLocked(
-                Process.SYSTEM_UID, false);
-        mLooper.dispatchAll();
-
-        // ensure all three displays are returned
-        assertEquals(3, threeDisplaysEnabled.length);
-    }
-
     /////////////////
     // Helper Methods
     /////////////////
diff --git a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
index 363c26b..bbed1b6 100644
--- a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
@@ -16,11 +16,14 @@
 
 package com.android.server.display.color;
 
+import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -1130,6 +1133,15 @@
                 eq(ColorDisplayManager.COLOR_MODE_BOOSTED), any(), eq(Display.COLOR_MODE_INVALID));
     }
 
+    @Test
+    public void getColorMode_noAvailableModes_returnsNotSet() {
+        when(mResourcesSpy.getIntArray(R.array.config_availableColorModes))
+                .thenReturn(new int[] {});
+        startService();
+        verify(mDisplayTransformManager, never()).setColorMode(anyInt(), any(), anyInt());
+        assertThat(mBinderService.getColorMode()).isEqualTo(-1);
+    }
+
     /**
      * Configures Night display to use a custom schedule.
      *
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 75bd2cc..bc2c57e 100644
--- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
+++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
@@ -22,6 +22,7 @@
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
 
 import android.app.usage.TimeSparseArray;
 import android.app.usage.UsageEvents.Event;
@@ -440,6 +441,7 @@
         prevDB.readMappingsLocked();
         prevDB.init(1);
         prevDB.putUsageStats(UsageStatsManager.INTERVAL_DAILY, mIntervalStats);
+        Set<String> prevDBApps = mIntervalStats.packageStats.keySet();
         // Create a backup with a specific version
         byte[] blob = prevDB.getBackupPayload(KEY_USAGE_STATS, version);
         if (version >= 1 && version <= 3) {
@@ -447,6 +449,11 @@
                     "UsageStatsDatabase shouldn't be able to write backups as XML");
             return;
         }
+        if (version < 1 || version > UsageStatsDatabase.BACKUP_VERSION) {
+            assertFalse(blob != null && blob.length != 0,
+                    "UsageStatsDatabase shouldn't be able to write backups for unknown versions");
+            return;
+        }
 
         clearUsageStatsFiles();
 
@@ -454,9 +461,11 @@
         newDB.readMappingsLocked();
         newDB.init(1);
         // Attempt to restore the usage stats from the backup
-        newDB.applyRestoredPayload(KEY_USAGE_STATS, blob);
-        List<IntervalStats> stats = newDB.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, 0, mEndTime,
-                mIntervalStatsVerifier);
+        Set<String> restoredApps = newDB.applyRestoredPayload(KEY_USAGE_STATS, blob);
+        assertTrue(restoredApps.containsAll(prevDBApps),
+                "List of restored apps does not match list backed-up apps list.");
+        List<IntervalStats> stats = newDB.queryUsageStats(
+                UsageStatsManager.INTERVAL_DAILY, 0, mEndTime, mIntervalStatsVerifier);
 
         if (version > UsageStatsDatabase.BACKUP_VERSION || version < 1) {
             assertFalse(stats != null && !stats.isEmpty(),
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index c735bb7..8a96feb 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -778,8 +778,7 @@
         assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(),
                 service, TEST_TIMEOUT_MILLIS));
 
-        vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
-                HAPTIC_FEEDBACK_ATTRS);
+        vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), HAPTIC_FEEDBACK_ATTRS);
 
         // Wait before checking it never played a second effect.
         assertFalse(waitUntil(s -> mVibratorProviders.get(1).getAllEffectSegments().size() > 1,
@@ -793,49 +792,78 @@
     }
 
     @Test
-    public void vibrate_withOngoingAlarmVibration_ignoresEffect() throws Exception {
+    public void vibrate_withNewRepeatingVibration_cancelsOngoingEffect() throws Exception {
         mockVibrators(1);
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         VibratorManagerService service = createSystemReadyService();
 
         VibrationEffect alarmEffect = VibrationEffect.createWaveform(
                 new long[]{10_000, 10_000}, new int[]{128, 255}, -1);
-        vibrate(service, alarmEffect, new VibrationAttributes.Builder().setUsage(
-                VibrationAttributes.USAGE_ALARM).build());
+        vibrate(service, alarmEffect, ALARM_ATTRS);
 
         // VibrationThread will start this vibration async, so wait before checking it started.
         assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(),
                 service, TEST_TIMEOUT_MILLIS));
 
-        vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
-                HAPTIC_FEEDBACK_ATTRS);
+        VibrationEffect repeatingEffect = VibrationEffect.createWaveform(
+                new long[]{10_000, 10_000}, new int[]{128, 255}, 1);
+        vibrate(service, repeatingEffect, NOTIFICATION_ATTRS);
 
-        // Wait before checking it never played a second effect.
-        assertFalse(waitUntil(s -> mVibratorProviders.get(1).getAllEffectSegments().size() > 1,
-                service, /* timeout= */ 50));
+        // VibrationThread will start this vibration async, so wait before checking it started.
+        assertTrue(waitUntil(s -> mVibratorProviders.get(1).getAllEffectSegments().size() > 1,
+                service, TEST_TIMEOUT_MILLIS));
+
+        // The second vibration should have recorded that the vibrators were turned on.
+        verify(mBatteryStatsMock, times(2)).noteVibratorOn(anyInt(), anyLong());
     }
 
     @Test
-    public void vibrate_withOngoingRingtoneVibration_ignoresEffect() throws Exception {
+    public void vibrate_withOngoingHigherImportanceVibration_ignoresEffect() throws Exception {
         mockVibrators(1);
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         VibratorManagerService service = createSystemReadyService();
 
-        VibrationEffect alarmEffect = VibrationEffect.createWaveform(
+        VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{10_000, 10_000}, new int[]{128, 255}, -1);
-        vibrate(service, alarmEffect, new VibrationAttributes.Builder().setUsage(
-                VibrationAttributes.USAGE_RINGTONE).build());
+        vibrate(service, effect, ALARM_ATTRS);
 
         // VibrationThread will start this vibration async, so wait before checking it started.
         assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(),
                 service, TEST_TIMEOUT_MILLIS));
 
-        vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
-                HAPTIC_FEEDBACK_ATTRS);
+        vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS);
 
         // Wait before checking it never played a second effect.
         assertFalse(waitUntil(s -> mVibratorProviders.get(1).getAllEffectSegments().size() > 1,
                 service, /* timeout= */ 50));
+
+        // The second vibration shouldn't have recorded that the vibrators were turned on.
+        verify(mBatteryStatsMock, times(1)).noteVibratorOn(anyInt(), anyLong());
+    }
+
+    @Test
+    public void vibrate_withOngoingLowerImportanceVibration_cancelsOngoingEffect()
+            throws Exception {
+        mockVibrators(1);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        VibratorManagerService service = createSystemReadyService();
+
+        VibrationEffect effect = VibrationEffect.createWaveform(
+                new long[]{10_000, 10_000}, new int[]{128, 255}, -1);
+        vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS);
+
+        // VibrationThread will start this vibration async, so wait before checking it started.
+        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(),
+                service, TEST_TIMEOUT_MILLIS));
+
+        vibrate(service, effect, RINGTONE_ATTRS);
+
+        // VibrationThread will start this vibration async, so wait before checking it started.
+        assertTrue(waitUntil(s -> mVibratorProviders.get(1).getAllEffectSegments().size() > 1,
+                service, TEST_TIMEOUT_MILLIS));
+
+        // The second vibration should have recorded that the vibrators were turned on.
+        verify(mBatteryStatsMock, times(2)).noteVibratorOn(anyInt(), anyLong());
     }
 
     @Test
@@ -1052,15 +1080,15 @@
                 IVibrator.CAP_COMPOSE_EFFECTS);
         VibratorManagerService service = createSystemReadyService();
 
-        vibrate(service, CombinedVibration.startSequential()
-                .addNext(1, VibrationEffect.createOneShot(100, 125))
-                .combine(), NOTIFICATION_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 1,
-                service, TEST_TIMEOUT_MILLIS));
-
         vibrate(service, VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
                 .compose(), HAPTIC_FEEDBACK_ATTRS);
+        assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 1,
+                service, TEST_TIMEOUT_MILLIS));
+
+        vibrate(service, CombinedVibration.startSequential()
+                .addNext(1, VibrationEffect.createOneShot(100, 125))
+                .combine(), NOTIFICATION_ATTRS);
         assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 2,
                 service, TEST_TIMEOUT_MILLIS));
 
@@ -1070,25 +1098,25 @@
         assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 3,
                 service, TEST_TIMEOUT_MILLIS));
 
+        // Ring vibrations have intensity OFF and are not played.
         vibrate(service, VibrationEffect.createOneShot(100, 125), RINGTONE_ATTRS);
         assertFalse(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() > 3,
-                service, TEST_TIMEOUT_MILLIS));
+                service, /* timeout= */ 50));
 
+        // Only 3 effects played successfully.
         assertEquals(3, fakeVibrator.getAllEffectSegments().size());
 
+        // Haptic feedback vibrations will be scaled with SCALE_LOW or none if default is low.
+        assertEquals(defaultTouchIntensity > Vibrator.VIBRATION_INTENSITY_LOW,
+                0.5 > ((PrimitiveSegment) fakeVibrator.getAllEffectSegments().get(0)).getScale());
+
         // Notification vibrations will be scaled with SCALE_HIGH or none if default is high.
         assertEquals(defaultNotificationIntensity < Vibrator.VIBRATION_INTENSITY_HIGH,
                 0.6 < fakeVibrator.getAmplitudes().get(0));
 
-        // Haptic feedback vibrations will be scaled with SCALE_LOW or none if default is low.
-        assertEquals(defaultTouchIntensity > Vibrator.VIBRATION_INTENSITY_LOW,
-                0.5 > ((PrimitiveSegment) fakeVibrator.getAllEffectSegments().get(1)).getScale());
-
         // Alarm vibration will be scaled with SCALE_NONE.
         assertEquals(1f,
                 ((PrimitiveSegment) fakeVibrator.getAllEffectSegments().get(2)).getScale(), 1e-5);
-
-        // Ring vibrations have intensity OFF and are not played.
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java
index c64ff9e..3de65c1 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java
@@ -185,7 +185,7 @@
         }
 
         @Override
-        public boolean isKeyguardLocked() {
+        public boolean isKeyguardShowingAndNotOccluded() {
             return mIsScreenLocked;
         }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index 2f054b0..8ba9af0 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -840,6 +840,156 @@
     }
 
     @Test
+    public void reregisterService_checksAppIsApproved_pkg() throws Exception {
+        Context context = mock(Context.class);
+        PackageManager pm = mock(PackageManager.class);
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+
+        when(context.getPackageName()).thenReturn(mContext.getPackageName());
+        when(context.getUserId()).thenReturn(mContext.getUserId());
+        when(context.getPackageManager()).thenReturn(pm);
+        when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
+
+        ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
+                APPROVAL_BY_PACKAGE);
+        ComponentName cn = ComponentName.unflattenFromString("a/a");
+
+        when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
+            Object[] args = invocation.getArguments();
+            ServiceConnection sc = (ServiceConnection) args[1];
+            sc.onServiceConnected(cn, mock(IBinder.class));
+            return true;
+        });
+
+        service.addApprovedList("a", 0, true);
+
+        service.reregisterService(cn, 0);
+
+        assertTrue(service.isBound(cn, 0));
+    }
+
+    @Test
+    public void reregisterService_checksAppIsApproved_pkg_secondary() throws Exception {
+        Context context = mock(Context.class);
+        PackageManager pm = mock(PackageManager.class);
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+
+        when(context.getPackageName()).thenReturn(mContext.getPackageName());
+        when(context.getUserId()).thenReturn(mContext.getUserId());
+        when(context.getPackageManager()).thenReturn(pm);
+        when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
+
+        ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
+                APPROVAL_BY_PACKAGE);
+        ComponentName cn = ComponentName.unflattenFromString("a/a");
+
+        when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
+            Object[] args = invocation.getArguments();
+            ServiceConnection sc = (ServiceConnection) args[1];
+            sc.onServiceConnected(cn, mock(IBinder.class));
+            return true;
+        });
+
+        service.addApprovedList("a", 0, false);
+
+        service.reregisterService(cn, 0);
+
+        assertTrue(service.isBound(cn, 0));
+    }
+
+    @Test
+    public void reregisterService_checksAppIsApproved_cn() throws Exception {
+        Context context = mock(Context.class);
+        PackageManager pm = mock(PackageManager.class);
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+
+        when(context.getPackageName()).thenReturn(mContext.getPackageName());
+        when(context.getUserId()).thenReturn(mContext.getUserId());
+        when(context.getPackageManager()).thenReturn(pm);
+        when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
+
+        ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
+                APPROVAL_BY_COMPONENT);
+        ComponentName cn = ComponentName.unflattenFromString("a/a");
+
+        when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
+            Object[] args = invocation.getArguments();
+            ServiceConnection sc = (ServiceConnection) args[1];
+            sc.onServiceConnected(cn, mock(IBinder.class));
+            return true;
+        });
+
+        service.addApprovedList("a/a", 0, true);
+
+        service.reregisterService(cn, 0);
+
+        assertTrue(service.isBound(cn, 0));
+    }
+
+    @Test
+    public void reregisterService_checksAppIsApproved_cn_secondary() throws Exception {
+        Context context = mock(Context.class);
+        PackageManager pm = mock(PackageManager.class);
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+
+        when(context.getPackageName()).thenReturn(mContext.getPackageName());
+        when(context.getUserId()).thenReturn(mContext.getUserId());
+        when(context.getPackageManager()).thenReturn(pm);
+        when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
+
+        ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
+                APPROVAL_BY_COMPONENT);
+        ComponentName cn = ComponentName.unflattenFromString("a/a");
+
+        when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
+            Object[] args = invocation.getArguments();
+            ServiceConnection sc = (ServiceConnection) args[1];
+            sc.onServiceConnected(cn, mock(IBinder.class));
+            return true;
+        });
+
+        service.addApprovedList("a/a", 0, false);
+
+        service.reregisterService(cn, 0);
+
+        assertTrue(service.isBound(cn, 0));
+    }
+
+    @Test
+    public void reregisterService_checksAppIsNotApproved_cn_secondary() throws Exception {
+        Context context = mock(Context.class);
+        PackageManager pm = mock(PackageManager.class);
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+
+        when(context.getPackageName()).thenReturn(mContext.getPackageName());
+        when(context.getUserId()).thenReturn(mContext.getUserId());
+        when(context.getPackageManager()).thenReturn(pm);
+        when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
+
+        ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, mIpm,
+                APPROVAL_BY_COMPONENT);
+        ComponentName cn = ComponentName.unflattenFromString("a/a");
+
+        when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> {
+            Object[] args = invocation.getArguments();
+            ServiceConnection sc = (ServiceConnection) args[1];
+            sc.onServiceConnected(cn, mock(IBinder.class));
+            return true;
+        });
+
+        service.addApprovedList("b/b", 0, false);
+
+        service.reregisterService(cn, 0);
+
+        assertFalse(service.isBound(cn, 0));
+    }
+
+    @Test
     public void unbindOtherUserServices() throws PackageManager.NameNotFoundException {
         Context context = mock(Context.class);
         PackageManager pm = mock(PackageManager.class);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
index 76d4059..c5131c8 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
@@ -28,6 +28,7 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.atLeast;
@@ -40,6 +41,9 @@
 import static org.mockito.Mockito.when;
 
 import android.app.INotificationManager;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
 import android.content.ComponentName;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
@@ -49,6 +53,7 @@
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerFilter;
 import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationRankingUpdate;
 import android.service.notification.NotificationStats;
 import android.service.notification.StatusBarNotification;
 import android.testing.TestableContext;
@@ -60,6 +65,8 @@
 
 import com.android.server.UiServiceTestCase;
 
+import com.google.common.collect.ImmutableList;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -397,6 +404,36 @@
     }
 
     @Test
+    public void testImplicitGrant() {
+        String pkg = "pkg";
+        int uid = 9;
+        NotificationChannel channel = new NotificationChannel("id", "name",
+                NotificationManager.IMPORTANCE_HIGH);
+        Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setTimeoutAfter(1);
+
+        StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, 8, "tag", uid, 0,
+                nb.build(), UserHandle.getUserHandleForUid(uid), null, 0);
+        NotificationRecord r = new NotificationRecord(mContext, sbn, channel);
+
+        ManagedServices.ManagedServiceInfo info = mListeners.new ManagedServiceInfo(
+                null, new ComponentName("a", "a"), sbn.getUserId(), false, null, 33, 33);
+        List<ManagedServices.ManagedServiceInfo> services = ImmutableList.of(info);
+        when(mListeners.getServices()).thenReturn(services);
+
+        when(mNm.isVisibleToListener(any(), anyInt(), any())).thenReturn(true);
+        when(mNm.makeRankingUpdateLocked(info)).thenReturn(mock(NotificationRankingUpdate.class));
+        mNm.mPackageManagerInternal = mPmi;
+
+        mListeners.notifyPostedLocked(r, null);
+
+        verify(mPmi).grantImplicitAccess(sbn.getUserId(), null, UserHandle.getAppId(33),
+                sbn.getUid(), false, false);
+    }
+
+    @Test
     public void testNotifyPostedLockedInLockdownMode() {
         NotificationRecord r = mock(NotificationRecord.class);
         NotificationRecord old = mock(NotificationRecord.class);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index fd1536c..4550b56 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -1622,7 +1622,9 @@
                     ZenModeConfig.toScheduleConditionId(si),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+            // We need the package name to be something that's not "android" so there aren't any
+            // existing rules under that package.
+            String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
             assertNotNull(id);
         }
         try {
@@ -1632,12 +1634,41 @@
                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+            String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
             fail("allowed too many rules to be created");
         } catch (IllegalArgumentException e) {
             // yay
         }
+    }
 
+    @Test
+    public void testAddAutomaticZenRule_beyondSystemLimit_differentComponents() {
+        // Make sure the system limit is enforced per-package even with different component provider
+        // names.
+        for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) {
+            ScheduleInfo si = new ScheduleInfo();
+            si.startHour = i;
+            AutomaticZenRule zenRule = new AutomaticZenRule("name" + i,
+                    null,
+                    new ComponentName("android", "ScheduleConditionProvider" + i),
+                    ZenModeConfig.toScheduleConditionId(si),
+                    new ZenPolicy.Builder().build(),
+                    NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+            String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+            assertNotNull(id);
+        }
+        try {
+            AutomaticZenRule zenRule = new AutomaticZenRule("name",
+                    null,
+                    new ComponentName("android", "ScheduleConditionProviderFinal"),
+                    ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+                    new ZenPolicy.Builder().build(),
+                    NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+            String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+            fail("allowed too many rules to be created");
+        } catch (IllegalArgumentException e) {
+            // yay
+        }
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 6fafa49..0c3b270 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -29,6 +29,8 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
+import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
+import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
 import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
@@ -182,6 +184,10 @@
 
     private final String mPackageName = getInstrumentation().getTargetContext().getPackageName();
 
+    private static final int ORIENTATION_CONFIG_CHANGES =
+            CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT | CONFIG_SCREEN_SIZE
+                    | CONFIG_SMALLEST_SCREEN_SIZE;
+
     @Before
     public void setUp() throws Exception {
         setBooted(mAtm);
@@ -487,7 +493,7 @@
     public void testSetRequestedOrientationUpdatesConfiguration() throws Exception {
         final ActivityRecord activity = new ActivityBuilder(mAtm)
                 .setCreateTask(true)
-                .setConfigChanges(CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT)
+                .setConfigChanges(ORIENTATION_CONFIG_CHANGES)
                 .build();
         activity.setState(RESUMED, "Testing");
 
@@ -710,7 +716,7 @@
         final ActivityRecord activity = new ActivityBuilder(mAtm)
                 .setCreateTask(true)
                 .setLaunchTaskBehind(true)
-                .setConfigChanges(CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT)
+                .setConfigChanges(ORIENTATION_CONFIG_CHANGES)
                 .build();
         final Task task = activity.getTask();
         activity.setState(STOPPED, "Testing");
@@ -1160,6 +1166,45 @@
         assertTrue(lastTransition.allReady());
     }
 
+    @Test
+    public void testFinishActivityIfPossible_sendResultImmediately() {
+        // Create activity representing the source of the activity result.
+        final ComponentName sourceComponent = ComponentName.createRelative(
+                DEFAULT_COMPONENT_PACKAGE_NAME, ".SourceActivity");
+        final ComponentName targetComponent = ComponentName.createRelative(
+                sourceComponent.getPackageName(), ".TargetActivity");
+
+        final ActivityRecord sourceActivity = new ActivityBuilder(mWm.mAtmService)
+                .setComponent(sourceComponent)
+                .setLaunchMode(ActivityInfo.LAUNCH_SINGLE_INSTANCE)
+                .setCreateTask(true)
+                .build();
+        sourceActivity.finishing = false;
+        sourceActivity.setState(STOPPED, "test");
+
+        final ActivityRecord targetActivity = new ActivityBuilder(mWm.mAtmService)
+                .setComponent(targetComponent)
+                .setTargetActivity(sourceComponent.getClassName())
+                .setLaunchMode(ActivityInfo.LAUNCH_SINGLE_INSTANCE)
+                .setCreateTask(true)
+                .setOnTop(true)
+                .build();
+        targetActivity.finishing = false;
+        targetActivity.setState(RESUMED, "test");
+        targetActivity.resultTo = sourceActivity;
+        targetActivity.setForceSendResultForMediaProjection();
+
+        clearInvocations(mAtm.getLifecycleManager());
+
+        targetActivity.finishIfPossible(0, new Intent(), null, "test", false /* oomAdj */);
+
+        try {
+            verify(mAtm.getLifecycleManager(), atLeastOnce()).scheduleTransaction(
+                    any(ClientTransaction.class));
+        } catch (RemoteException ignored) {
+        }
+    }
+
     /**
      * Verify that complete finish request for non-finishing activity is invalid.
      */
@@ -1786,13 +1831,16 @@
     public void testActivityOnCancelFixedRotationTransform() {
         final ActivityRecord activity = createActivityWithTask();
         final DisplayRotation displayRotation = activity.mDisplayContent.getDisplayRotation();
+        final RemoteDisplayChangeController remoteDisplayChangeController = activity
+                .mDisplayContent.mRemoteDisplayChangeController;
         spyOn(displayRotation);
+        spyOn(remoteDisplayChangeController);
 
         final DisplayContent display = activity.mDisplayContent;
         final int originalRotation = display.getRotation();
 
         // Make {@link DisplayContent#sendNewConfiguration} not apply rotation immediately.
-        doReturn(true).when(displayRotation).isWaitingForRemoteRotation();
+        doReturn(true).when(remoteDisplayChangeController).isWaitingForRemoteDisplayChange();
         doReturn((originalRotation + 1) % 4).when(displayRotation).rotationForOrientation(
                 anyInt() /* orientation */, anyInt() /* lastRotation */);
         // Set to visible so the activity can freeze the screen.
@@ -1830,7 +1878,7 @@
         // Simulate the remote rotation has completed and the configuration doesn't change, then
         // the rotated activity should also be restored by clearing the transform.
         displayRotation.updateRotationUnchecked(true /* forceUpdate */);
-        doReturn(false).when(displayRotation).isWaitingForRemoteRotation();
+        doReturn(false).when(remoteDisplayChangeController).isWaitingForRemoteDisplayChange();
         clearInvocations(activity);
         display.setFixedRotationLaunchingAppUnchecked(activity);
         display.sendNewConfiguration();
@@ -1954,7 +2002,8 @@
                     any() /* window */,  any() /* attrs */,
                     anyInt() /* viewVisibility */, anyInt() /* displayId */,
                     any() /* requestedVisibilities */, any() /* outInputChannel */,
-                    any() /* outInsetsState */, any() /* outActiveControls */);
+                    any() /* outInsetsState */, any() /* outActiveControls */,
+                    any() /* outAttachedFrame */);
             mAtm.mWindowManager.mStartingSurfaceController
                     .createTaskSnapshotSurface(activity, snapshot);
         } catch (RemoteException ignored) {
@@ -2165,39 +2214,6 @@
     }
 
     @Test
-    public void testSupportsSplitScreenWindowingMode() {
-        final ActivityRecord activity = new ActivityBuilder(mAtm)
-                .setCreateTask(true)
-                .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE)
-                .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
-                .build();
-
-        // Not allow non-resizable
-        mAtm.mForceResizableActivities = false;
-        mAtm.mSupportsNonResizableMultiWindow = -1;
-        mAtm.mDevEnableNonResizableMultiWindow = false;
-        assertFalse(activity.supportsSplitScreenWindowingMode());
-
-        // Force resizable
-        mAtm.mForceResizableActivities = true;
-        mAtm.mSupportsNonResizableMultiWindow = -1;
-        mAtm.mDevEnableNonResizableMultiWindow = false;
-        assertTrue(activity.supportsSplitScreenWindowingMode());
-
-        // Use development option to allow non-resizable
-        mAtm.mForceResizableActivities = false;
-        mAtm.mSupportsNonResizableMultiWindow = -1;
-        mAtm.mDevEnableNonResizableMultiWindow = true;
-        assertTrue(activity.supportsSplitScreenWindowingMode());
-
-        // Always allow non-resizable
-        mAtm.mForceResizableActivities = false;
-        mAtm.mSupportsNonResizableMultiWindow = 1;
-        mAtm.mDevEnableNonResizableMultiWindow = false;
-        assertTrue(activity.supportsSplitScreenWindowingMode());
-    }
-
-    @Test
     public void testSupportsFreeform() {
         final ActivityRecord activity = new ActivityBuilder(mAtm)
                 .setCreateTask(true)
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index b943275..1176786 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -794,7 +794,7 @@
         // Create adjacent tasks and put one activity under it
         final Task parent = new TaskBuilder(mSupervisor).build();
         final Task adjacentParent = new TaskBuilder(mSupervisor).build();
-        parent.setAdjacentTaskFragment(adjacentParent, true);
+        parent.setAdjacentTaskFragment(adjacentParent);
         final ActivityRecord activity = new ActivityBuilder(mAtm)
                 .setParentTask(parent)
                 .setCreateTask(true).build();
@@ -1120,28 +1120,27 @@
     }
 
     @Test
-    public void testTargetStackInSplitScreen() {
+    public void testTargetTaskInSplitScreen() {
         final ActivityStarter starter =
                 prepareStarter(FLAG_ACTIVITY_LAUNCH_ADJACENT, false /* mockGetRootTask */);
         final ActivityRecord top = new ActivityBuilder(mAtm).setCreateTask(true).build();
         final ActivityOptions options = ActivityOptions.makeBasic();
         final ActivityRecord[] outActivity = new ActivityRecord[1];
 
-        // Activity must not land on split-screen stack if currently not in split-screen mode.
+        // Activity must not land on split-screen task if currently not in split-screen mode.
         starter.setActivityOptions(options.toBundle())
-                .setReason("testWindowingModeOptionsLaunchAdjacent")
+                .setReason("testTargetTaskInSplitScreen")
                 .setOutActivity(outActivity).execute();
         assertThat(outActivity[0].inMultiWindowMode()).isFalse();
 
-        // Move activity to split-screen-primary stack and make sure it has the focus.
+        // Move activity to split-screen-primary task and make sure it has the focus.
         TestSplitOrganizer splitOrg = new TestSplitOrganizer(mAtm, top.getDisplayContent());
         top.getRootTask().reparent(splitOrg.mPrimary, POSITION_BOTTOM);
-        top.getRootTask().moveToFront("testWindowingModeOptionsLaunchAdjacent");
+        top.getRootTask().moveToFront("testTargetTaskInSplitScreen");
 
-        // Activity must landed on split-screen-secondary when launch adjacent.
-        starter.setActivityOptions(options.toBundle())
-                .setReason("testWindowingModeOptionsLaunchAdjacent")
-                .setOutActivity(outActivity).execute();
+        // Activity must land on split-screen-secondary when launch adjacent.
+        startActivityInner(starter, outActivity[0], top, options, null /* inTask */,
+                null /* taskFragment*/);
         assertThat(outActivity[0].inMultiWindowMode()).isTrue();
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index a857190..20b1120 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -21,7 +21,6 @@
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
@@ -42,8 +41,8 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doCallRealMethod;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.when;
 
 import android.annotation.Nullable;
@@ -60,7 +59,6 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.LocaleList;
-import android.os.PowerManager;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.view.Display;
@@ -136,7 +134,7 @@
         assertNull(transaction.getLifecycleStateRequest());
     }
 
-    @Test(expected = IllegalStateException.class)
+    @Test
     public void testOnPictureInPictureRequested_cannotEnterPip() throws RemoteException {
         final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
         final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
@@ -146,11 +144,16 @@
 
         mAtm.mActivityClientController.requestPictureInPictureMode(activity);
 
-        // Check enter no transactions with enter pip requests are made.
-        verify(lifecycleManager, times(0)).scheduleTransaction(any());
+        verify(lifecycleManager, atLeast(0))
+                .scheduleTransaction(mClientTransactionCaptor.capture());
+        final ClientTransaction transaction = mClientTransactionCaptor.getValue();
+        // Check that none are enter pip request items.
+        transaction.getCallbacks().forEach(clientTransactionItem -> {
+            assertFalse(clientTransactionItem instanceof EnterPipRequestedItem);
+        });
     }
 
-    @Test(expected = IllegalStateException.class)
+    @Test
     public void testOnPictureInPictureRequested_alreadyInPIPMode() throws RemoteException {
         final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
         final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
@@ -159,8 +162,13 @@
 
         mAtm.mActivityClientController.requestPictureInPictureMode(activity);
 
-        // Check that no transactions with enter pip requests are made.
-        verify(lifecycleManager, times(0)).scheduleTransaction(any());
+        verify(lifecycleManager, atLeast(0))
+                .scheduleTransaction(mClientTransactionCaptor.capture());
+        final ClientTransaction transaction = mClientTransactionCaptor.getValue();
+        // Check that none are enter pip request items.
+        transaction.getCallbacks().forEach(clientTransactionItem -> {
+            assertFalse(clientTransactionItem instanceof EnterPipRequestedItem);
+        });
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
index 716612c..75ecfd8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java
@@ -21,6 +21,7 @@
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
@@ -34,6 +35,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
@@ -284,10 +286,14 @@
                 .setCreateActivity(true).build().getTopMostActivity();
         activity2.getTask().setResumedActivity(activity2, "test");
 
-        mAtm.mAmInternal.deletePendingTopUid(activity1.getUid(), Long.MAX_VALUE);
+        final int[] pendingTopUid = new int[1];
+        doAnswer(invocation -> {
+            pendingTopUid[0] = invocation.getArgument(0);
+            return null;
+        }).when(mAtm.mAmInternal).addPendingTopUid(anyInt(), anyInt(), any());
         clearInvocations(mAtm);
         activity1.moveFocusableActivityToTop("test");
-        assertTrue(mAtm.mAmInternal.isPendingTopUid(activity1.getUid()));
+        assertEquals(activity1.getUid(), pendingTopUid[0]);
         verify(mAtm).updateOomAdj();
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 890a547..f2d6273 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -25,6 +26,8 @@
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
+import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN;
 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
 import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE;
 import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE;
@@ -155,6 +158,32 @@
     }
 
     @Test
+    public void testDreamActivityOpenTransition() {
+        final ActivityRecord dreamActivity = createActivityRecord(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM);
+        mDisplayContent.prepareAppTransition(TRANSIT_OPEN);
+        mDisplayContent.mOpeningApps.add(dreamActivity);
+
+        assertEquals(TRANSIT_OLD_DREAM_ACTIVITY_OPEN,
+                AppTransitionController.getTransitCompatType(mDisplayContent.mAppTransition,
+                        mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps,
+                        mDisplayContent.mChangingContainers, null, null, false));
+    }
+
+    @Test
+    public void testDreamActivityCloseTransition() {
+        final ActivityRecord dreamActivity = createActivityRecord(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM);
+        mDisplayContent.prepareAppTransition(TRANSIT_CLOSE);
+        mDisplayContent.mClosingApps.add(dreamActivity);
+
+        assertEquals(TRANSIT_OLD_DREAM_ACTIVITY_CLOSE,
+                AppTransitionController.getTransitCompatType(mDisplayContent.mAppTransition,
+                        mDisplayContent.mOpeningApps, mDisplayContent.mClosingApps,
+                        mDisplayContent.mChangingContainers, null, null, false));
+    }
+
+    @Test
     public void testChangeIsNotOverwritten() {
         final ActivityRecord behind = createActivityRecord(mDisplayContent,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
@@ -564,7 +593,7 @@
                 .setCreatedByOrganizer(true);
         final Task splitRoot1 = builder.build();
         final Task splitRoot2 = builder.build();
-        splitRoot1.setAdjacentTaskFragment(splitRoot2, false /* moveTogether */);
+        splitRoot1.setAdjacentTaskFragment(splitRoot2);
         final ActivityRecord activity1 = createActivityRecordWithParentTask(splitRoot1);
         activity1.setVisible(false);
         activity1.mVisibleRequested = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 0792300..40e266c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -22,6 +22,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -77,10 +78,8 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
 import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_TOKEN_TRANSFORM;
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
-import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 
@@ -123,8 +122,8 @@
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.Gravity;
-import android.view.IDisplayWindowRotationCallback;
-import android.view.IDisplayWindowRotationController;
+import android.view.IDisplayChangeWindowCallback;
+import android.view.IDisplayChangeWindowController;
 import android.view.ISystemGestureExclusionListener;
 import android.view.IWindowManager;
 import android.view.InsetsState;
@@ -135,6 +134,7 @@
 import android.view.SurfaceControl.Transaction;
 import android.view.View;
 import android.view.WindowManager;
+import android.window.DisplayAreaInfo;
 import android.window.IDisplayAreaOrganizer;
 import android.window.WindowContainerToken;
 
@@ -641,6 +641,7 @@
         final DisplayContent dc = mDisplayContent;
         final WindowState ws = createWindow(null, TYPE_APPLICATION, dc, "app window");
         dc.setImeLayeringTarget(ws);
+        dc.setImeInputTarget(ws);
 
         // Adjust bounds so that matchesRootDisplayAreaBounds() returns false.
         final Rect bounds = new Rect(dc.getBounds());
@@ -1097,6 +1098,25 @@
     }
 
     @Test
+    public void testOrientationBehind() {
+        final ActivityRecord prev = new ActivityBuilder(mAtm).setCreateTask(true)
+                .setScreenOrientation(getRotatedOrientation(mDisplayContent)).build();
+        prev.mVisibleRequested = false;
+        final ActivityRecord top = new ActivityBuilder(mAtm).setCreateTask(true)
+                .setScreenOrientation(SCREEN_ORIENTATION_BEHIND).build();
+        assertNotEquals(WindowConfiguration.ROTATION_UNDEFINED,
+                mDisplayContent.rotationForActivityInDifferentOrientation(top));
+
+        mDisplayContent.requestTransitionAndLegacyPrepare(WindowManager.TRANSIT_OPEN, 0);
+        top.setVisibility(true);
+        mDisplayContent.updateOrientation();
+        // The top uses "behind", so the orientation is decided by the previous.
+        assertEquals(prev, mDisplayContent.getLastOrientationSource());
+        // The top will use the rotation from "prev" with fixed rotation.
+        assertTrue(top.hasFixedRotationTransform());
+    }
+
+    @Test
     public void testFixedToUserRotationChanged() {
         final DisplayContent dc = createNewDisplay();
         dc.getDisplayRotation().setFixedToUserRotation(
@@ -1133,6 +1153,7 @@
         dc.setImeLayeringTarget(createWindow(null, TYPE_STATUS_BAR, "app"));
         dc.getImeTarget(IME_TARGET_LAYERING).getWindow().setWindowingMode(
                 WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
+        dc.setImeInputTarget(dc.getImeTarget(IME_TARGET_LAYERING).getWindow());
         assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
     }
 
@@ -1151,6 +1172,7 @@
     public void testComputeImeParent_noApp() throws Exception {
         final DisplayContent dc = createNewDisplay();
         dc.setImeLayeringTarget(createWindow(null, TYPE_STATUS_BAR, "statusBar"));
+        dc.setImeInputTarget(dc.getImeTarget(IME_TARGET_LAYERING).getWindow());
         assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
     }
 
@@ -1593,14 +1615,14 @@
         final Task task = app.getTask();
         final ActivityRecord app2 = new ActivityBuilder(mWm.mAtmService).setTask(task).build();
         mDisplayContent.setFixedRotationLaunchingApp(app2, (mDisplayContent.getRotation() + 1) % 4);
-        doReturn(true).when(task).isAppTransitioning();
-        // If the task is animating transition, this should be no-op.
+        doReturn(true).when(app).isInTransition();
+        // If the task contains a transition, this should be no-op.
         mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token);
 
         assertTrue(app2.hasFixedRotationTransform());
         assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp());
 
-        doReturn(false).when(task).isAppTransitioning();
+        doReturn(false).when(app).isInTransition();
         // Although this notifies app instead of app2 that uses the fixed rotation, app2 should
         // still finish the transform because there is no more transition event.
         mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token);
@@ -1677,6 +1699,13 @@
         assertFalse(displayContent.mPinnedTaskController.isFreezingTaskConfig(pinnedTask));
         assertEquals(pinnedActivity.getConfiguration().orientation,
                 displayContent.getConfiguration().orientation);
+
+        // No need to apply rotation if the display ignores orientation request.
+        doCallRealMethod().when(displayContent).rotationForActivityInDifferentOrientation(any());
+        pinnedActivity.mOrientation = SCREEN_ORIENTATION_LANDSCAPE;
+        displayContent.setIgnoreOrientationRequest(true);
+        assertEquals(WindowConfiguration.ROTATION_UNDEFINED,
+                displayContent.rotationForActivityInDifferentOrientation(pinnedActivity));
     }
 
     @Test
@@ -1693,8 +1722,7 @@
         // The condition should reject using fixed rotation because the resumed client in real case
         // might get display info immediately. And the fixed rotation adjustments haven't arrived
         // client side so the info may be inconsistent with the requested orientation.
-        verify(mDisplayContent).handleTopActivityLaunchingInDifferentOrientation(eq(app),
-                eq(true) /* checkOpening */);
+        verify(mDisplayContent).updateOrientation(eq(app), anyBoolean());
         assertFalse(app.isFixedRotationTransforming());
         assertFalse(mDisplayContent.hasTopFixedRotationLaunchingApp());
     }
@@ -1782,15 +1810,16 @@
                     return true;
                 }).when(dc).updateDisplayOverrideConfigurationLocked();
         final boolean[] called = new boolean[1];
-        mWm.mDisplayRotationController =
-                new IDisplayWindowRotationController.Stub() {
+        mWm.mDisplayChangeController =
+                new IDisplayChangeWindowController.Stub() {
                     @Override
-                    public void onRotateDisplay(int displayId, int fromRotation, int toRotation,
-                            IDisplayWindowRotationCallback callback) {
+                    public void onDisplayChange(int displayId, int fromRotation, int toRotation,
+                            DisplayAreaInfo newDisplayAreaInfo,
+                            IDisplayChangeWindowCallback callback) throws RemoteException {
                         called[0] = true;
 
                         try {
-                            callback.continueRotateDisplay(toRotation, null);
+                            callback.continueDisplayChange(null);
                         } catch (RemoteException e) {
                             assertTrue(false);
                         }
@@ -1824,13 +1853,14 @@
         // Rotate 180 degree so the display doesn't have configuration change. This condition is
         // used for the later verification of stop-freezing (without setting mWaitingForConfig).
         doReturn((dr.getRotation() + 2) % 4).when(dr).rotationForOrientation(anyInt(), anyInt());
-        mWm.mDisplayRotationController =
-                new IDisplayWindowRotationController.Stub() {
+        mWm.mDisplayChangeController =
+                new IDisplayChangeWindowController.Stub() {
                     @Override
-                    public void onRotateDisplay(int displayId, int fromRotation, int toRotation,
-                            IDisplayWindowRotationCallback callback) {
+                    public void onDisplayChange(int displayId, int fromRotation, int toRotation,
+                            DisplayAreaInfo newDisplayAreaInfo,
+                            IDisplayChangeWindowCallback callback) throws RemoteException {
                         try {
-                            callback.continueRotateDisplay(toRotation, null);
+                            callback.continueDisplayChange(null);
                         } catch (RemoteException e) {
                             assertTrue(false);
                         }
@@ -2193,23 +2223,28 @@
      */
     @Test
     public void testCreateTestDisplayContentFromDimensions() {
-        final int displayWidth = 1000;
-        final int displayHeight = 2000;
+        final int displayWidth = 540;
+        final int displayHeight = 960;
+        final int density = 192;
+        final int expectedWidthDp = 450; // = 540/(192/160)
+        final int expectedHeightDp = 800; // = 960/(192/160)
         final int windowingMode = WINDOWING_MODE_FULLSCREEN;
         final boolean ignoreOrientationRequests = false;
         final float fixedOrientationLetterboxRatio = 0;
         final DisplayContent testDisplayContent = new TestDisplayContent.Builder(mAtm, displayWidth,
-                displayHeight).build();
+                displayHeight).setDensityDpi(density).build();
 
         // test display info
         final DisplayInfo di = testDisplayContent.getDisplayInfo();
         assertEquals(displayWidth, di.logicalWidth);
         assertEquals(displayHeight, di.logicalHeight);
-        assertEquals(TestDisplayContent.DEFAULT_LOGICAL_DISPLAY_DENSITY, di.logicalDensityDpi);
+        assertEquals(density, di.logicalDensityDpi);
 
         // test configuration
-        final WindowConfiguration windowConfig = testDisplayContent.getConfiguration()
-                .windowConfiguration;
+        final Configuration config = testDisplayContent.getConfiguration();
+        assertEquals(expectedWidthDp, config.screenWidthDp);
+        assertEquals(expectedHeightDp, config.screenHeightDp);
+        final WindowConfiguration windowConfig = config.windowConfiguration;
         assertEquals(displayWidth, windowConfig.getBounds().width());
         assertEquals(displayHeight, windowConfig.getBounds().height());
         assertEquals(windowingMode, windowConfig.getWindowingMode());
@@ -2396,7 +2431,7 @@
     @Test
     public void testImeMenuDialogFocusWhenImeLayeringTargetChanges() {
         final WindowState imeMenuDialog =
-                createWindow(mImeWindow, TYPE_INPUT_METHOD_DIALOG, "imeMenuDialog");
+                createWindow(null, TYPE_INPUT_METHOD_DIALOG, "imeMenuDialog");
         makeWindowVisibleAndDrawn(imeMenuDialog, mImeWindow);
         assertTrue(imeMenuDialog.canReceiveKeys());
         mDisplayContent.setInputMethodWindowLocked(mImeWindow);
@@ -2409,13 +2444,11 @@
         doReturn(true).when(imeAppTarget).getRequestedVisibility(ITYPE_IME);
         assertEquals(imeMenuDialog, mDisplayContent.findFocusedWindow());
 
-        // Verify imeMenuDialog doesn't be focused window if the next IME target does not
-        // request IME visible.
+        // Verify imeMenuDialog doesn't be focused window if the next IME target is closing.
         final WindowState nextImeAppTarget =
                 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "nextImeAppTarget");
-        spyOn(nextImeAppTarget);
-        doReturn(true).when(nextImeAppTarget).isAnimating(PARENTS | TRANSITION,
-                ANIMATION_TYPE_APP_TRANSITION);
+        makeWindowVisibleAndDrawn(nextImeAppTarget);
+        nextImeAppTarget.mActivityRecord.commitVisibility(false, false);
         mDisplayContent.setImeLayeringTarget(nextImeAppTarget);
         assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow());
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 45ae81a..34575ae 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -43,6 +43,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.util.Pair;
 import android.view.DisplayInfo;
+import android.view.InsetsFrameProvider;
 import android.view.InsetsState;
 import android.view.PrivacyIndicatorBounds;
 import android.view.RoundedCorners;
@@ -153,7 +154,10 @@
         mDisplayPolicy.removeWindowLw(mStatusBarWindow);  // Removes the existing one.
 
         WindowState win = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
-        win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES};
+        win.mAttrs.providedInsets = new InsetsFrameProvider[] {
+                new InsetsFrameProvider(ITYPE_STATUS_BAR),
+                new InsetsFrameProvider(ITYPE_TOP_GESTURES)
+        };
         win.getFrame().set(0, 0, 500, 100);
 
         addWindow(win);
@@ -182,7 +186,9 @@
     public void addingWindow_InWindowTypeWithPredefinedInsets() {
         mDisplayPolicy.removeWindowLw(mStatusBarWindow);  // Removes the existing one.
         WindowState win = createWindow(null, TYPE_STATUS_BAR, "StatusBar");
-        win.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR};
+        win.mAttrs.providedInsets = new InsetsFrameProvider[] {
+                new InsetsFrameProvider(ITYPE_STATUS_BAR)
+        };
         win.getFrame().set(0, 0, 500, 100);
 
         addWindow(win);
@@ -199,12 +205,19 @@
     @Test
     public void addingWindow_throwsException_WithMultipleInsetTypes() {
         WindowState win1 = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
-        win1.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
+        win1.mAttrs.providedInsets = new InsetsFrameProvider[] {
+                new InsetsFrameProvider(ITYPE_STATUS_BAR),
+                new InsetsFrameProvider(ITYPE_NAVIGATION_BAR)
+        };
 
         expectThrows(IllegalArgumentException.class, () -> addWindow(win1));
 
         WindowState win2 = createWindow(null, TYPE_STATUS_BAR_SUB_PANEL, "StatusBarSubPanel");
-        win2.mAttrs.providesInsetsTypes = new int[]{ITYPE_CLIMATE_BAR, ITYPE_EXTRA_NAVIGATION_BAR};
+
+        win2.mAttrs.providedInsets = new InsetsFrameProvider[] {
+                new InsetsFrameProvider(ITYPE_CLIMATE_BAR),
+                new InsetsFrameProvider(ITYPE_EXTRA_NAVIGATION_BAR)
+        };
 
         expectThrows(IllegalArgumentException.class, () -> addWindow(win2));
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
index dbb7fae..2956c14 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -168,7 +168,8 @@
         mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda);
 
-        prepareUnresizable(mFirstActivity, SCREEN_ORIENTATION_PORTRAIT);
+        prepareLimitedBounds(mFirstActivity, SCREEN_ORIENTATION_PORTRAIT,
+                false /* isUnresizable */);
         final Rect dagBounds = new Rect(mFirstRoot.getBounds());
         final Rect taskBounds = new Rect(mFirstTask.getBounds());
         final Rect activityBounds = new Rect(mFirstActivity.getBounds());
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
index 1e86522..e502f2f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
@@ -63,7 +63,7 @@
         mLetterbox = new Letterbox(mSurfaces, StubTransaction::new,
                 () -> mAreCornersRounded, () -> Color.valueOf(mColor),
                 () -> mHasWallpaperBackground, () -> mBlurRadius, () -> mDarkScrimAlpha,
-                /* doubleTapCallback= */ x -> {});
+                /* doubleTapCallbackX= */ x -> {}, /* doubleTapCallbackY= */ y -> {});
         mTransaction = spy(StubTransaction.class);
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index feb1c6f..1708ed7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -1229,7 +1229,6 @@
         RecentTaskInfo info = mRecentTasks.createRecentTaskInfo(task, true);
 
         assertTrue(info.supportsMultiWindow);
-        assertTrue(info.supportsSplitScreenMultiWindow);
 
         // The task can be put in split screen even if it is not attached now.
         task.removeImmediately();
@@ -1237,7 +1236,6 @@
         info = mRecentTasks.createRecentTaskInfo(task, true);
 
         assertTrue(info.supportsMultiWindow);
-        assertTrue(info.supportsSplitScreenMultiWindow);
 
         // Test non-resizable.
         // The non-resizable task cannot be put in split screen because of the config.
@@ -1247,7 +1245,6 @@
         info = mRecentTasks.createRecentTaskInfo(task, true);
 
         assertFalse(info.supportsMultiWindow);
-        assertFalse(info.supportsSplitScreenMultiWindow);
 
         // Even if it is not attached, the non-resizable task can be put in split screen as long as
         // the device supports it.
@@ -1256,8 +1253,6 @@
         info = mRecentTasks.createRecentTaskInfo(task, true);
 
         assertTrue(info.supportsMultiWindow);
-        assertTrue(info.supportsSplitScreenMultiWindow);
-
     }
 
     private TaskSnapshot createSnapshot(Point taskSize, Point bufferSize) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 1b19a28..a1d6a50 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -37,13 +37,13 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 
-import android.app.IApplicationThread;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -91,9 +91,15 @@
         TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
         Task recentsStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        final WindowProcessController wpc = mSystemServicesTestRule.addProcess(
+                mRecentsComponent.getPackageName(), mRecentsComponent.getPackageName(),
+                // Use real pid/uid of the test so the corresponding process can be mapped by
+                // Binder.getCallingPid/Uid.
+                WindowManagerService.MY_PID, WindowManagerService.MY_UID);
         ActivityRecord recentActivity = new ActivityBuilder(mAtm)
                 .setComponent(mRecentsComponent)
                 .setTask(recentsStack)
+                .setUseProcess(wpc)
                 .build();
         ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
         topActivity.getRootTask().moveToFront("testRecentsActivityVisiblility");
@@ -106,11 +112,14 @@
                 mRecentsComponent, true /* getRecentsAnimation */);
         // The launch-behind state should make the recents activity visible.
         assertTrue(recentActivity.mVisibleRequested);
+        assertEquals(ActivityTaskManagerService.DEMOTE_TOP_REASON_ANIMATING_RECENTS,
+                mAtm.mDemoteTopAppReasons);
 
         // Simulate the animation is cancelled without changing the stack order.
         recentsAnimation.onAnimationFinished(REORDER_KEEP_IN_PLACE, false /* sendUserLeaveHint */);
         // The non-top recents activity should be invisible by the restored launch-behind state.
         assertFalse(recentActivity.mVisibleRequested);
+        assertEquals(0, mAtm.mDemoteTopAppReasons);
     }
 
     @Test
@@ -138,11 +147,8 @@
                 anyInt() /* startFlags */, any() /* profilerInfo */);
 
         // Assume its process is alive because the caller should be the recents service.
-        WindowProcessController wpc = new WindowProcessController(mAtm, aInfo.applicationInfo,
-                aInfo.processName, aInfo.applicationInfo.uid, 0 /* userId */,
-                mock(Object.class) /* owner */, mock(WindowProcessListener.class));
-        wpc.setThread(mock(IApplicationThread.class));
-        doReturn(wpc).when(mAtm).getProcessController(eq(wpc.mName), eq(wpc.mUid));
+        mSystemServicesTestRule.addProcess(aInfo.packageName, aInfo.processName, 12345 /* pid */,
+                aInfo.applicationInfo.uid);
 
         Intent recentsIntent = new Intent().setComponent(mRecentsComponent);
         // Null animation indicates to preload.
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index e6910c2..027f521 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -79,19 +79,25 @@
 
 /**
  * Build/Install/Run:
- *  atest WmTests:RemoteAnimationControllerTest
+ * atest WmTests:RemoteAnimationControllerTest
  */
 @SmallTest
 @Presubmit
 @RunWith(WindowTestRunner.class)
 public class RemoteAnimationControllerTest extends WindowTestsBase {
 
-    @Mock SurfaceControl mMockLeash;
-    @Mock SurfaceControl mMockThumbnailLeash;
-    @Mock Transaction mMockTransaction;
-    @Mock OnAnimationFinishedCallback mFinishedCallback;
-    @Mock OnAnimationFinishedCallback mThumbnailFinishedCallback;
-    @Mock IRemoteAnimationRunner mMockRunner;
+    @Mock
+    SurfaceControl mMockLeash;
+    @Mock
+    SurfaceControl mMockThumbnailLeash;
+    @Mock
+    Transaction mMockTransaction;
+    @Mock
+    OnAnimationFinishedCallback mFinishedCallback;
+    @Mock
+    OnAnimationFinishedCallback mThumbnailFinishedCallback;
+    @Mock
+    IRemoteAnimationRunner mMockRunner;
     private RemoteAnimationAdapter mAdapter;
     private RemoteAnimationController mController;
     private final OffsettableClock mClock = new OffsettableClock.Stopped();
@@ -105,7 +111,8 @@
         mAdapter = new RemoteAnimationAdapter(mMockRunner, 100, 50, true /* changeNeedsSnapshot */);
         mAdapter.setCallingPidUid(123, 456);
         runWithScissors(mWm.mH, () -> mHandler = new TestHandler(null, mClock), 0);
-        mController = new RemoteAnimationController(mWm, mDisplayContent, mAdapter, mHandler);
+        mController = new RemoteAnimationController(mWm, mDisplayContent, mAdapter,
+                mHandler, false /*isActivityEmbedding*/);
     }
 
     private WindowState createAppOverlayWindow() {
@@ -117,13 +124,47 @@
     }
 
     @Test
+    public void testForwardsShowBackdrop() throws Exception {
+        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
+        mDisplayContent.mOpeningApps.add(win.mActivityRecord);
+        final WindowState overlayWin = createAppOverlayWindow();
+        try {
+            final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
+                    win.mActivityRecord,
+                    new Point(50, 100), null, new Rect(50, 100, 150, 150), null,
+                    true /* showBackdrop */).mAdapter;
+            adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
+                    mFinishedCallback);
+            mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
+            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+            final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
+                    ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
+            final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor =
+                    ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
+            final ArgumentCaptor<RemoteAnimationTarget[]> nonAppsCaptor =
+                    ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
+            final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
+                    ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class);
+            verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN),
+                    appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(),
+                    finishedCaptor.capture());
+            assertEquals(1, appsCaptor.getValue().length);
+            final RemoteAnimationTarget app = appsCaptor.getValue()[0];
+            assertTrue(app.showBackdrop);
+        } finally {
+            mDisplayContent.mOpeningApps.clear();
+        }
+    }
+
+    @Test
     public void testRun() throws Exception {
         final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
         mDisplayContent.mOpeningApps.add(win.mActivityRecord);
         final WindowState overlayWin = createAppOverlayWindow();
         try {
-            final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
-                    new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter;
+            final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
+                    win.mActivityRecord,
+                    new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter;
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
@@ -162,8 +203,9 @@
     @Test
     public void testCancel() throws Exception {
         final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
-        final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
-                new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter;
+        final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
+                win.mActivityRecord,
+                new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter;
         adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                 mFinishedCallback);
         mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
@@ -175,8 +217,9 @@
     @Test
     public void testTimeout() throws Exception {
         final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
-        final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
-                new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter;
+        final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
+                win.mActivityRecord,
+                new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter;
         adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                 mFinishedCallback);
         mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
@@ -197,7 +240,7 @@
                     "testWin");
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                     win.mActivityRecord, new Point(50, 100), null, new Rect(50, 100, 150, 150),
-                    null).mAdapter;
+                    null, false).mAdapter;
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
@@ -229,7 +272,7 @@
     public void testNotReallyStarted() throws Exception {
         final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
         mController.createRemoteAnimationRecord(win.mActivityRecord,
-                new Point(50, 100), null, new Rect(50, 100, 150, 150), null);
+                new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false);
         mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
         verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
         verify(mMockRunner).onAnimationCancelled(anyBoolean());
@@ -240,9 +283,10 @@
         final WindowState win1 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin1");
         final WindowState win2 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin2");
         mController.createRemoteAnimationRecord(win1.mActivityRecord,
-                new Point(50, 100), null, new Rect(50, 100, 150, 150), null);
-        final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win2.mActivityRecord,
-                new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter;
+                new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false);
+        final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
+                win2.mActivityRecord,
+                new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter;
         adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                 mFinishedCallback);
         mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
@@ -265,8 +309,9 @@
     @Test
     public void testRemovedBeforeStarted() throws Exception {
         final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
-        final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
-                new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter;
+        final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
+                win.mActivityRecord,
+                new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter;
         adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                 mFinishedCallback);
         win.mActivityRecord.removeImmediately();
@@ -310,7 +355,7 @@
         try {
             final RemoteAnimationRecord record = mController.createRemoteAnimationRecord(
                     win.mActivityRecord, new Point(50, 100), null, new Rect(50, 100, 150, 150),
-                    new Rect(0, 0, 200, 200));
+                    new Rect(0, 0, 200, 200), false);
             assertNotNull(record.mThumbnailAdapter);
             ((AnimationAdapter) record.mAdapter)
                     .startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION,
@@ -364,7 +409,7 @@
         try {
             final RemoteAnimationRecord record = mController.createRemoteAnimationRecord(
                     win.mActivityRecord, new Point(0, 0), null, new Rect(0, 0, 200, 200),
-                    new Rect(50, 100, 150, 150));
+                    new Rect(50, 100, 150, 150), false);
             assertNotNull(record.mThumbnailAdapter);
             ((AnimationAdapter) record.mAdapter)
                     .startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION,
@@ -418,7 +463,7 @@
         try {
             final RemoteAnimationRecord record = mController.createRemoteAnimationRecord(
                     win.mActivityRecord, new Point(100, 100), null, new Rect(150, 150, 400, 400),
-                    new Rect(50, 100, 150, 150));
+                    new Rect(50, 100, 150, 150), false);
             assertNotNull(record.mThumbnailAdapter);
             ((AnimationAdapter) record.mAdapter)
                     .startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION,
@@ -475,8 +520,9 @@
         final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
         mDisplayContent.mOpeningApps.add(win.mActivityRecord);
         try {
-            final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
-                    new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter;
+            final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
+                    win.mActivityRecord,
+                    new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter;
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
@@ -507,8 +553,9 @@
         final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
         mDisplayContent.mOpeningApps.add(win.mActivityRecord);
         try {
-            final AnimationAdapter adapter = mController.createRemoteAnimationRecord(win.mActivityRecord,
-                    new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter;
+            final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
+                    win.mActivityRecord,
+                    new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false).mAdapter;
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
@@ -544,7 +591,7 @@
         try {
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                     win.mActivityRecord, new Point(50, 100), null,
-                    new Rect(50, 100, 150, 150), null).mAdapter;
+                    new Rect(50, 100, 150, 150), null, false).mAdapter;
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_KEYGUARD_GOING_AWAY);
@@ -594,7 +641,7 @@
         try {
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                     win.mActivityRecord, new Point(50, 100), null,
-                    new Rect(50, 100, 150, 150), null).mAdapter;
+                    new Rect(50, 100, 150, 150), null, false).mAdapter;
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
             mController.goodToGo(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER);
@@ -728,7 +775,7 @@
             mDisplayContent.mOpeningApps.add(win2.mActivityRecord);
             final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                     win2.mActivityRecord, new Point(50, 100), null,
-                    new Rect(50, 100, 150, 150), null).mAdapter;
+                    new Rect(50, 100, 150, 150), null, false).mAdapter;
             adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                     mFinishedCallback);
 
@@ -758,7 +805,7 @@
 
         final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                 win.mActivityRecord, new Point(50, 100), null,
-                new Rect(50, 100, 150, 150), null).mAdapter;
+                new Rect(50, 100, 150, 150), null, false).mAdapter;
         adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                 mFinishedCallback);
         mController.goodToGo(transit);
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 700fadd..68079f4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -657,7 +657,7 @@
 
         doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
 
-        mAtm.setBooted(true);
+        setBooted(mAtm);
 
         // Trigger resume on all displays
         mRootWindowContainer.resumeFocusedTasksTopActivities();
@@ -685,7 +685,7 @@
 
         doReturn(true).when(mRootWindowContainer).resumeHomeActivity(any(), any(), any());
 
-        mAtm.setBooted(true);
+        setBooted(mAtm);
 
         // Trigger resume on all displays
         mRootWindowContainer.resumeFocusedTasksTopActivities();
@@ -771,17 +771,10 @@
     @Test
     public void testNotStartHomeBeforeBoot() {
         final int displayId = 1;
-        final boolean isBooting = mAtm.mAmInternal.isBooting();
-        final boolean isBooted = mAtm.mAmInternal.isBooted();
-        try {
-            mAtm.mAmInternal.setBooting(false);
-            mAtm.mAmInternal.setBooted(false);
-            mRootWindowContainer.onDisplayAdded(displayId);
-            verify(mRootWindowContainer, never()).startHomeOnDisplay(anyInt(), any(), anyInt());
-        } finally {
-            mAtm.mAmInternal.setBooting(isBooting);
-            mAtm.mAmInternal.setBooted(isBooted);
-        }
+        doReturn(false).when(mAtm).isBooting();
+        doReturn(false).when(mAtm).isBooted();
+        mRootWindowContainer.onDisplayAdded(displayId);
+        verify(mRootWindowContainer, never()).startHomeOnDisplay(anyInt(), any(), anyInt());
     }
 
     /**
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 891b33b..324e244 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -1259,6 +1259,36 @@
     }
 
     @Test
+    @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
+            ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE})
+    public void testOverrideMinAspectRatioLargeForResizableAppInSplitScreen() {
+        setUpDisplaySizeWithApp(/* dw= */ 1000, /* dh= */ 2800);
+
+        // Create a size compat activity on the same task.
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setTask(mTask)
+                .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+                .setComponent(ComponentName.createRelative(mContext,
+                        SizeCompatTests.class.getName()))
+                .setUid(android.os.Process.myUid())
+                .build();
+
+        final TestSplitOrganizer organizer =
+                new TestSplitOrganizer(mAtm, activity.getDisplayContent());
+
+        // Move activity to split screen which takes half of the screen.
+        mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test");
+        organizer.mPrimary.setBounds(0, 0, 1000, 1400);
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode());
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW, activity.getWindowingMode());
+
+        // The per-package override forces the activity into a 16:9 aspect ratio
+        assertEquals(1400, activity.getBounds().height());
+        assertEquals(1400 / ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
+                activity.getBounds().width(), 0.5);
+    }
+
+    @Test
     public void testLaunchWithFixedRotationTransform() {
         final int dw = 1000;
         final int dh = 2500;
@@ -1409,12 +1439,10 @@
         setUpDisplaySizeWithApp(2800, 1400);
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
 
-        // Portrait fixed app with min aspect ratio higher that aspect ratio override for fixed
-        // orientation letterbox.
         final float fixedOrientationLetterboxAspectRatio = 1.1f;
         mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(
                 fixedOrientationLetterboxAspectRatio);
-        prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT);
+        prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_PORTRAIT, /* isUnresizable= */ false);
 
         final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
         final Rect activityBounds = new Rect(mActivity.getBounds());
@@ -1435,6 +1463,111 @@
     }
 
     @Test
+    public void testDisplayIgnoreOrientationRequest_unresizableWithCorrespondingMinAspectRatio() {
+        // Set up a display in landscape and ignoring orientation request.
+        setUpDisplaySizeWithApp(2800, 1400);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        final float fixedOrientationLetterboxAspectRatio = 1.1f;
+        mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(
+                fixedOrientationLetterboxAspectRatio);
+        mActivity.mWmService.mLetterboxConfiguration.setDefaultMinAspectRatioForUnresizableApps(
+                1.5f);
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+
+        final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+        final Rect activityBounds = new Rect(mActivity.getBounds());
+
+        // Display shouldn't be rotated.
+        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED,
+                mActivity.mDisplayContent.getLastOrientation());
+        assertTrue(displayBounds.width() > displayBounds.height());
+
+        // App should launch in fixed orientation letterbox.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        assertFalse(mActivity.inSizeCompatMode());
+
+        // Letterbox logic should use config_letterboxDefaultMinAspectRatioForUnresizableApps over
+        // config_fixedOrientationLetterboxAspectRatio.
+        assertEquals(displayBounds.height(), activityBounds.height());
+        final float defaultAspectRatio = mActivity.mWmService.mLetterboxConfiguration
+                .getDefaultMinAspectRatioForUnresizableApps();
+        assertEquals(displayBounds.height() / defaultAspectRatio, activityBounds.width(), 0.5);
+    }
+
+    @Test
+    public void testSplitAspectRatioForUnresizablePortraitApps() {
+        // Set up a display in landscape and ignoring orientation request.
+        int screenWidth = 1600;
+        int screenHeight = 1400;
+        setUpDisplaySizeWithApp(screenWidth, screenHeight);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mActivity.mWmService.mLetterboxConfiguration
+                        .setIsSplitScreenAspectRatioForUnresizableAppsEnabled(true);
+
+        mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(1.1f);
+
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+
+        final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+        final Rect activityBounds = new Rect(mActivity.getBounds());
+
+        // App should launch in fixed orientation letterbox.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        // Checking that there is no size compat mode.
+        assertFitted();
+
+        assertEquals(displayBounds.height(), activityBounds.height());
+        assertTrue(activityBounds.width() < displayBounds.width() / 2);
+
+        final TestSplitOrganizer organizer =
+                new TestSplitOrganizer(mAtm, mActivity.getDisplayContent());
+        // Move activity to split screen which takes half of the screen.
+        mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test");
+        organizer.mPrimary.setBounds(0, 0, getExpectedSplitSize(screenWidth), screenHeight);
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode());
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode());
+        // Checking that there is no size compat mode.
+        assertFitted();
+    }
+
+    @Test
+    public void testSplitAspectRatioForUnresizableLandscapeApps() {
+        // Set up a display in portrait and ignoring orientation request.
+        int screenWidth = 1400;
+        int screenHeight = 1600;
+        setUpDisplaySizeWithApp(screenWidth, screenHeight);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mActivity.mWmService.mLetterboxConfiguration
+                        .setIsSplitScreenAspectRatioForUnresizableAppsEnabled(true);
+
+        mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(1.1f);
+
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+        final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds());
+        final Rect activityBounds = new Rect(mActivity.getBounds());
+
+        // App should launch in fixed orientation letterbox.
+        assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
+        // Checking that there is no size compat mode.
+        assertFitted();
+
+        assertEquals(displayBounds.width(), activityBounds.width());
+        assertTrue(activityBounds.height() < displayBounds.height() / 2);
+
+        final TestSplitOrganizer organizer =
+                new TestSplitOrganizer(mAtm, mActivity.getDisplayContent());
+        // Move activity to split screen which takes half of the screen.
+        mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test");
+        organizer.mPrimary.setBounds(0, 0, screenWidth, getExpectedSplitSize(screenHeight));
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode());
+        assertEquals(WINDOWING_MODE_MULTI_WINDOW, mActivity.getWindowingMode());
+        // Checking that there is no size compat mode.
+        assertFitted();
+    }
+
+    @Test
     public void
             testDisplayIgnoreOrientationRequest_orientationLetterboxBecameSizeCompatAfterRotate() {
         // Set up a display in landscape and ignoring orientation request.
@@ -1908,7 +2041,7 @@
     }
 
     @Test
-    public void testSupportsNonResizableInSplitScreen_fillTaskForSameOrientation() {
+    public void testSupportsNonResizableInSplitScreen_aspectRatioLetterboxInSameOrientation() {
         // Support non resizable in multi window
         mAtm.mDevEnableNonResizableMultiWindow = true;
         setUpDisplaySizeWithApp(1000, 2800);
@@ -1960,7 +2093,7 @@
         prepareUnresizable(mActivity, /* maxAspect */ 1.1f, SCREEN_ORIENTATION_UNSPECIFIED);
 
         // Bounds are letterboxed to respect the provided max aspect ratio.
-        assertEquals(mActivity.getBounds(), new Rect(0, 0, 1000, 1100));
+        assertEquals(mActivity.getBounds(), new Rect(0, 850, 1000, 1950));
 
         // Move activity to split screen which has landscape size.
         mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents */ false, "test");
@@ -2077,19 +2210,14 @@
         mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
                 letterboxHorizontalPositionMultiplier);
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
-
         assertEquals(fixedOrientationLetterbox, mActivity.getBounds());
-
         // Rotate to put activity in size compat mode.
         rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
-
         assertTrue(mActivity.inSizeCompatMode());
         // Activity is in size compat mode but not scaled.
         assertEquals(sizeCompatUnscaled, mActivity.getBounds());
-
         // Force activity to scaled down for size compat mode.
         resizeDisplay(mTask.mDisplayContent, 700, 1400);
-
         assertTrue(mActivity.inSizeCompatMode());
         assertScaled();
         assertEquals(sizeCompatScaled, mActivity.getBounds());
@@ -2107,6 +2235,109 @@
     }
 
     @Test
+    public void testUpdateResolvedBoundsVerticalPosition_top() {
+        // Display configured as (1400, 2800).
+        assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+                /* letterboxVerticalPositionMultiplier */ 0.0f,
+                // At launch.
+                /* fixedOrientationLetterbox */ new Rect(0, 0, 1400, 700),
+                // After 90 degree rotation.
+                /* sizeCompatUnscaled */ new Rect(700, 0, 2100, 700),
+                // After the display is resized to (1400, 700).
+                /* sizeCompatScaled */ new Rect(0, 0, 700, 350));
+    }
+
+    @Test
+    public void testUpdateResolvedBoundsVerticalPosition_center() {
+        // Display configured as (1400, 2800).
+        assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+                /* letterboxVerticalPositionMultiplier */ 0.5f,
+                // At launch.
+                /* fixedOrientationLetterbox */ new Rect(0, 1050, 1400, 1750),
+                // After 90 degree rotation.
+                /* sizeCompatUnscaled */ new Rect(700, 350, 2100, 1050),
+                // After the display is resized to (1400, 700).
+                /* sizeCompatScaled */ new Rect(0, 525, 700, 875));
+    }
+
+    @Test
+    public void testUpdateResolvedBoundsVerticalPosition_invalidMultiplier_defaultToCenter() {
+        // Display configured as (1400, 2800).
+
+        // Below 0.0.
+        assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+                /* letterboxVerticalPositionMultiplier */ -1.0f,
+                // At launch.
+                /* fixedOrientationLetterbox */ new Rect(0, 1050, 1400, 1750),
+                // After 90 degree rotation.
+                /* sizeCompatUnscaled */ new Rect(700, 350, 2100, 1050),
+                // After the display is resized to (1400, 700).
+                /* sizeCompatScaled */ new Rect(0, 525, 700, 875));
+
+        // Above 1.0
+        assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+                /* letterboxVerticalPositionMultiplier */ 2.0f,
+                // At launch.
+                /* fixedOrientationLetterbox */ new Rect(0, 1050, 1400, 1750),
+                // After 90 degree rotation.
+                /* sizeCompatUnscaled */ new Rect(700, 350, 2100, 1050),
+                // After the display is resized to (1400, 700).
+                /* sizeCompatScaled */ new Rect(0, 525, 700, 875));
+    }
+
+    @Test
+    public void testUpdateResolvedBoundsVerticalPosition_bottom() {
+        // Display configured as (1400, 2800).
+        assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+                /* letterboxVerticalPositionMultiplier */ 1.0f,
+                // At launch.
+                /* fixedOrientationLetterbox */ new Rect(0, 2100, 1400, 2800),
+                // After 90 degree rotation.
+                /* sizeCompatUnscaled */ new Rect(700, 700, 2100, 1400),
+                // After the display is resized to (1400, 700).
+                /* sizeCompatScaled */ new Rect(0, 1050, 700, 1400));
+    }
+
+    private void assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
+            float letterboxVerticalPositionMultiplier, Rect fixedOrientationLetterbox,
+            Rect sizeCompatUnscaled, Rect sizeCompatScaled) {
+        // Set up a display in portrait and ignoring orientation request.
+        setUpDisplaySizeWithApp(1400, 2800);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(
+                letterboxVerticalPositionMultiplier);
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+
+        assertEquals(fixedOrientationLetterbox, mActivity.getBounds());
+
+        // Rotate to put activity in size compat mode.
+        rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+
+        assertTrue(mActivity.inSizeCompatMode());
+        // Activity is in size compat mode but not scaled.
+        assertEquals(sizeCompatUnscaled, mActivity.getBounds());
+
+        // Force activity to scaled down for size compat mode.
+        resizeDisplay(mTask.mDisplayContent, 1400, 700);
+
+        assertTrue(mActivity.inSizeCompatMode());
+        assertScaled();
+        assertEquals(sizeCompatScaled, mActivity.getBounds());
+    }
+
+    @Test
+    public void testUpdateResolvedBoundsVerticalPosition_activityFillParentHeight() {
+        // When activity height equals parent height, multiplier shouldn't have any effect.
+        assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity(
+                /* letterboxVerticalPositionMultiplier */ 0.0f);
+        assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity(
+                /* letterboxVerticalPositionMultiplier */ 0.5f);
+        assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity(
+                /* letterboxVerticalPositionMultiplier */ 1.0f);
+    }
+
+    @Test
     public void testAreBoundsLetterboxed_letterboxedForAspectRatio_returnsTrue() {
         setUpDisplaySizeWithApp(1000, 2500);
 
@@ -2390,6 +2621,16 @@
         assertEquals(newDensity, mActivity.getConfiguration().densityDpi);
     }
 
+    private int getExpectedSplitSize(int dimensionToSplit) {
+        int dividerWindowWidth =
+                mActivity.mWmService.mContext.getResources().getDimensionPixelSize(
+                        com.android.internal.R.dimen.docked_stack_divider_thickness);
+        int dividerInsets =
+                mActivity.mWmService.mContext.getResources().getDimensionPixelSize(
+                        com.android.internal.R.dimen.docked_stack_divider_insets);
+        return (dimensionToSplit - (dividerWindowWidth - dividerInsets * 2)) / 2;
+    }
+
     private void assertHorizontalPositionForDifferentDisplayConfigsForLandscapeActivity(
             float letterboxHorizontalPositionMultiplier) {
         // Set up a display in landscape and ignoring orientation request.
@@ -2399,6 +2640,23 @@
         mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
                 letterboxHorizontalPositionMultiplier);
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+        assertFitted();
+        // Rotate to put activity in size compat mode.
+        rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
+        assertTrue(mActivity.inSizeCompatMode());
+        // Activity is in size compat mode but not scaled.
+        assertEquals(new Rect(0, 1050, 1400, 1750), mActivity.getBounds());
+    }
+
+    private void assertVerticalPositionForDifferentDisplayConfigsForPortraitActivity(
+            float letterboxVerticalPositionMultiplier) {
+        // Set up a display in portrait and ignoring orientation request.
+        setUpDisplaySizeWithApp(1400, 2800);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(
+                letterboxVerticalPositionMultiplier);
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
 
         assertFitted();
 
@@ -2407,7 +2665,7 @@
 
         assertTrue(mActivity.inSizeCompatMode());
         // Activity is in size compat mode but not scaled.
-        assertEquals(new Rect(0, 1050, 1400, 1750), mActivity.getBounds());
+        assertEquals(new Rect(1050, 0, 1750, 1400), mActivity.getBounds());
     }
 
     private static WindowState addWindowToActivity(ActivityRecord activity) {
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 dc9a625..6c100d7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -43,12 +43,14 @@
 
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
+import android.app.IApplicationThread;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.database.ContentObserver;
@@ -66,7 +68,6 @@
 import android.provider.DeviceConfig;
 import android.util.Log;
 import android.view.InputChannel;
-import android.view.Surface;
 import android.view.SurfaceControl;
 
 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
@@ -77,7 +78,6 @@
 import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerService;
-import com.android.server.appop.AppOpsService;
 import com.android.server.display.color.ColorDisplayService;
 import com.android.server.firewall.IntentFirewall;
 import com.android.server.input.InputManagerService;
@@ -94,10 +94,8 @@
 import org.mockito.Mockito;
 import org.mockito.quality.Strictness;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Supplier;
 
 /**
  * JUnit test rule to correctly setting up system services like {@link WindowManagerService}
@@ -125,13 +123,11 @@
     private Description mDescription;
     private Context mContext;
     private StaticMockitoSession mMockitoSession;
-    private ActivityManagerService mAmService;
     private ActivityTaskManagerService mAtmService;
     private WindowManagerService mWmService;
     private WindowState.PowerManagerWrapper mPowerManagerWrapper;
     private InputManagerService mImService;
     private InputChannel mInputChannel;
-    private Supplier<Surface> mSurfaceFactory = () -> mock(Surface.class);
     /**
      * Spied {@link SurfaceControl.Transaction} class than can be used to verify calls.
      */
@@ -289,29 +285,9 @@
     }
 
     private void setUpActivityTaskManagerService() {
-        // ActivityManagerService
-        mAmService = new ActivityManagerService(new AMTestInjector(mContext), null /* thread */);
-        spyOn(mAmService);
-        doReturn(mock(IPackageManager.class)).when(mAmService).getPackageManager();
-        doNothing().when(mAmService).grantImplicitAccess(
-                anyInt(), any(), anyInt(), anyInt());
-
         // ActivityManagerInternal
-        final ActivityManagerInternal amInternal = mAmService.mInternal;
-        spyOn(amInternal);
-        doNothing().when(amInternal).trimApplications();
-        doNothing().when(amInternal).scheduleAppGcs();
-        doNothing().when(amInternal).updateCpuStats();
-        doNothing().when(amInternal).updateOomAdj();
-        doNothing().when(amInternal).updateBatteryStats(any(), anyInt(), anyInt(), anyBoolean());
-        doNothing().when(amInternal).updateActivityUsageStats(
-                any(), anyInt(), anyInt(), any(), any());
-        doNothing().when(amInternal).startProcess(
-                any(), any(), anyBoolean(), anyBoolean(), any(), any());
-        doNothing().when(amInternal).updateOomLevelsForDisplay(anyInt());
-        doNothing().when(amInternal).broadcastGlobalConfigurationChanged(anyInt(), anyBoolean());
-        doNothing().when(amInternal).cleanUpServices(anyInt(), any(), any());
-        doNothing().when(amInternal).reportCurKeyguardUsageEvent(anyBoolean());
+        final ActivityManagerInternal amInternal =
+                mock(ActivityManagerInternal.class, withSettings().stubOnly());
         doReturn(UserHandle.USER_SYSTEM).when(amInternal).getCurrentUserId();
         doReturn(TEST_USER_PROFILE_IDS).when(amInternal).getCurrentProfileIds();
         doReturn(true).when(amInternal).isUserRunning(anyInt(), anyInt());
@@ -320,7 +296,9 @@
         doReturn(false).when(amInternal).isActivityStartsLoggingEnabled();
         LocalServices.addService(ActivityManagerInternal.class, amInternal);
 
-        mAtmService = new TestActivityTaskManagerService(mContext, mAmService);
+        final ActivityManagerService amService =
+                mock(ActivityManagerService.class, withSettings().stubOnly());
+        mAtmService = new TestActivityTaskManagerService(mContext, amService);
         LocalServices.addService(ActivityTaskManagerInternal.class, mAtmService.getAtmInternal());
     }
 
@@ -334,7 +312,7 @@
         mWmService = WindowManagerService.main(
                 mContext, mImService, false, false, wmPolicy, mAtmService,
                 testDisplayWindowSettingsProvider, StubTransaction::new,
-                () -> mSurfaceFactory.get(), (unused) -> new MockSurfaceControlBuilder());
+                (unused) -> new MockSurfaceControlBuilder());
         spyOn(mWmService);
         spyOn(mWmService.mRoot);
         // Invoked during {@link ActivityStack} creation.
@@ -355,7 +333,7 @@
                 null, null, mTransaction, mWmService.mPowerManagerInternal);
 
         mWmService.onInitReady();
-        mAmService.setWindowManager(mWmService);
+        mAtmService.setWindowManager(mWmService);
         mWmService.mDisplayEnabled = true;
         mWmService.mDisplayReady = true;
         // Set configuration for default display
@@ -454,8 +432,32 @@
                 .spiedInstance(sWakeLock).stubOnly());
     }
 
-    void setSurfaceFactory(Supplier<Surface> factory) {
-        mSurfaceFactory = factory;
+    WindowProcessController addProcess(String pkgName, String procName, int pid, int uid) {
+        return addProcess(mAtmService, pkgName, procName, pid, uid);
+    }
+
+    static WindowProcessController addProcess(ActivityTaskManagerService atmService, String pkgName,
+            String procName, int pid, int uid) {
+        final ApplicationInfo info = new ApplicationInfo();
+        info.uid = uid;
+        info.packageName = pkgName;
+        return addProcess(atmService, info, procName, pid);
+    }
+
+    static WindowProcessController addProcess(ActivityTaskManagerService atmService,
+            ApplicationInfo info, String procName, int pid) {
+        final WindowProcessListener mockListener = mock(WindowProcessListener.class,
+                withSettings().stubOnly());
+        final int uid = info.uid;
+        final WindowProcessController proc = new WindowProcessController(atmService,
+                info, procName, uid, UserHandle.getUserId(uid), mockListener, mockListener);
+        proc.setThread(mock(IApplicationThread.class, withSettings().stubOnly()));
+        atmService.mProcessNames.put(procName, uid, proc);
+        if (pid > 0) {
+            proc.setPid(pid);
+            atmService.mProcessMap.put(pid, proc);
+        }
+        return proc;
     }
 
     void cleanupWindowManagerHandlers() {
@@ -618,32 +620,4 @@
             doReturn(true).when(controller).checkKeyguardVisibility(any());
         }
     }
-
-    // TODO: Can we just mock this?
-    private static class AMTestInjector extends ActivityManagerService.Injector {
-
-        AMTestInjector(Context context) {
-            super(context);
-        }
-
-        @Override
-        public Context getContext() {
-            return getInstrumentation().getTargetContext();
-        }
-
-        @Override
-        public AppOpsService getAppOpsService(File file, Handler handler) {
-            return null;
-        }
-
-        @Override
-        public Handler getUiHandler(ActivityManagerService service) {
-            return UiThread.getHandler();
-        }
-
-        @Override
-        public boolean isNetworkRestrictedForUid(int uid) {
-            return false;
-        }
-    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index e8f1d23..7f09606 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
@@ -82,7 +82,7 @@
                 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
         adjacentRootTask.mCreatedByOrganizer = true;
         final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea();
-        adjacentRootTask.setAdjacentTaskFragment(rootTask, false /* moveTogether */);
+        adjacentRootTask.setAdjacentTaskFragment(rootTask);
 
         taskDisplayArea.setLaunchAdjacentFlagRootTask(adjacentRootTask);
         Task actualRootTask = taskDisplayArea.getLaunchRootTask(
@@ -108,7 +108,7 @@
         final Task adjacentRootTask = createTask(
                 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
         adjacentRootTask.mCreatedByOrganizer = true;
-        adjacentRootTask.setAdjacentTaskFragment(rootTask, false /* moveTogether */);
+        adjacentRootTask.setAdjacentTaskFragment(rootTask);
 
         taskDisplayArea.setLaunchRootTask(rootTask,
                 new int[]{WINDOWING_MODE_MULTI_WINDOW}, new int[]{ACTIVITY_TYPE_STANDARD});
@@ -129,7 +129,7 @@
                 mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
         adjacentRootTask.mCreatedByOrganizer = true;
         final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea();
-        adjacentRootTask.setAdjacentTaskFragment(rootTask, false /* moveTogether */);
+        adjacentRootTask.setAdjacentTaskFragment(rootTask);
 
         taskDisplayArea.setLaunchAdjacentFlagRootTask(adjacentRootTask);
         final Task actualRootTask = taskDisplayArea.getLaunchRootTask(
@@ -756,18 +756,26 @@
         adjacentRootTask.mCreatedByOrganizer = true;
         final Task candidateTask = createTaskInRootTask(rootTask, 0 /* userId*/);
         final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea();
-        adjacentRootTask.setAdjacentTaskFragment(rootTask, false /* moveTogether */);
+        adjacentRootTask.setAdjacentTaskFragment(rootTask);
 
         // Verify the launch root with candidate task
         Task actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED,
                 ACTIVITY_TYPE_STANDARD, null /* options */, adjacentRootTask /* sourceTask */,
                 0 /* launchFlags */, candidateTask);
-        assertSame(rootTask, actualRootTask.getRootTask());
+        assertSame(rootTask, actualRootTask);
 
         // Verify the launch root task without candidate task
         actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED,
                 ACTIVITY_TYPE_STANDARD, null /* options */, adjacentRootTask /* sourceTask */,
                 0 /* launchFlags */);
-        assertSame(adjacentRootTask, actualRootTask.getRootTask());
+        assertSame(adjacentRootTask, actualRootTask);
+
+        final Task pinnedTask = createTask(
+                mDisplayContent, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
+        // Verify not adjusting launch target for pinned candidate task
+        actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED,
+                ACTIVITY_TYPE_STANDARD, null /* options */, adjacentRootTask /* sourceTask */,
+                0 /* launchFlags */, pinnedTask /* candidateTask */);
+        assertNull(actualRootTask);
     }
 }
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 8202cd9..1c3b869 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -34,7 +34,6 @@
 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.eq;
 import static org.mockito.Mockito.clearInvocations;
@@ -421,7 +420,7 @@
 
         // Throw exception if the transaction is trying to change a window that is not organized by
         // the organizer.
-        mTransaction.setAdjacentRoots(mFragmentWindowToken, token2, false /* moveTogether */);
+        mTransaction.setAdjacentRoots(mFragmentWindowToken, token2);
 
         assertApplyTransactionDisallowed(mTransaction);
 
@@ -636,7 +635,7 @@
 
         verify(mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
                 eq(mErrorToken), any(IllegalArgumentException.class));
-        verify(mTaskFragment, never()).setAdjacentTaskFragment(any(), anyBoolean());
+        verify(mTaskFragment, never()).setAdjacentTaskFragment(any());
     }
 
     @Test
@@ -923,13 +922,14 @@
                 .build();
         doReturn(true).when(mTaskFragment).isAllowedToEmbedActivity(activity);
         mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
-        clearInvocations(mAtm.mRootWindowContainer);
 
         // Reparent activity to mTaskFragment, which is smaller than activity's
         // minimum dimensions.
         mTransaction.reparentActivityToTaskFragment(mFragmentToken, activity.token)
                 .setErrorCallbackToken(mErrorToken);
         mWindowOrganizerController.applyTransaction(mTransaction);
+        // The pending event will be dispatched on the handler (from requestTraversal).
+        waitHandlerIdle(mWm.mAnimationHandler);
 
         verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(SecurityException.class));
     }
@@ -959,7 +959,6 @@
         doReturn(true).when(mTaskFragment).isAllowedToEmbedActivity(activity);
         mWindowOrganizerController.mLaunchTaskFragments.put(oldFragToken, oldTaskFrag);
         mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
-        clearInvocations(mAtm.mRootWindowContainer);
 
         // Reparent oldTaskFrag's children to mTaskFragment, which is smaller than activity's
         // minimum dimensions.
@@ -967,6 +966,8 @@
                         mTaskFragment.mRemoteToken.toWindowContainerToken())
                 .setErrorCallbackToken(mErrorToken);
         mWindowOrganizerController.applyTransaction(mTransaction);
+        // The pending event will be dispatched on the handler (from requestTraversal).
+        waitHandlerIdle(mWm.mAnimationHandler);
 
         verify(mOrganizer).onTaskFragmentError(eq(mErrorToken), any(SecurityException.class));
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 3ed484a..5f30963 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -202,7 +202,7 @@
         doReturn(true).when(primaryActivity).supportsPictureInPicture();
         doReturn(false).when(secondaryActivity).supportsPictureInPicture();
 
-        primaryTf.setAdjacentTaskFragment(secondaryTf, false /* moveAdjacentTogether */);
+        primaryTf.setAdjacentTaskFragment(secondaryTf);
         primaryActivity.setState(RESUMED, "test");
         secondaryActivity.setState(RESUMED, "test");
 
@@ -448,7 +448,7 @@
                 .setOrganizer(mOrganizer)
                 .setFragmentToken(new Binder())
                 .build();
-        tf0.setAdjacentTaskFragment(tf1, false /* moveAdjacentTogether */);
+        tf0.setAdjacentTaskFragment(tf1);
         tf0.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         tf1.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         task.setBounds(0, 0, 1200, 1000);
@@ -475,5 +475,13 @@
         assertFalse(activity0.isLetterboxedForFixedOrientationAndAspectRatio());
         assertFalse(activity1.isLetterboxedForFixedOrientationAndAspectRatio());
         assertEquals(SCREEN_ORIENTATION_UNSET, task.getOrientation());
+
+        tf0.setResumedActivity(activity0, "test");
+        tf1.setResumedActivity(activity1, "test");
+        mDisplayContent.mFocusedApp = activity1;
+
+        // Making the activity0 be the focused activity and ensure the focused app is updated.
+        activity0.moveFocusableActivityToTop("test");
+        assertEquals(activity0, mDisplayContent.mFocusedApp);
     }
 }
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 202168b..46e21f1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -31,7 +31,6 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.util.DisplayMetrics.DENSITY_DEFAULT;
 import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_ENABLED;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_90;
@@ -60,7 +59,6 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.clearInvocations;
@@ -497,34 +495,6 @@
         assertEquals(reqBounds.height(), task.getBounds().height());
     }
 
-    /** Tests that the task bounds adjust properly to changes between FULLSCREEN and FREEFORM */
-    @Test
-    public void testBoundsOnModeChangeFreeformToFullscreen() {
-        DisplayContent display = mAtm.mRootWindowContainer.getDefaultDisplay();
-        Task rootTask = new TaskBuilder(mSupervisor).setDisplay(display).setCreateActivity(true)
-                .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
-        Task task = rootTask.getBottomMostTask();
-        task.getRootActivity().setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
-        DisplayInfo info = new DisplayInfo();
-        display.mDisplay.getDisplayInfo(info);
-        final Rect fullScreenBounds = new Rect(0, 0, info.logicalWidth, info.logicalHeight);
-        final Rect freeformBounds = new Rect(fullScreenBounds);
-        freeformBounds.inset((int) (freeformBounds.width() * 0.2),
-                (int) (freeformBounds.height() * 0.2));
-        task.setBounds(freeformBounds);
-
-        assertEquals(freeformBounds, task.getBounds());
-
-        // FULLSCREEN inherits bounds
-        rootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        assertEquals(fullScreenBounds, task.getBounds());
-        assertEquals(freeformBounds, task.mLastNonFullscreenBounds);
-
-        // FREEFORM restores bounds
-        rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
-        assertEquals(freeformBounds, task.getBounds());
-    }
-
     /**
      * Tests that a task with forced orientation has orientation-consistent bounds within the
      * parent.
@@ -590,6 +560,7 @@
 
         // FULLSCREEN letterboxes bounds on activity level, no constraint on task level.
         rootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        rootTask.setBounds(null);
         assertThat(task.getBounds().height()).isGreaterThan(task.getBounds().width());
         assertThat(top.getBounds().width()).isGreaterThan(top.getBounds().height());
         assertEquals(fullScreenBoundsPort, task.getBounds());
@@ -667,8 +638,6 @@
         final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
         final Configuration inOutConfig = new Configuration();
         final Configuration parentConfig = new Configuration();
-        final int longSide = 1200;
-        final int shortSide = 600;
         final Rect parentBounds = new Rect(0, 0, 250, 500);
         final Rect parentAppBounds = new Rect(0, 0, 250, 480);
         parentConfig.windowConfiguration.setBounds(parentBounds);
@@ -689,14 +658,17 @@
         // If bounds are overridden, config properties should be made to match. Surface hierarchy
         // will crop for policy.
         inOutConfig.setToDefaults();
+        final int longSide = 960;
+        final int shortSide = 540;
+        parentConfig.densityDpi = 192;
         final Rect largerPortraitBounds = new Rect(0, 0, shortSide, longSide);
         inOutConfig.windowConfiguration.setBounds(largerPortraitBounds);
         task.computeConfigResourceOverrides(inOutConfig, parentConfig);
         // The override bounds are beyond the parent, the out appBounds should not be intersected
         // by parent appBounds.
         assertEquals(largerPortraitBounds, inOutConfig.windowConfiguration.getAppBounds());
-        assertEquals(longSide, inOutConfig.screenHeightDp * parentConfig.densityDpi / 160);
-        assertEquals(shortSide, inOutConfig.screenWidthDp * parentConfig.densityDpi / 160);
+        assertEquals(800, inOutConfig.screenHeightDp); // 960/(192/160) = 800
+        assertEquals(450, inOutConfig.screenWidthDp); // 540/(192/160) = 450
 
         inOutConfig.setToDefaults();
         // Landscape bounds.
@@ -716,16 +688,17 @@
         // Without limiting to be inside the parent bounds, the out screen size should keep relative
         // to the input bounds.
         final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
-        final ActivityRecord.CompatDisplayInsets compatIntsets =
+        final ActivityRecord.CompatDisplayInsets compatInsets =
                 new ActivityRecord.CompatDisplayInsets(
                         display, activity, /* fixedOrientationBounds= */ null);
-        task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatIntsets);
+        task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatInsets);
 
         assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds());
-        assertEquals((shortSide - statusBarHeight) * DENSITY_DEFAULT / parentConfig.densityDpi,
-                inOutConfig.screenHeightDp);
-        assertEquals(longSide * DENSITY_DEFAULT / parentConfig.densityDpi,
-                inOutConfig.screenWidthDp);
+        final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+        final int expectedHeightDp = (int) ((shortSide - statusBarHeight) / density + 0.5f);
+        assertEquals(expectedHeightDp, inOutConfig.screenHeightDp);
+        final int expectedWidthDp = (int) (longSide / density + 0.5f);
+        assertEquals(expectedWidthDp, inOutConfig.screenWidthDp);
         assertEquals(Configuration.ORIENTATION_LANDSCAPE, inOutConfig.orientation);
     }
 
@@ -1443,25 +1416,6 @@
     }
 
     @Test
-    public void testMoveToFront_moveAdjacentTask() {
-        final Task task1 =
-                createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
-        final Task task2 =
-                createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
-        spyOn(task2);
-
-        task1.setAdjacentTaskFragment(task2, false /* moveTogether */);
-        task1.moveToFront("" /* reason */);
-        verify(task2, never()).moveToFrontInner(anyString(), isNull());
-
-        // Reset adjacent tasks to move together.
-        task1.setAdjacentTaskFragment(null, false /* moveTogether */);
-        task1.setAdjacentTaskFragment(task2, true /* moveTogether */);
-        task1.moveToFront("" /* reason */);
-        verify(task2).moveToFrontInner(anyString(), isNull());
-    }
-
-    @Test
     public void testResumeTask_doNotResumeTaskFragmentBehindTranslucent() {
         final Task task = createTask(mDisplayContent);
         final TaskFragment tfBehind = createTaskFragmentWithParentTask(
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index ea98b6b..92457c7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -26,7 +26,6 @@
 import android.os.PowerManager.GoToSleepReason;
 import android.os.PowerManager.WakeReason;
 import android.util.proto.ProtoOutputStream;
-import android.view.IWindowManager;
 import android.view.KeyEvent;
 import android.view.WindowManager;
 import android.view.animation.Animation;
@@ -50,8 +49,7 @@
     }
 
     @Override
-    public void init(Context context, IWindowManager windowManager,
-            WindowManagerFuncs windowManagerFuncs) {
+    public void init(Context context, WindowManagerFuncs windowManagerFuncs) {
     }
 
     public void setDefaultDisplay(DisplayContentInfo displayContentInfo) {
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 6c1c086..ab72a0f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -85,9 +85,14 @@
 @Presubmit
 @RunWith(WindowTestRunner.class)
 public class TransitionTests extends WindowTestsBase {
+    final SurfaceControl.Transaction mMockT = mock(SurfaceControl.Transaction.class);
 
     private Transition createTestTransition(int transitType) {
-        TransitionController controller = mock(TransitionController.class);
+        TransitionTracer tracer = mock(TransitionTracer.class);
+        final TransitionController controller = new TransitionController(
+                mock(ActivityTaskManagerService.class), mock(TaskSnapshotController.class),
+                mock(TransitionTracer.class));
+
         final BLASTSyncEngine sync = createTestBLASTSyncEngine();
         final Transition t = new Transition(transitType, 0 /* flags */, controller, sync);
         t.startCollecting(0 /* timeoutMs */);
@@ -121,7 +126,8 @@
         participants.add(oldTask);
         participants.add(newTask);
         ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
-        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
+                mMockT);
         assertEquals(2, info.getChanges().size());
         assertEquals(transit, info.getType());
 
@@ -129,7 +135,7 @@
         participants.add(opening);
         participants.add(closing);
         targets = Transition.calculateTargets(participants, changes);
-        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
         assertEquals(2, info.getChanges().size());
         assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
         assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
@@ -137,7 +143,7 @@
         // Check combined prune and promote
         participants.remove(newTask);
         targets = Transition.calculateTargets(participants, changes);
-        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
         assertEquals(2, info.getChanges().size());
         assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
         assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
@@ -145,7 +151,7 @@
         // Check multi promote
         participants.remove(oldTask);
         targets = Transition.calculateTargets(participants, changes);
-        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
         assertEquals(2, info.getChanges().size());
         assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
         assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
@@ -186,7 +192,8 @@
         participants.add(opening);
         participants.add(opening2);
         ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
-        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
+                mMockT);
         assertEquals(2, info.getChanges().size());
         assertEquals(transit, info.getType());
         assertNotNull(info.getChange(newTask.mRemoteToken.toWindowContainerToken()));
@@ -195,7 +202,7 @@
         // Check that unchanging but visible descendant of sibling prevents promotion
         participants.remove(opening2);
         targets = Transition.calculateTargets(participants, changes);
-        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
         assertEquals(2, info.getChanges().size());
         assertNotNull(info.getChange(newNestedTask.mRemoteToken.toWindowContainerToken()));
         assertNotNull(info.getChange(oldTask.mRemoteToken.toWindowContainerToken()));
@@ -232,7 +239,8 @@
         participants.add(showing);
         participants.add(showing2);
         ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
-        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
+                mMockT);
         assertEquals(1, info.getChanges().size());
         assertEquals(transit, info.getType());
         assertNotNull(info.getChange(tda.mRemoteToken.toWindowContainerToken()));
@@ -240,14 +248,14 @@
         // Check that organized tasks get reported even if not top
         makeTaskOrganized(showTask);
         targets = Transition.calculateTargets(participants, changes);
-        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
         assertEquals(2, info.getChanges().size());
         assertNotNull(info.getChange(tda.mRemoteToken.toWindowContainerToken()));
         assertNotNull(info.getChange(showTask.mRemoteToken.toWindowContainerToken()));
         // Even if DisplayArea explicitly participating
         participants.add(tda);
         targets = Transition.calculateTargets(participants, changes);
-        info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        info = Transition.calculateTransitionInfo(transit, flags, targets, changes, mMockT);
         assertEquals(2, info.getChanges().size());
     }
 
@@ -271,7 +279,7 @@
         ArrayList<WindowContainer> targets = Transition.calculateTargets(
                 transition.mParticipants, transition.mChanges);
         TransitionInfo info = Transition.calculateTransitionInfo(
-                0, 0, targets, transition.mChanges);
+                0, 0, targets, transition.mChanges, mMockT);
         assertEquals(2, info.getChanges().size());
         // There was an existence change on open, so it should be OPEN rather than SHOW
         assertEquals(TRANSIT_OPEN,
@@ -308,7 +316,7 @@
         ArrayList<WindowContainer> targets = Transition.calculateTargets(
                 transition.mParticipants, transition.mChanges);
         TransitionInfo info = Transition.calculateTransitionInfo(
-                0, 0, targets, transition.mChanges);
+                0, 0, targets, transition.mChanges, mMockT);
         assertEquals(taskCount, info.getChanges().size());
         // verify order is top-to-bottem
         for (int i = 0; i < taskCount; ++i) {
@@ -358,7 +366,7 @@
         ArrayList<WindowContainer> targets = Transition.calculateTargets(
                 transition.mParticipants, transition.mChanges);
         TransitionInfo info = Transition.calculateTransitionInfo(
-                0, 0, targets, transition.mChanges);
+                0, 0, targets, transition.mChanges, mMockT);
         // verify that wallpaper is at bottom
         assertEquals(taskCount + 1, info.getChanges().size());
         // The wallpaper is not organized, so it won't have a token; however, it will be marked
@@ -392,7 +400,7 @@
         ArrayList<WindowContainer> targets = Transition.calculateTargets(
                 transition.mParticipants, transition.mChanges);
         TransitionInfo info = Transition.calculateTransitionInfo(
-                0, 0, targets, transition.mChanges);
+                0, 0, targets, transition.mChanges, mMockT);
         // The wallpaper is not organized, so it won't have a token; however, it will be marked
         // as IS_WALLPAPER
         assertEquals(FLAG_IS_WALLPAPER, info.getChanges().get(0).getFlags());
@@ -474,7 +482,8 @@
         participants.add(changeTask);
         final ArrayList<WindowContainer> targets =
                 Transition.calculateTargets(participants, changes);
-        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
+                mMockT);
         // Root changes should always be considered independent
         assertTrue(isIndependent(
                 info.getChange(openTask.mRemoteToken.toWindowContainerToken()), info));
@@ -526,7 +535,8 @@
         participants.add(oldTask);
         participants.add(newTask);
         ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
-        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
+                mMockT);
         assertEquals(2, info.getChanges().size());
         assertEquals(transit, info.getType());
 
@@ -566,7 +576,8 @@
         participants.add(oldTask);
         participants.add(newTask);
         ArrayList<WindowContainer> targets = Transition.calculateTargets(participants, changes);
-        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes);
+        TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, changes,
+                mMockT);
         assertEquals(2, info.getChanges().size());
         assertEquals(transit, info.getType());
 
@@ -577,7 +588,7 @@
     @Test
     public void testTimeout() {
         final TransitionController controller = new TransitionController(mAtm,
-                mock(TaskSnapshotController.class));
+                mock(TaskSnapshotController.class), mock(TransitionTracer.class));
         final BLASTSyncEngine sync = new BLASTSyncEngine(mWm);
         final CountDownLatch latch = new CountDownLatch(1);
         // When the timeout is reached, it will finish the sync-group and notify transaction ready.
@@ -608,7 +619,7 @@
             final int flags = 0;
             final TransitionInfo info = Transition.calculateTransitionInfo(transition.mType, flags,
                     Transition.calculateTargets(transition.mParticipants, transition.mChanges),
-                    transition.mChanges);
+                    transition.mChanges, mMockT);
             transition.abort();
             return info.getChanges().get(0);
         };
@@ -654,6 +665,11 @@
         mDisplayContent.setLastHasContent();
         mDisplayContent.requestChangeTransitionIfNeeded(1 /* any changes */,
                 null /* displayChange */);
+        assertEquals(WindowContainer.SYNC_STATE_NONE, statusBar.mSyncState);
+        assertEquals(WindowContainer.SYNC_STATE_NONE, navBar.mSyncState);
+        assertEquals(WindowContainer.SYNC_STATE_NONE, screenDecor.mSyncState);
+        assertEquals(WindowContainer.SYNC_STATE_WAITING_FOR_DRAW, ime.mSyncState);
+
         final AsyncRotationController asyncRotationController =
                 mDisplayContent.getAsyncRotationController();
         assertNotNull(asyncRotationController);
@@ -767,7 +783,7 @@
 
         player.start();
         player.finish();
-        app.getTask().clearSyncState();
+        app.getTask().finishSync(mWm.mTransactionFactory.get(), false /* cancel */);
 
         // The open transition is finished. Continue to play seamless display change transition,
         // so the previous async rotation controller should still exist.
@@ -777,6 +793,10 @@
         assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp());
         assertNotNull(mDisplayContent.getAsyncRotationController());
 
+        // The app is still in transition, so the callback should be no-op.
+        mDisplayContent.mTransitionController.dispatchLegacyAppTransitionFinished(app);
+        assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp());
+
         statusBar.setOrientationChanging(true);
         player.startTransition();
         // Non-app windows should not be collected.
@@ -814,8 +834,11 @@
         player.onTransactionReady(mDisplayContent.getSyncTransaction());
 
         final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
+        final RemoteDisplayChangeController displayChangeController = mDisplayContent
+                .mRemoteDisplayChangeController;
         spyOn(displayRotation);
-        doReturn(true).when(displayRotation).isWaitingForRemoteRotation();
+        spyOn(displayChangeController);
+        doReturn(true).when(displayChangeController).isWaitingForRemoteDisplayChange();
         doReturn(prevRotation + 1).when(displayRotation).rotationForOrientation(
                 anyInt() /* orientation */, anyInt() /* lastRotation */);
         // Rotation update is skipped while the recents animation is running.
@@ -831,7 +854,8 @@
     @Test
     public void testIntermediateVisibility() {
         final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
-        final TransitionController controller = new TransitionController(mAtm, snapshotController);
+        final TransitionController controller = new TransitionController(mAtm, snapshotController,
+                mock(TransitionTracer.class));
         final ITransitionPlayer player = new ITransitionPlayer.Default();
         controller.registerTransitionPlayer(player, null /* appThread */);
         final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
@@ -895,7 +919,8 @@
     @Test
     public void testTransientLaunch() {
         final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
-        final TransitionController controller = new TransitionController(mAtm, snapshotController);
+        final TransitionController controller = new TransitionController(mAtm, snapshotController,
+                mock(TransitionTracer.class));
         final ITransitionPlayer player = new ITransitionPlayer.Default();
         controller.registerTransitionPlayer(player, null /* appThread */);
         final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
@@ -955,6 +980,30 @@
         verify(snapshotController, times(1)).recordTaskSnapshot(eq(task1), eq(false));
     }
 
+    @Test
+    public void testNotReadyPushPop() {
+        final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
+        final TransitionController controller = new TransitionController(mAtm, snapshotController,
+                mock(TransitionTracer.class));
+        final ITransitionPlayer player = new ITransitionPlayer.Default();
+        controller.registerTransitionPlayer(player, null /* appThread */);
+        final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
+
+        // Start out with task2 visible and set up a transition that closes task2 and opens task1
+        final Task task1 = createTask(mDisplayContent);
+        openTransition.collectExistenceChange(task1);
+
+        assertFalse(openTransition.allReady());
+
+        openTransition.setAllReady();
+
+        openTransition.deferTransitionReady();
+        assertFalse(openTransition.allReady());
+
+        openTransition.continueTransitionReady();
+        assertTrue(openTransition.allReady());
+    }
+
     private static void makeTaskOrganized(Task... tasks) {
         final ITaskOrganizer organizer = mock(ITaskOrganizer.class);
         for (Task t : tasks) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 1f68608..9963827 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -35,6 +35,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
@@ -82,10 +83,7 @@
         assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
 
         // No wallpaper WSA Surface
-        WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
-                true, dc, true /* ownerCanManageAppTokens */);
-        WindowState wallpaperWindow = createWindow(null /* parent */, TYPE_WALLPAPER,
-                wallpaperWindowToken, "wallpaperWindow");
+        final WindowState wallpaperWindow = createWallpaperWindow(dc);
         assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
 
         // Wallpaper with not visible WSA surface.
@@ -107,13 +105,10 @@
     @Test
     public void testWallpaperSizeWithFixedTransform() {
         // No wallpaper
-        final DisplayContent dc = createNewDisplay();
+        final DisplayContent dc = mDisplayContent;
 
         // No wallpaper WSA Surface
-        WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
-                true, dc, true /* ownerCanManageAppTokens */);
-        WindowState wallpaperWindow = createWindow(null /* parent */, TYPE_WALLPAPER,
-                wallpaperWindowToken, "wallpaperWindow");
+        final WindowState wallpaperWindow = createWallpaperWindow(dc);
 
         WindowManager.LayoutParams attrs = wallpaperWindow.getAttrs();
         Rect bounds = dc.getBounds();
@@ -153,7 +148,7 @@
         final WmDisplayCutout cutout = dc.calculateDisplayCutoutForRotation(Surface.ROTATION_0);
         final DisplayFrames displayFrames = new DisplayFrames(dc.getDisplayId(), new InsetsState(),
                 info, cutout, RoundedCorners.NO_ROUNDED_CORNERS, new PrivacyIndicatorBounds());
-        wallpaperWindowToken.applyFixedRotationTransform(info, displayFrames, config);
+        wallpaperWindow.mToken.applyFixedRotationTransform(info, displayFrames, config);
 
         // Check that the wallpaper has the same frame in landscape than in portrait
         assertEquals(Configuration.ORIENTATION_LANDSCAPE, dc.getConfiguration().orientation);
@@ -163,10 +158,7 @@
     @Test
     public void testWallpaperZoom() throws RemoteException {
         final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
-        final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
-                mock(IBinder.class), true,  dc, true /* ownerCanManageAppTokens */);
-        final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
-                "wallpaperWindow");
+        final WindowState wallpaperWindow = createWallpaperWindow(dc);
         wallpaperWindow.getAttrs().privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
 
@@ -189,10 +181,7 @@
     @Test
     public void testWallpaperZoom_shouldNotScaleWallpaper() throws RemoteException {
         final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
-        final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
-                mock(IBinder.class), true,  dc, true /* ownerCanManageAppTokens */);
-        final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
-                "wallpaperWindow");
+        final WindowState wallpaperWindow = createWallpaperWindow(dc);
         wallpaperWindow.getAttrs().privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
 
@@ -219,11 +208,7 @@
     @Test
     public void testWallpaperZoom_multipleCallers() {
         final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
-        final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
-                mock(IBinder.class), true,  dc,
-                true /* ownerCanManageAppTokens */);
-        final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
-                "wallpaperWindow");
+        final WindowState wallpaperWindow = createWallpaperWindow(dc);
         wallpaperWindow.getAttrs().privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS;
 
@@ -278,37 +263,51 @@
         assertEquals(WINDOWING_MODE_FULLSCREEN, token.getWindowingMode());
     }
 
-    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testFixedRotationRecentsAnimatingTask() {
+        final WindowState wallpaperWindow = createWallpaperWindow(mDisplayContent);
+        final WallpaperWindowToken wallpaperToken = wallpaperWindow.mToken.asWallpaperToken();
+        final WindowState appWin = createWindow(null, TYPE_BASE_APPLICATION, "app");
+        makeWindowVisible(appWin);
+        final ActivityRecord r = appWin.mActivityRecord;
         final RecentsAnimationController recentsController = mock(RecentsAnimationController.class);
-        doReturn(true).when(recentsController).isWallpaperVisible(eq(mAppWindow));
+        doReturn(true).when(recentsController).isWallpaperVisible(eq(appWin));
         mWm.setRecentsAnimationController(recentsController);
 
-        mAppWindow.mActivityRecord.applyFixedRotationTransform(mDisplayContent.getDisplayInfo(),
+        r.applyFixedRotationTransform(mDisplayContent.getDisplayInfo(),
                 mDisplayContent.mDisplayFrames, mDisplayContent.getConfiguration());
-        mAppWindow.mActivityRecord.mVisibleRequested = true;
-        mDisplayContent.mWallpaperController.adjustWallpaperWindows();
-
-        assertEquals(mAppWindow, mDisplayContent.mWallpaperController.getWallpaperTarget());
-        // Wallpaper should link the transform of its target.
-        assertTrue(mAppWindow.mActivityRecord.hasFixedRotationTransform());
-
-        mAppWindow.mActivityRecord.finishFixedRotationTransform();
         // Invisible requested activity should not share its rotation transform.
-        mAppWindow.mActivityRecord.mVisibleRequested = false;
+        r.mVisibleRequested = false;
         mDisplayContent.mWallpaperController.adjustWallpaperWindows();
+        assertFalse(wallpaperToken.hasFixedRotationTransform());
 
-        assertFalse(mAppWindow.mActivityRecord.hasFixedRotationTransform());
+        // Wallpaper should link the transform of its target.
+        r.mVisibleRequested = true;
+        mDisplayContent.mWallpaperController.adjustWallpaperWindows();
+        assertEquals(appWin, mDisplayContent.mWallpaperController.getWallpaperTarget());
+        assertTrue(r.hasFixedRotationTransform());
+        assertTrue(wallpaperToken.hasFixedRotationTransform());
+
+        // The case with shell transition.
+        registerTestTransitionPlayer();
+        final Transition t = r.mTransitionController.createTransition(TRANSIT_OPEN);
+        final ActivityRecord recents = mock(ActivityRecord.class);
+        t.collect(r.getTask());
+        r.mTransitionController.setTransientLaunch(recents, r.getTask());
+        // The activity in restore-below task should not be the target if keyguard is not locked.
+        mDisplayContent.mWallpaperController.adjustWallpaperWindows();
+        assertNotEquals(appWin, mDisplayContent.mWallpaperController.getWallpaperTarget());
+        // The activity in restore-below task should be the target if keyguard is occluded.
+        doReturn(true).when(mDisplayContent).isKeyguardLocked();
+        mDisplayContent.mWallpaperController.adjustWallpaperWindows();
+        assertEquals(appWin, mDisplayContent.mWallpaperController.getWallpaperTarget());
     }
 
     @Test
     public void testWallpaperTokenVisibility() {
         final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
-        final WallpaperWindowToken token = new WallpaperWindowToken(mWm, mock(IBinder.class),
-                true, dc, true /* ownerCanManageAppTokens */);
-        final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, token,
-                "wallpaperWindow");
+        final WindowState wallpaperWindow = createWallpaperWindow(dc);
+        final WallpaperWindowToken token = wallpaperWindow.mToken.asWallpaperToken();
         wallpaperWindow.setHasSurface(true);
 
         // Set-up mock shell transitions
@@ -350,6 +349,13 @@
         assertTrue(token.isVisible());
     }
 
+    private WindowState createWallpaperWindow(DisplayContent dc) {
+        final WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
+                true /* explicit */, dc, true /* ownerCanManageAppTokens */);
+        return createWindow(null /* parent */, TYPE_WALLPAPER, wallpaperWindowToken,
+                "wallpaperWindow");
+    }
+
     private WindowState createWallpaperTargetWindow(DisplayContent dc) {
         final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService)
                 .setTask(dc.getDefaultTaskDisplayArea().getRootHomeTask())
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
index ea18e58..739e783 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
@@ -72,7 +72,7 @@
     private static final Insets WATERFALL_INSETS = Insets.of(6, 0, 12, 0);
 
     private final WindowLayout mWindowLayout = new WindowLayout();
-    private final ClientWindowFrames mOutFrames = new ClientWindowFrames();
+    private final ClientWindowFrames mFrames = new ClientWindowFrames();
 
     private WindowManager.LayoutParams mAttrs;
     private InsetsState mState;
@@ -82,7 +82,6 @@
     private int mRequestedWidth;
     private int mRequestedHeight;
     private InsetsVisibilities mRequestedVisibilities;
-    private Rect mAttachedWindowFrame;
     private float mCompatScale;
 
     @Before
@@ -100,14 +99,14 @@
         mRequestedWidth = DISPLAY_WIDTH;
         mRequestedHeight = DISPLAY_HEIGHT;
         mRequestedVisibilities = new InsetsVisibilities();
-        mAttachedWindowFrame = null;
         mCompatScale = 1f;
+        mFrames.attachedFrame = null;
     }
 
     private void computeFrames() {
         mWindowLayout.computeFrames(mAttrs, mState, mDisplayCutoutSafe, mWindowBounds,
                 mWindowingMode, mRequestedWidth, mRequestedHeight, mRequestedVisibilities,
-                mAttachedWindowFrame, mCompatScale, mOutFrames);
+                mCompatScale, mFrames);
     }
 
     private void addDisplayCutout() {
@@ -145,9 +144,9 @@
     public void defaultParams() {
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.frame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.frame);
     }
 
     @Test
@@ -156,9 +155,9 @@
         mRequestedHeight = UNSPECIFIED_LENGTH;
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.frame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.frame);
     }
 
     @Test
@@ -172,9 +171,9 @@
         mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
-        assertRect(0, STATUS_BAR_HEIGHT, width, STATUS_BAR_HEIGHT + height, mOutFrames.frame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.parentFrame);
+        assertRect(0, STATUS_BAR_HEIGHT, width, STATUS_BAR_HEIGHT + height, mFrames.frame);
     }
 
     @Test
@@ -186,11 +185,24 @@
         computeFrames();
 
         assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
-                mOutFrames.displayFrame);
+                mFrames.displayFrame);
         assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
-                mOutFrames.parentFrame);
+                mFrames.parentFrame);
         assertRect(0, top, DISPLAY_WIDTH, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT,
-                mOutFrames.frame);
+                mFrames.frame);
+    }
+
+    @Test
+    public void attachedFrame() {
+        final int bottom = (DISPLAY_HEIGHT - STATUS_BAR_HEIGHT - NAVIGATION_BAR_HEIGHT) / 2;
+        mFrames.attachedFrame = new Rect(0, STATUS_BAR_HEIGHT, DISPLAY_WIDTH, bottom);
+        mRequestedWidth = UNSPECIFIED_LENGTH;
+        mRequestedHeight = UNSPECIFIED_LENGTH;
+        computeFrames();
+
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.displayFrame);
+        assertEquals(mFrames.attachedFrame, mFrames.parentFrame);
+        assertEquals(mFrames.attachedFrame, mFrames.frame);
     }
 
     @Test
@@ -198,9 +210,9 @@
         mAttrs.setFitInsetsTypes(WindowInsets.Type.statusBars());
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.displayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.parentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.frame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mFrames.frame);
     }
 
     @Test
@@ -208,9 +220,9 @@
         mAttrs.setFitInsetsTypes(WindowInsets.Type.navigationBars());
         computeFrames();
 
-        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
-        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
-        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mOutFrames.frame);
+        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mFrames.displayFrame);
+        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mFrames.parentFrame);
+        assertInsetByTopBottom(0, NAVIGATION_BAR_HEIGHT, mFrames.frame);
     }
 
     @Test
@@ -218,9 +230,9 @@
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetByTopBottom(0, 0, mOutFrames.displayFrame);
-        assertInsetByTopBottom(0, 0, mOutFrames.parentFrame);
-        assertInsetByTopBottom(0, 0, mOutFrames.frame);
+        assertInsetByTopBottom(0, 0, mFrames.displayFrame);
+        assertInsetByTopBottom(0, 0, mFrames.parentFrame);
+        assertInsetByTopBottom(0, 0, mFrames.frame);
     }
 
     @Test
@@ -228,9 +240,9 @@
         mAttrs.setFitInsetsSides(WindowInsets.Side.all());
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.frame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.frame);
     }
 
     @Test
@@ -238,9 +250,9 @@
         mAttrs.setFitInsetsSides(WindowInsets.Side.TOP);
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.displayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.parentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mOutFrames.frame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, 0, mFrames.frame);
     }
 
     @Test
@@ -248,9 +260,9 @@
         mAttrs.setFitInsetsSides(0);
         computeFrames();
 
-        assertInsetByTopBottom(0, 0, mOutFrames.displayFrame);
-        assertInsetByTopBottom(0, 0, mOutFrames.parentFrame);
-        assertInsetByTopBottom(0, 0, mOutFrames.frame);
+        assertInsetByTopBottom(0, 0, mFrames.displayFrame);
+        assertInsetByTopBottom(0, 0, mFrames.parentFrame);
+        assertInsetByTopBottom(0, 0, mFrames.frame);
     }
 
     @Test
@@ -259,9 +271,9 @@
         mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(false);
         computeFrames();
 
-        assertInsetByTopBottom(0, 0, mOutFrames.displayFrame);
-        assertInsetByTopBottom(0, 0, mOutFrames.parentFrame);
-        assertInsetByTopBottom(0, 0, mOutFrames.frame);
+        assertInsetByTopBottom(0, 0, mFrames.displayFrame);
+        assertInsetByTopBottom(0, 0, mFrames.parentFrame);
+        assertInsetByTopBottom(0, 0, mFrames.frame);
     }
 
     @Test
@@ -271,9 +283,9 @@
         mAttrs.setFitInsetsIgnoringVisibility(true);
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.parentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.frame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.frame);
     }
 
     @Test
@@ -284,9 +296,9 @@
         mAttrs.privateFlags |= PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
         computeFrames();
 
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mOutFrames.displayFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, IME_HEIGHT, mOutFrames.parentFrame);
-        assertInsetByTopBottom(STATUS_BAR_HEIGHT, IME_HEIGHT, mOutFrames.frame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, NAVIGATION_BAR_HEIGHT, mFrames.displayFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, IME_HEIGHT, mFrames.parentFrame);
+        assertInsetByTopBottom(STATUS_BAR_HEIGHT, IME_HEIGHT, mFrames.frame);
     }
 
     @Test
@@ -297,11 +309,11 @@
         computeFrames();
 
         assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.displayFrame);
+                mFrames.displayFrame);
         assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.parentFrame);
+                mFrames.parentFrame);
         assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.frame);
+                mFrames.frame);
     }
 
     @Test
@@ -312,11 +324,11 @@
         computeFrames();
 
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.displayFrame);
+                mFrames.displayFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.parentFrame);
+                mFrames.parentFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.frame);
+                mFrames.frame);
     }
 
     @Test
@@ -327,9 +339,9 @@
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.displayFrame);
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.parentFrame);
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.frame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mFrames.displayFrame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mFrames.parentFrame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mFrames.frame);
     }
 
     @Test
@@ -344,9 +356,9 @@
         mAttrs.privateFlags |= PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
         computeFrames();
 
-        assertRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, mOutFrames.displayFrame);
-        assertRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, mOutFrames.parentFrame);
-        assertRect(0, 0, DISPLAY_WIDTH, height + DISPLAY_CUTOUT_HEIGHT, mOutFrames.frame);
+        assertRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, mFrames.displayFrame);
+        assertRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, mFrames.parentFrame);
+        assertRect(0, 0, DISPLAY_WIDTH, height + DISPLAY_CUTOUT_HEIGHT, mFrames.frame);
     }
 
     @Test
@@ -359,11 +371,11 @@
         computeFrames();
 
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.displayFrame);
+                mFrames.displayFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.parentFrame);
+                mFrames.parentFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.frame);
+                mFrames.frame);
     }
 
     @Test
@@ -373,9 +385,9 @@
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.displayFrame);
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.parentFrame);
-        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mOutFrames.frame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mFrames.displayFrame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mFrames.parentFrame);
+        assertInsetBy(WATERFALL_INSETS.left, 0, WATERFALL_INSETS.right, 0, mFrames.frame);
     }
 
     @Test
@@ -386,11 +398,11 @@
         computeFrames();
 
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.displayFrame);
+                mFrames.displayFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.parentFrame);
+                mFrames.parentFrame);
         assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
-                mOutFrames.frame);
+                mFrames.frame);
     }
 
     @Test
@@ -400,8 +412,8 @@
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetByTopBottom(0, 0, mOutFrames.displayFrame);
-        assertInsetByTopBottom(0, 0, mOutFrames.parentFrame);
-        assertInsetByTopBottom(0, 0, mOutFrames.frame);
+        assertInsetByTopBottom(0, 0, mFrames.displayFrame);
+        assertInsetByTopBottom(0, 0, mFrames.parentFrame);
+        assertInsetByTopBottom(0, 0, mFrames.frame);
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index a0c20c2..1a64f5e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -49,6 +49,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.pm.PackageManager;
+import android.graphics.Rect;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -60,6 +61,7 @@
 import android.view.InsetsVisibilities;
 import android.view.View;
 import android.view.WindowManager;
+import android.window.WindowContainerToken;
 
 import androidx.test.filters.SmallTest;
 
@@ -281,7 +283,7 @@
 
         mWm.addWindow(session, new TestIWindow(), params, View.VISIBLE, DEFAULT_DISPLAY,
                 UserHandle.USER_SYSTEM, new InsetsVisibilities(), null, new InsetsState(),
-                new InsetsSourceControl[0]);
+                new InsetsSourceControl[0], new Rect());
 
         verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(any(),
                 any(), anyInt(), anyInt(), any());
@@ -316,4 +318,76 @@
         verify(mWm.mInputManager).setInTouchMode(
                 !currentTouchMode, callingPid, callingUid, /* hasPermission= */ false);
     }
+
+    @Test
+    public void testGetTaskWindowContainerTokenForLaunchCookie_nullCookie() {
+        WindowContainerToken wct = mWm.getTaskWindowContainerTokenForLaunchCookie(null);
+        assertThat(wct).isNull();
+    }
+
+    @Test
+    public void testGetTaskWindowContainerTokenForLaunchCookie_invalidCookie() {
+        Binder cookie = new Binder("test cookie");
+        WindowContainerToken wct = mWm.getTaskWindowContainerTokenForLaunchCookie(cookie);
+        assertThat(wct).isNull();
+
+        final ActivityRecord testActivity = new ActivityBuilder(mAtm)
+                .setCreateTask(true)
+                .build();
+
+        wct = mWm.getTaskWindowContainerTokenForLaunchCookie(cookie);
+        assertThat(wct).isNull();
+    }
+
+    @Test
+    public void testGetTaskWindowContainerTokenForLaunchCookie_validCookie() {
+        final Binder cookie = new Binder("ginger cookie");
+        final WindowContainerToken launchRootTask = mock(WindowContainerToken.class);
+        setupActivityWithLaunchCookie(cookie, launchRootTask);
+
+        WindowContainerToken wct = mWm.getTaskWindowContainerTokenForLaunchCookie(cookie);
+        assertThat(wct).isEqualTo(launchRootTask);
+    }
+
+    @Test
+    public void testGetTaskWindowContainerTokenForLaunchCookie_multipleCookies() {
+        final Binder cookie1 = new Binder("ginger cookie");
+        final WindowContainerToken launchRootTask1 = mock(WindowContainerToken.class);
+        setupActivityWithLaunchCookie(cookie1, launchRootTask1);
+
+        setupActivityWithLaunchCookie(new Binder("choc chip cookie"),
+                mock(WindowContainerToken.class));
+
+        setupActivityWithLaunchCookie(new Binder("peanut butter cookie"),
+                mock(WindowContainerToken.class));
+
+        WindowContainerToken wct = mWm.getTaskWindowContainerTokenForLaunchCookie(cookie1);
+        assertThat(wct).isEqualTo(launchRootTask1);
+    }
+
+    @Test
+    public void testGetTaskWindowContainerTokenForLaunchCookie_multipleCookies_noneValid() {
+        setupActivityWithLaunchCookie(new Binder("ginger cookie"),
+                mock(WindowContainerToken.class));
+
+        setupActivityWithLaunchCookie(new Binder("choc chip cookie"),
+                mock(WindowContainerToken.class));
+
+        setupActivityWithLaunchCookie(new Binder("peanut butter cookie"),
+                mock(WindowContainerToken.class));
+
+        WindowContainerToken wct = mWm.getTaskWindowContainerTokenForLaunchCookie(
+                new Binder("some other cookie"));
+        assertThat(wct).isNull();
+    }
+
+    private void setupActivityWithLaunchCookie(IBinder launchCookie, WindowContainerToken wct) {
+        final WindowContainer.RemoteToken remoteToken = mock(WindowContainer.RemoteToken.class);
+        when(remoteToken.toWindowContainerToken()).thenReturn(wct);
+        final ActivityRecord testActivity = new ActivityBuilder(mAtm)
+                .setCreateTask(true)
+                .build();
+        testActivity.mLaunchCookie = launchCookie;
+        testActivity.getTask().mRemoteToken = remoteToken;
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 40ca250..08bad70 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -522,7 +522,10 @@
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
 
         assertEquals(WINDOWING_MODE_FULLSCREEN, record.getWindowingMode());
-        assertEquals(WINDOWING_MODE_PINNED, rootTask.getWindowingMode());
+        // Get the root task from the PIP activity record again, since the PIP root task may have
+        // changed when the activity entered PIP mode.
+        final Task pipRootTask = record.getRootTask();
+        assertEquals(WINDOWING_MODE_PINNED, pipRootTask.getWindowingMode());
     }
 
     @Test
@@ -687,7 +690,7 @@
         final RunningTaskInfo info2 = task2.getTaskInfo();
 
         WindowContainerTransaction wct = new WindowContainerTransaction();
-        wct.setAdjacentRoots(info1.token, info2.token, false /* moveTogether */);
+        wct.setAdjacentRoots(info1.token, info2.token);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
         assertEquals(task1.getAdjacentTaskFragment(), task2);
         assertEquals(task2.getAdjacentTaskFragment(), task1);
@@ -697,8 +700,8 @@
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
         assertEquals(dc.getDefaultTaskDisplayArea().mLaunchAdjacentFlagRootTask, task1);
 
-        task1.setAdjacentTaskFragment(null, false /* moveTogether */);
-        task2.setAdjacentTaskFragment(null, false /* moveTogether */);
+        task1.setAdjacentTaskFragment(null);
+        task2.setAdjacentTaskFragment(null);
         wct = new WindowContainerTransaction();
         wct.clearLaunchAdjacentFlagRoot(info1.token);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
@@ -1015,6 +1018,8 @@
         final ActivityRecord record = createActivityRecordWithParentTask(mDisplayContent,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         record.info.flags |= ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
+        record.setPictureInPictureParams(new PictureInPictureParams.Builder()
+                .setAutoEnterEnabled(true).build());
         spyOn(record);
         doReturn(true).when(record).checkEnterPictureInPictureState(any(), anyBoolean());
 
@@ -1499,7 +1504,11 @@
         verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
 
         clearInvocations(mWm.mAtmService.mRootWindowContainer);
-        t.setWindowingMode(wct, WINDOWING_MODE_FULLSCREEN);
+        // The token for the PIP root task may have changed when the task entered PIP mode, so do
+        // not reuse the one from above.
+        final WindowContainerToken newToken =
+                record.getRootTask().mRemoteToken.toWindowContainerToken();
+        t.setWindowingMode(newToken, WINDOWING_MODE_FULLSCREEN);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
         verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 746f2b5..3abf7ce 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -21,6 +21,7 @@
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
@@ -39,24 +40,30 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.when;
 
 import android.Manifest;
+import android.app.ActivityManager;
+import android.app.ClientTransactionHandler;
 import android.app.IApplicationThread;
+import android.app.servertransaction.ConfigurationChangeItem;
 import android.content.ComponentName;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.LocaleList;
+import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
 import org.mockito.Mockito;
 
@@ -282,6 +289,39 @@
     }
 
     @Test
+    public void testCachedStateConfigurationChange() throws RemoteException {
+        final ClientLifecycleManager clientManager = mAtm.getLifecycleManager();
+        doNothing().when(clientManager).scheduleTransaction(any(), any());
+        final IApplicationThread thread = mWpc.getThread();
+        final Configuration newConfig = new Configuration(mWpc.getConfiguration());
+        newConfig.densityDpi += 100;
+        // Non-cached state will send the change directly.
+        mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+        clearInvocations(clientManager);
+        mWpc.onConfigurationChanged(newConfig);
+        verify(clientManager).scheduleTransaction(eq(thread), any());
+
+        // Cached state won't send the change.
+        clearInvocations(clientManager);
+        mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY);
+        newConfig.densityDpi += 100;
+        mWpc.onConfigurationChanged(newConfig);
+        verify(clientManager, never()).scheduleTransaction(eq(thread), any());
+
+        // Cached -> non-cached will send the previous deferred config immediately.
+        mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_RECEIVER);
+        final ArgumentCaptor<ConfigurationChangeItem> captor =
+                ArgumentCaptor.forClass(ConfigurationChangeItem.class);
+        verify(clientManager).scheduleTransaction(eq(thread), captor.capture());
+        final ClientTransactionHandler client = mock(ClientTransactionHandler.class);
+        captor.getValue().preExecute(client, null /* token */);
+        final ArgumentCaptor<Configuration> configCaptor =
+                ArgumentCaptor.forClass(Configuration.class);
+        verify(client).updatePendingConfiguration(configCaptor.capture());
+        assertEquals(newConfig, configCaptor.getValue());
+    }
+
+    @Test
     public void testComputeOomAdjFromActivities() {
         final ActivityRecord activity = createActivityRecord(mWpc);
         activity.mVisibleRequested = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 20935f1..fb7400b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -712,6 +712,14 @@
         // Keyguard host window should be always contained. The drawn app or app with starting
         // window are unnecessary to draw.
         assertEquals(Arrays.asList(keyguardHostWindow, startingWindow), outWaitingForDrawn);
+
+        // No need to wait for a window of invisible activity even if the window has surface.
+        final WindowState invisibleApp = mAppWindow;
+        invisibleApp.mActivityRecord.mVisibleRequested = false;
+        invisibleApp.mActivityRecord.allDrawn = false;
+        outWaitingForDrawn.clear();
+        invisibleApp.requestDrawIfNeeded(outWaitingForDrawn);
+        assertTrue(outWaitingForDrawn.isEmpty());
     }
 
     @UseTestDisplay(addWindows = W_ABOVE_ACTIVITY)
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 20fbda4..8a539cd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -64,7 +64,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityOptions;
-import android.app.IApplicationThread;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -229,14 +228,28 @@
         // {@link com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio}, is set
         // on some device form factors.
         mAtm.mWindowManager.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(0);
-        // Ensure letterbox position multiplier is not overridden on any device target.
+        // Ensure letterbox horizontal position multiplier is not overridden on any device target.
         // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier},
         // may be set on some device form factors.
         mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f);
-        // Ensure letterbox reachability treatment isn't overridden on any device target.
-        // {@link com.android.internal.R.bool.config_letterboxIsReachabilityEnabled},
+        // Ensure letterbox vertical position multiplier is not overridden on any device target.
+        // {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier},
         // may be set on some device form factors.
-        mAtm.mWindowManager.mLetterboxConfiguration.setIsReachabilityEnabled(false);
+        mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f);
+        // Ensure letterbox horizontal reachability treatment isn't overridden on any device target.
+        // {@link com.android.internal.R.bool.config_letterboxIsHorizontalReachabilityEnabled},
+        // may be set on some device form factors.
+        mAtm.mWindowManager.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(false);
+        // Ensure letterbox vertical reachability treatment isn't overridden on any device target.
+        // {@link com.android.internal.R.bool.config_letterboxIsVerticalReachabilityEnabled},
+        // may be set on some device form factors.
+        mAtm.mWindowManager.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(false);
+        // Ensure aspect ratio for unresizable apps isn't overridden on any device target.
+        // {@link com.android.internal.R.bool
+        // .config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled}, may be set on some
+        // device form factors.
+        mAtm.mWindowManager.mLetterboxConfiguration
+                .setIsSplitScreenAspectRatioForUnresizableAppsEnabled(false);
 
         checkDeviceSpecificOverridesNotApplied();
     }
@@ -246,7 +259,11 @@
         // Revert back to device overrides.
         mAtm.mWindowManager.mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
         mAtm.mWindowManager.mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
-        mAtm.mWindowManager.mLetterboxConfiguration.resetIsReachabilityEnabled();
+        mAtm.mWindowManager.mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier();
+        mAtm.mWindowManager.mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled();
+        mAtm.mWindowManager.mLetterboxConfiguration.resetIsVerticalReachabilityEnabled();
+        mAtm.mWindowManager.mLetterboxConfiguration
+                .resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
     }
 
     /**
@@ -915,13 +932,15 @@
      */
     protected static class ActivityBuilder {
         static final int DEFAULT_FAKE_UID = 12345;
+        static final String DEFAULT_PROCESS_NAME = "procName";
+        static int sProcNameSeq;
 
         private final ActivityTaskManagerService mService;
 
         private ComponentName mComponent;
         private String mTargetActivity;
         private Task mTask;
-        private String mProcessName = "name";
+        private String mProcessName = DEFAULT_PROCESS_NAME;
         private String mAffinity;
         private int mUid = DEFAULT_FAKE_UID;
         private boolean mCreateTask = false;
@@ -1109,6 +1128,9 @@
             aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
             aInfo.applicationInfo.packageName = mComponent.getPackageName();
             aInfo.applicationInfo.uid = mUid;
+            if (DEFAULT_PROCESS_NAME.equals(mProcessName)) {
+                mProcessName += ++sProcNameSeq;
+            }
             aInfo.processName = mProcessName;
             aInfo.packageName = mComponent.getPackageName();
             aInfo.name = mComponent.getClassName();
@@ -1173,16 +1195,11 @@
             if (mWpc != null) {
                 wpc = mWpc;
             } else {
-                wpc = new WindowProcessController(mService,
-                        aInfo.applicationInfo, mProcessName, mUid,
-                        UserHandle.getUserId(mUid), mock(Object.class),
-                        mock(WindowProcessListener.class));
-                wpc.setThread(mock(IApplicationThread.class));
+                final WindowProcessController p = mService.getProcessController(mProcessName, mUid);
+                wpc = p != null ? p : SystemServicesTestRule.addProcess(
+                        mService, aInfo.applicationInfo, mProcessName, 0 /* pid */);
             }
-            wpc.setThread(mock(IApplicationThread.class));
             activity.setProcess(wpc);
-            doReturn(wpc).when(mService).getProcessController(
-                    activity.processName, activity.info.applicationInfo.uid);
 
             // Resume top activities to make sure all other signals in the system are connected.
             mService.mRootWindowContainer.resumeFocusedTasksTopActivities();
@@ -1550,7 +1567,7 @@
             mSecondary = mService.mTaskOrganizerController.createRootTask(
                     display, WINDOWING_MODE_MULTI_WINDOW, null);
 
-            mPrimary.setAdjacentTaskFragment(mSecondary, true);
+            mPrimary.setAdjacentTaskFragment(mSecondary);
             display.getDefaultTaskDisplayArea().setLaunchAdjacentFlagRootTask(mSecondary);
 
             final Rect primaryBounds = new Rect();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index 2df1d23..77fca45 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -328,7 +328,6 @@
         assertWindowHigher(mImeWindow, imeSystemOverlayTarget);
         assertWindowHigher(mImeWindow, mChildAppWindowAbove);
         assertWindowHigher(mImeWindow, mAppWindow);
-        assertWindowHigher(mImeWindow, mDockedDividerWindow);
 
         // The IME has a higher base layer than the status bar so we may expect it to go
         // above the status bar once they are both in the Non-App layer, as past versions of this
@@ -349,7 +348,6 @@
 
         assertWindowHigher(mImeWindow, mChildAppWindowAbove);
         assertWindowHigher(mImeWindow, mAppWindow);
-        assertWindowHigher(mImeWindow, mDockedDividerWindow);
         assertWindowHigher(mImeWindow, mStatusBarWindow);
 
         // And, IME dialogs should always have an higher layer than the IME.
@@ -489,77 +487,6 @@
     }
 
     @Test
-    public void testDockedDividerPosition() {
-        final Task pinnedTask =
-                createTask(mDisplayContent, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
-        final WindowState pinnedWindow =
-                createAppWindow(pinnedTask, ACTIVITY_TYPE_STANDARD, "pinnedWindow");
-
-        final Task belowTask =
-                createTask(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
-        final WindowState belowTaskWindow =
-                createAppWindow(belowTask, ACTIVITY_TYPE_STANDARD, "belowTaskWindow");
-
-        final Task splitScreenTask1 =
-                createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
-        final WindowState splitWindow1 =
-                createAppWindow(splitScreenTask1, ACTIVITY_TYPE_STANDARD, "splitWindow1");
-        final Task splitScreenTask2 =
-                createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
-        final WindowState splitWindow2 =
-                createAppWindow(splitScreenTask2, ACTIVITY_TYPE_STANDARD, "splitWindow2");
-        splitScreenTask1.setAdjacentTaskFragment(splitScreenTask2, true /* moveTogether */);
-        splitScreenTask2.setAdjacentTaskFragment(splitScreenTask1, true /* moveTogether */);
-
-        final Task aboveTask =
-                createTask(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
-        final WindowState aboveTaskWindow =
-                createAppWindow(aboveTask, ACTIVITY_TYPE_STANDARD, "aboveTaskWindow");
-
-        mDisplayContent.assignChildLayers(mTransaction);
-
-        assertWindowHigher(splitWindow1, belowTaskWindow);
-        assertWindowHigher(splitWindow2, belowTaskWindow);
-        assertWindowHigher(mDockedDividerWindow, splitWindow1);
-        assertWindowHigher(mDockedDividerWindow, splitWindow2);
-        assertWindowHigher(aboveTaskWindow, mDockedDividerWindow);
-        assertWindowHigher(pinnedWindow, aboveTaskWindow);
-    }
-
-
-    @Test
-    public void testDockedDividerPosition_noAboveTask() {
-        final Task pinnedTask =
-                createTask(mDisplayContent, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
-        final WindowState pinnedWindow =
-                createAppWindow(pinnedTask, ACTIVITY_TYPE_STANDARD, "pinnedWindow");
-
-        final Task belowTask =
-                createTask(mDisplayContent, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
-        final WindowState belowTaskWindow =
-                createAppWindow(belowTask, ACTIVITY_TYPE_STANDARD, "belowTaskWindow");
-
-        final Task splitScreenTask1 =
-                createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
-        final WindowState splitWindow1 =
-                createAppWindow(splitScreenTask1, ACTIVITY_TYPE_STANDARD, "splitWindow1");
-        final Task splitScreenTask2 =
-                createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
-        final WindowState splitWindow2 =
-                createAppWindow(splitScreenTask2, ACTIVITY_TYPE_STANDARD, "splitWindow2");
-        splitScreenTask1.setAdjacentTaskFragment(splitScreenTask2, true /* moveTogether */);
-        splitScreenTask2.setAdjacentTaskFragment(splitScreenTask1, true /* moveTogether */);
-
-        mDisplayContent.assignChildLayers(mTransaction);
-
-        assertWindowHigher(splitWindow1, belowTaskWindow);
-        assertWindowHigher(splitWindow2, belowTaskWindow);
-        assertWindowHigher(mDockedDividerWindow, splitWindow1);
-        assertWindowHigher(mDockedDividerWindow, splitWindow2);
-        assertWindowHigher(pinnedWindow, mDockedDividerWindow);
-    }
-
-    @Test
     public void testAttachNavBarWhenEnteringRecents_expectNavBarHigherThanIme() {
         // create RecentsAnimationController
         IRecentsAnimationRunner mockRunner = mock(IRecentsAnimationRunner.class);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index cc33f88..26a1e9d 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -16,6 +16,7 @@
 
 package com.android.server.usage;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.usage.TimeSparseArray;
 import android.app.usage.UsageEvents;
@@ -24,6 +25,7 @@
 import android.os.Build;
 import android.os.SystemProperties;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -55,8 +57,11 @@
 import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Provides an interface to query for UsageStat data from a Protocol Buffer database.
@@ -1252,6 +1257,10 @@
             Slog.wtf(TAG, "Attempting to backup UsageStats as XML with version " + version);
             return null;
         }
+        if (version < 1 || version > BACKUP_VERSION) {
+            Slog.wtf(TAG, "Attempting to backup UsageStats with an unknown version: " + version);
+            return null;
+        }
         synchronized (mLock) {
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
             if (KEY_USAGE_STATS.equals(key)) {
@@ -1300,14 +1309,26 @@
             }
             return baos.toByteArray();
         }
+    }
 
+    /**
+     * Updates the set of packages given to only include those that have been used within the
+     * given timeframe (as defined by {@link UsageStats#getLastTimePackageUsed()}).
+     */
+    private void calculatePackagesUsedWithinTimeframe(
+            IntervalStats stats, Set<String> packagesList, long timeframeMs) {
+        for (UsageStats stat : stats.packageStats.values()) {
+            if (stat.getLastTimePackageUsed() > timeframeMs) {
+                packagesList.add(stat.mPackageName);
+            }
+        }
     }
 
     /**
      * @hide
      */
     @VisibleForTesting
-    public void applyRestoredPayload(String key, byte[] payload) {
+    public @NonNull Set<String> applyRestoredPayload(String key, byte[] payload) {
         synchronized (mLock) {
             if (KEY_USAGE_STATS.equals(key)) {
                 // Read stats files for the current device configs
@@ -1320,12 +1341,15 @@
                 IntervalStats yearlyConfigSource =
                         getLatestUsageStats(UsageStatsManager.INTERVAL_YEARLY);
 
+                final Set<String> packagesRestored = new ArraySet<>();
                 try {
                     DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload));
                     int backupDataVersion = in.readInt();
 
                     // Can't handle this backup set
-                    if (backupDataVersion < 1 || backupDataVersion > BACKUP_VERSION) return;
+                    if (backupDataVersion < 1 || backupDataVersion > BACKUP_VERSION) {
+                        return packagesRestored;
+                    }
 
                     // Delete all stats files
                     // Do this after reading version and before actually restoring
@@ -1333,10 +1357,14 @@
                         deleteDirectoryContents(mIntervalDirs[i]);
                     }
 
+                    // 90 days before today in epoch
+                    final long timeframe = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(90);
                     int fileCount = in.readInt();
                     for (int i = 0; i < fileCount; i++) {
                         IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
                                 backupDataVersion);
+                        calculatePackagesUsedWithinTimeframe(stats, packagesRestored, timeframe);
+                        packagesRestored.addAll(stats.packageStats.keySet());
                         stats = mergeStats(stats, dailyConfigSource);
                         putUsageStats(UsageStatsManager.INTERVAL_DAILY, stats);
                     }
@@ -1345,6 +1373,7 @@
                     for (int i = 0; i < fileCount; i++) {
                         IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
                                 backupDataVersion);
+                        calculatePackagesUsedWithinTimeframe(stats, packagesRestored, timeframe);
                         stats = mergeStats(stats, weeklyConfigSource);
                         putUsageStats(UsageStatsManager.INTERVAL_WEEKLY, stats);
                     }
@@ -1353,6 +1382,7 @@
                     for (int i = 0; i < fileCount; i++) {
                         IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
                                 backupDataVersion);
+                        calculatePackagesUsedWithinTimeframe(stats, packagesRestored, timeframe);
                         stats = mergeStats(stats, monthlyConfigSource);
                         putUsageStats(UsageStatsManager.INTERVAL_MONTHLY, stats);
                     }
@@ -1361,6 +1391,7 @@
                     for (int i = 0; i < fileCount; i++) {
                         IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
                                 backupDataVersion);
+                        calculatePackagesUsedWithinTimeframe(stats, packagesRestored, timeframe);
                         stats = mergeStats(stats, yearlyConfigSource);
                         putUsageStats(UsageStatsManager.INTERVAL_YEARLY, stats);
                     }
@@ -1370,7 +1401,9 @@
                 } finally {
                     indexFilesLocked();
                 }
+                return packagesRestored;
             }
+            return Collections.EMPTY_SET;
         }
     }
 
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index ef13cd9..f595c3d 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -3034,7 +3034,8 @@
                     if (userStats == null) {
                         return; // user was stopped or removed
                     }
-                    userStats.applyRestoredPayload(key, payload);
+                    final Set<String> restoredApps = userStats.applyRestoredPayload(key, payload);
+                    mAppStandby.restoreAppsToRare(restoredApps, user);
                 }
             }
         }
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index c609add..34c6c16 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -63,6 +63,7 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Set;
 
 /**
  * A per-user UsageStatsService. All methods are meant to be called with the main lock held
@@ -1374,8 +1375,8 @@
         return mDatabase.getBackupPayload(key);
     }
 
-    void applyRestoredPayload(String key, byte[] payload){
+    Set<String> applyRestoredPayload(String key, byte[] payload) {
         checkAndGetTimeLocked();
-        mDatabase.applyRestoredPayload(key, payload);
+        return mDatabase.applyRestoredPayload(key, payload);
     }
 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 42d446d..25db81f 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -31,11 +31,18 @@
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_TIMEOUT;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__AUDIO_SERVICE_DIED;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__SCHEDULE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__APP_REQUEST_UPDATE_STATE;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_UPDATE_STATE_AFTER_TIMEOUT;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECTED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_REJECTED;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__ON_DISCONNECTED;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_UPDATE_STATE;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__START_EXTERNAL_SOURCE_DETECTION;
+import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__START_SOFTWARE_DETECTION;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED;
@@ -46,11 +53,9 @@
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED_FROM_RESTART;
 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECT_UNEXPECTED_CALLBACK;
-import static com.android.server.voiceinteraction.SoundTriggerSessionPermissionsDecorator.enforcePermissionForPreflight;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.AppOpsManager;
 import android.content.ComponentName;
 import android.content.ContentCaptureOptions;
 import android.content.Context;
@@ -148,6 +153,13 @@
     private static final int METRICS_KEYPHRASE_TRIGGERED_REJECT_UNEXPECTED_CALLBACK =
             HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECT_UNEXPECTED_CALLBACK;
 
+    private static final int METRICS_EXTERNAL_SOURCE_DETECTED =
+            HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECTED;
+    private static final int METRICS_EXTERNAL_SOURCE_REJECTED =
+            HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_REJECTED;
+    private static final int METRICS_EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION =
+            HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION;
+
     private final Executor mAudioCopyExecutor = Executors.newCachedThreadPool();
     // TODO: This may need to be a Handler(looper)
     private final ScheduledExecutorService mScheduledExecutorService =
@@ -384,6 +396,10 @@
     }
 
     void updateStateLocked(PersistableBundle options, SharedMemory sharedMemory) {
+        HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                HOTWORD_DETECTOR_EVENTS__EVENT__APP_REQUEST_UPDATE_STATE,
+                mVoiceInteractionServiceUid);
+
         // Prevent doing the init late, so restart is handled equally to a clean process start.
         // TODO(b/191742511): this logic needs a test
         if (!mUpdateStateAfterStartFinished.get()
@@ -424,14 +440,23 @@
                     Slog.d(TAG, "onDetected");
                 }
                 synchronized (mLock) {
+                    HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                            mDetectorType,
+                            HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED);
                     if (!mPerformingSoftwareHotwordDetection) {
                         Slog.i(TAG, "Hotword detection has already completed");
+                        HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                                mDetectorType,
+                                METRICS_KEYPHRASE_TRIGGERED_DETECT_UNEXPECTED_CALLBACK);
                         return;
                     }
                     mPerformingSoftwareHotwordDetection = false;
                     try {
                         enforcePermissionsForDataDelivery();
                     } catch (SecurityException e) {
+                        HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                                mDetectorType,
+                                METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION);
                         mSoftwareCallback.onError();
                         return;
                     }
@@ -451,6 +476,9 @@
                 if (DEBUG) {
                     Slog.wtf(TAG, "onRejected");
                 }
+                HotwordMetricsLogger.writeKeyphraseTriggerEvent(
+                        mDetectorType,
+                        HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED);
                 // onRejected isn't allowed here, and we are not expecting it.
             }
         };
@@ -462,6 +490,9 @@
                         null,
                         null,
                         internalCallback));
+        HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                HOTWORD_DETECTOR_EVENTS__EVENT__START_SOFTWARE_DETECTION,
+                mVoiceInteractionServiceUid);
     }
 
     public void startListeningFromExternalSource(
@@ -893,6 +924,9 @@
                                 @Override
                                 public void onRejected(HotwordRejectedResult result)
                                         throws RemoteException {
+                                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                                            METRICS_EXTERNAL_SOURCE_REJECTED,
+                                            mVoiceInteractionServiceUid);
                                     mScheduledExecutorService.schedule(
                                             () -> {
                                                 bestEffortClose(serviceAudioSink, audioSource);
@@ -914,6 +948,9 @@
                                 @Override
                                 public void onDetected(HotwordDetectedResult triggerResult)
                                         throws RemoteException {
+                                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                                            METRICS_EXTERNAL_SOURCE_DETECTED,
+                                            mVoiceInteractionServiceUid);
                                     mScheduledExecutorService.schedule(
                                             () -> {
                                                 bestEffortClose(serviceAudioSink, audioSource);
@@ -924,6 +961,9 @@
                                     try {
                                         enforcePermissionsForDataDelivery();
                                     } catch (SecurityException e) {
+                                        HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                                                METRICS_EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION,
+                                                mVoiceInteractionServiceUid);
                                         callback.onError();
                                         return;
                                     }
@@ -944,6 +984,9 @@
                     // A copy of this has been created and passed to the hotword validator
                     bestEffortClose(serviceAudioSource);
                 });
+        HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                HOTWORD_DETECTOR_EVENTS__EVENT__START_EXTERNAL_SOURCE_DETECTION,
+                mVoiceInteractionServiceUid);
     }
 
     private class ServiceConnectionFactory {
@@ -1004,7 +1047,12 @@
                     return;
                 }
                 mIsBound = connected;
-                if (connected && !mIsLoggedFirstConnect) {
+
+                if (!connected) {
+                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
+                            HOTWORD_DETECTOR_EVENTS__EVENT__ON_DISCONNECTED,
+                            mVoiceInteractionServiceUid);
+                } else if (!mIsLoggedFirstConnect) {
                     mIsLoggedFirstConnect = true;
                     HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
                             HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED,
@@ -1162,11 +1210,12 @@
     // TODO: Share this code with SoundTriggerMiddlewarePermission.
     private void enforcePermissionsForDataDelivery() {
         Binder.withCleanCallingIdentity(() -> {
-            enforcePermissionForPreflight(mContext, mVoiceInteractorIdentity, RECORD_AUDIO);
-            int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD);
-            mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp,
-                    mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
-                    mVoiceInteractorIdentity.attributionTag, OP_MESSAGE);
+            // Hack to make sure we show the mic privacy-indicator since the Trusted Hotword
+            // requirement isn't being enforced for now. Normally, we would note the HOTWORD op here
+            // instead.
+            enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
+                    RECORD_AUDIO, OP_MESSAGE);
+
             enforcePermissionForDataDelivery(mContext, mVoiceInteractorIdentity,
                     CAPTURE_AUDIO_HOTWORD, OP_MESSAGE);
         });
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 235ed84..3ed87e1 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1137,10 +1137,7 @@
             return false;
         }
         // DEFAULT can handle HIPRI.
-        if (hasApnType(type)) {
-            return true;
-        }
-        return false;
+        return hasApnType(type);
     }
 
     // Check whether the types of two APN same (even only one type of each APN is same).
@@ -2193,11 +2190,10 @@
             }
             if ((mApnTypeBitmask & TYPE_MMS) != 0 && !TextUtils.isEmpty(mMmsProxyAddress)
                     && mMmsProxyAddress.startsWith("http")) {
-                if (Build.IS_DEBUGGABLE) {
-                    throw new IllegalArgumentException("mms proxy(" +  mMmsProxyAddress
-                            + ") should be a hostname, not a url");
-                }
-                return null;
+                Log.wtf(LOG_TAG,"mms proxy(" + mMmsProxyAddress
+                        + ") should be a hostname, not a url");
+                Uri mMmsProxyAddressUri = Uri.parse(mMmsProxyAddress);
+                mMmsProxyAddress = mMmsProxyAddressUri.getHost();
             }
             return new ApnSetting(this);
         }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index 7f309e1..315c40f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -18,10 +18,13 @@
 package com.android.server.wm.flicker
 
 import com.android.server.wm.flicker.helpers.WindowUtils
+import com.android.server.wm.flicker.traces.region.RegionSubject
 import com.android.server.wm.traces.common.FlickerComponentName
 
-val LAUNCHER_COMPONENT = FlickerComponentName("com.google.android.apps.nexuslauncher",
-        "com.google.android.apps.nexuslauncher.NexusLauncherActivity")
+val LAUNCHER_COMPONENT = FlickerComponentName(
+    "com.google.android.apps.nexuslauncher",
+    "com.google.android.apps.nexuslauncher.NexusLauncherActivity"
+)
 
 /**
  * Checks that [FlickerComponentName.STATUS_BAR] window is visible and above the app windows in
@@ -109,9 +112,9 @@
 fun FlickerTestParameter.navBarLayerPositionStart() {
     assertLayersStart {
         val display = this.entry.displays.minByOrNull { it.id }
-                ?: throw RuntimeException("There is no display!")
+            ?: throw RuntimeException("There is no display!")
         this.visibleRegion(FlickerComponentName.NAV_BAR)
-                .coversExactly(WindowUtils.getNavigationBarPosition(display))
+            .coversExactly(WindowUtils.getNavigationBarPosition(display, isGesturalNavigation))
     }
 }
 
@@ -122,9 +125,9 @@
 fun FlickerTestParameter.navBarLayerPositionEnd() {
     assertLayersEnd {
         val display = this.entry.displays.minByOrNull { it.id }
-                ?: throw RuntimeException("There is no display!")
+            ?: throw RuntimeException("There is no display!")
         this.visibleRegion(FlickerComponentName.NAV_BAR)
-                .coversExactly(WindowUtils.getNavigationBarPosition(display))
+            .coversExactly(WindowUtils.getNavigationBarPosition(display, isGesturalNavigation))
     }
 }
 
@@ -173,6 +176,33 @@
 }
 
 /**
+ * Asserts that the visibleRegion of the [FlickerComponentName.SNAPSHOT] layer can cover
+ * the visibleRegion of the given app component exactly
+ */
+fun FlickerTestParameter.snapshotStartingWindowLayerCoversExactlyOnApp(
+        component: FlickerComponentName) {
+    assertLayers {
+        invoke("snapshotStartingWindowLayerCoversExactlyOnApp") {
+            val snapshotLayers = it.subjects.filter { subject ->
+                subject.name.contains(
+                        FlickerComponentName.SNAPSHOT.toLayerName()) && subject.isVisible
+            }
+            // Verify the size of snapshotRegion covers appVisibleRegion exactly in animation.
+            if (snapshotLayers.isNotEmpty()) {
+                val visibleAreas = snapshotLayers.mapNotNull { snapshotLayer ->
+                    snapshotLayer.layer?.visibleRegion
+                }.toTypedArray()
+                val snapshotRegion = RegionSubject.assertThat(visibleAreas, this, timestamp)
+                val appVisibleRegion = it.visibleRegion(component)
+                if (snapshotRegion.region.isNotEmpty) {
+                    snapshotRegion.coversExactly(appVisibleRegion.region)
+                }
+            }
+        }
+    }
+}
+
+/**
  * Asserts that:
  *     [originalLayer] is visible at the start of the trace
  *     [originalLayer] becomes invisible during the trace and (in the same entry) [newLayer]
@@ -216,11 +246,11 @@
 
     assertLayersStart {
         this.isVisible(originalLayer)
-                .isInvisible(newLayer)
+            .isInvisible(newLayer)
     }
 
     assertLayersEnd {
         this.isInvisible(originalLayer)
-                .isVisible(newLayer)
+            .isVisible(newLayer)
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
index 6257484..2e29b3e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
@@ -59,7 +59,7 @@
             }
             transitions {
                 imeTestApp.dismissDialog(wmHelper)
-                instrumentation.uiAutomation.syncInputTransactions()
+                wmHelper.waitImeGone()
             }
             teardown {
                 eachRun {
@@ -91,7 +91,7 @@
                     .then()
                     .isVisible(FlickerComponentName.IME_SNAPSHOT)
                     .then()
-                    .isInvisible(FlickerComponentName.IME_SNAPSHOT)
+                    .isInvisible(FlickerComponentName.IME_SNAPSHOT, isOptional = true)
                     .isInvisible(FlickerComponentName.IME)
         }
     }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
index 78aea1f..88fb1a2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
@@ -17,23 +17,25 @@
 package com.android.server.wm.flicker.ime
 
 import android.app.Instrumentation
+import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.platform.test.annotations.RequiresDevice
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.FlakyTest
 import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
 import com.android.server.wm.flicker.FlickerBuilderProvider
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group2
 import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper
 import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.navBarLayerRotatesAndScales
+import com.android.server.wm.flicker.navBarLayerPositionEnd
 import com.android.server.wm.flicker.navBarWindowIsVisible
+import com.android.server.wm.flicker.snapshotStartingWindowLayerCoversExactlyOnApp
 import com.android.server.wm.flicker.statusBarLayerRotatesScales
 import com.android.server.wm.flicker.statusBarWindowIsVisible
 import org.junit.FixMethodOrder
@@ -43,7 +45,8 @@
 import org.junit.runners.Parameterized
 
 /**
- * Test IME window layer will become visible when switching from the fixed orientation activity.
+ * Test IME window layer will become visible when switching from the fixed orientation activity
+ * (e.g. Launcher activity).
  * To run this test: `atest FlickerTests:OpenImeWindowFromFixedOrientationAppTest`
  */
 @RequiresDevice
@@ -53,24 +56,31 @@
 @Group2
 class OpenImeWindowFromFixedOrientationAppTest(private val testSpec: FlickerTestParameter) {
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-    private val fixedOrientationApp = FixedOrientationAppHelper(instrumentation)
     private val imeTestApp = ImeAppAutoFocusHelper(instrumentation, testSpec.startRotation)
+    private val taplInstrumentation = LauncherInstrumentation()
 
     @FlickerBuilderProvider
     fun buildFlicker(): FlickerBuilder {
         return FlickerBuilder(instrumentation).apply {
             setup {
+                test {
+                    // Launch the activity with expecting IME will be shown.
+                    imeTestApp.launchViaIntent(wmHelper)
+                }
                 eachRun {
-                    fixedOrientationApp.launchViaIntent(wmHelper)
-                    this.setRotation(Surface.ROTATION_90)
+                    // Swiping out the IME activity to home.
+                    taplInstrumentation.goHome()
+                    wmHelper.waitForHomeActivityVisible()
                 }
             }
             transitions {
+                // Bring the exist IME activity to the front in landscape mode device rotation.
+                setRotation(Surface.ROTATION_90)
                 imeTestApp.launchViaIntent(wmHelper)
             }
             teardown {
                 test {
-                    fixedOrientationApp.exit(wmHelper)
+                    imeTestApp.exit(wmHelper)
                 }
             }
         }
@@ -90,7 +100,7 @@
 
     @Presubmit
     @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
+    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
 
     @FlakyTest(bugId = 206753786)
     fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@@ -99,6 +109,12 @@
     @Test
     fun imeLayerBecomesVisible() = testSpec.imeLayerBecomesVisible()
 
+    @Postsubmit
+    @Test
+    fun snapshotStartingWindowLayerCoversExactlyOnApp() {
+        testSpec.snapshotStartingWindowLayerCoversExactlyOnApp(imeTestApp.component)
+    }
+
     companion object {
         /**
          * Creates the test configurations.
@@ -112,7 +128,7 @@
             return FlickerTestParameterFactory.getInstance()
                     .getConfigNonRotationTests(
                             repetitions = 3,
-                            supportedRotations = listOf(Surface.ROTATION_0),
+                            supportedRotations = listOf(Surface.ROTATION_90),
                             supportedNavigationModes = listOf(
                                     WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
                             )
diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
index 43aa4b1..3e2130d 100644
--- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
@@ -45,6 +45,7 @@
              android:theme="@style/CutoutShortEdges"
              android:taskAffinity="com.android.server.wm.flicker.testapp.ImeActivityAutoFocus"
              android:windowSoftInputMode="stateVisible"
+             android:configChanges="orientation|screenSize"
              android:label="ImeAppAutoFocus"
              android:exported="true">
             <intent-filter>
diff --git a/tests/WindowInsetsTests/res/layout/controller_activity.xml b/tests/WindowInsetsTests/res/layout/controller_activity.xml
index d51a4dd..5550eab 100644
--- a/tests/WindowInsetsTests/res/layout/controller_activity.xml
+++ b/tests/WindowInsetsTests/res/layout/controller_activity.xml
@@ -88,7 +88,7 @@
 
         <TextView
             android:id="@+id/textViewControllableInsets"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_margin="5dp" />
 
diff --git a/tests/WindowInsetsTests/res/values/strings.xml b/tests/WindowInsetsTests/res/values/strings.xml
index d6355f5..516d458 100644
--- a/tests/WindowInsetsTests/res/values/strings.xml
+++ b/tests/WindowInsetsTests/res/values/strings.xml
@@ -22,7 +22,7 @@
 
     <!-- The item positions should match the flag values respectively. -->
     <string-array name="behaviors">
-        <item>BEHAVIOR_SHOW_BARS_BY_TOUCH</item>
+        <item>BEHAVIOR_SHOW_BARS_BY_TOUCH (deprecated)</item>
         <item>BEHAVIOR_DEFAULT</item>
         <item>BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE</item>
     </string-array>
diff --git a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/ControllerActivity.java b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/ControllerActivity.java
index 95fd959..e6b60cf 100644
--- a/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/ControllerActivity.java
+++ b/tests/WindowInsetsTests/src/com/google/android/test/windowinsetstests/ControllerActivity.java
@@ -83,7 +83,51 @@
         final View contentView = findViewById(R.id.content);
         contentView.setOnApplyWindowInsetsListener(this);
         contentView.getWindowInsetsController().addOnControllableInsetsChangedListener(
-                (c, types) -> mTextControllableInsets.setText("ControllableInsetsTypes=" + types));
+                (c, types) -> mTextControllableInsets.setText(
+                        "ControllableInsetsTypes:\n" + insetsTypesToString(types)));
+    }
+
+    private static String insetsTypesToString(int types) {
+        if (types == 0) {
+            return "none";
+        }
+        final StringBuilder sb = new StringBuilder();
+        if ((types & Type.statusBars()) != 0) {
+            types &= ~Type.statusBars();
+            sb.append("statusBars ");
+        }
+        if ((types & Type.navigationBars()) != 0) {
+            types &= ~Type.navigationBars();
+            sb.append("navigationBars ");
+        }
+        if ((types & Type.captionBar()) != 0) {
+            types &= ~Type.captionBar();
+            sb.append("captionBar ");
+        }
+        if ((types & Type.ime()) != 0) {
+            types &= ~Type.ime();
+            sb.append("ime ");
+        }
+        if ((types & Type.systemGestures()) != 0) {
+            types &= ~Type.systemGestures();
+            sb.append("systemGestures ");
+        }
+        if ((types & Type.mandatorySystemGestures()) != 0) {
+            types &= ~Type.mandatorySystemGestures();
+            sb.append("mandatorySystemGestures ");
+        }
+        if ((types & Type.tappableElement()) != 0) {
+            types &= ~Type.tappableElement();
+            sb.append("tappableElement ");
+        }
+        if ((types & Type.displayCutout()) != 0) {
+            types &= ~Type.displayCutout();
+            sb.append("displayCutout ");
+        }
+        if (types != 0) {
+            sb.append("unknownTypes:").append(types);
+        }
+        return sb.toString();
     }
 
     @Override
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 1fe13fe..06cbeb5 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -124,16 +124,6 @@
     @SmallTest
     public void testSET_ORIENTATION() {
         try {
-            mWm.updateRotation(true, false);
-            fail("IWindowManager.updateRotation did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-
-        try {
             mWm.freezeRotation(-1);
             fail("IWindowManager.freezeRotation did not throw SecurityException as"
                     + " expected");