Merge "Add visibility special casing for sdk sandbox" into tm-dev am: f598205c2d am: ee2f587be0

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

Change-Id: I14fd4772cdf29c4c4b77b463bd2ab9e37ec4d96c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 48277fb3b..2df158d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -482,8 +482,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
   }
 
@@ -1857,7 +1855,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;
   }
@@ -3396,7 +3393,7 @@
     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 @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/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 c6f5920..11d42461 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3425,26 +3425,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;
             // Defer the top state for VM to avoid aggressive JIT compilation affecting activity
             // launch time.
@@ -3461,22 +3447,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. */
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/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/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/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/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 d2a86eb..d1ff9f7 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
@@ -10945,6 +10996,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 d598017..5f5645f 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -1536,8 +1536,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..f246cd9 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.
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 127c7b7..19c2cfb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -563,7 +563,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 final WindowLayout mWindowLayout;
 
     private ViewRootImpl mParentViewRoot;
 
@@ -603,6 +603,7 @@
     int mSyncSeqId = 0;
     int mLastSyncSeqId = 0;
 
+    private boolean mUpdateSurfaceNeeded;
     boolean mFullRedrawNeeded;
     boolean mNewSurfaceNeeded;
     boolean mForceNextWindowRelayout;
@@ -880,18 +881,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();
@@ -1767,7 +1770,7 @@
             }
         }
 
-        mForceNextWindowRelayout = forceNextWindowRelayout;
+        mForceNextWindowRelayout |= forceNextWindowRelayout;
         mPendingAlwaysConsumeSystemBars = args.argi2 != 0;
         mSyncSeqId = args.argi4 > mSyncSeqId ? args.argi4 : mSyncSeqId;
 
@@ -2893,7 +2896,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;
@@ -2997,6 +2999,8 @@
                             !mFirst, INVALID_DISPLAY /* same display */);
                     updatedConfiguration = true;
                 }
+                final boolean updateSurfaceNeeded = mUpdateSurfaceNeeded;
+                mUpdateSurfaceNeeded = false;
 
                 surfaceSizeChanged = false;
                 if (!mLastSurfaceSize.equals(mSurfaceSize)) {
@@ -3075,8 +3079,7 @@
                     if (isHardwareEnabled()) {
                         mAttachInfo.mThreadedRenderer.destroy();
                     }
-                } else if ((surfaceReplaced
-                        || surfaceSizeChanged || windowRelayoutWasForced)
+                } else if ((surfaceReplaced || surfaceSizeChanged || updateSurfaceNeeded)
                         && mSurfaceHolder == null
                         && mAttachInfo.mThreadedRenderer != null
                         && mSurface.isValid()) {
@@ -5204,6 +5207,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,
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 00052f6..690981e 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -341,6 +341,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 +380,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 {}
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index aae930e..85a5762 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -386,7 +386,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..7cc50c5
--- /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,
+            Rect attachedWindowFrame, float compatScale, ClientWindowFrames outFrames) {
+        outFrames.frame.set(0, 0, attrs.width, attrs.height);
+        outFrames.displayFrame.set(outFrames.frame);
+        outFrames.parentFrame.set(outFrames.frame);
+    }
+}
+
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..633d879 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -384,12 +384,10 @@
      */
     @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;
     }
 
@@ -1106,9 +1104,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 +1166,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 +1216,6 @@
             mInsetsProviderFrame = copy.mInsetsProviderFrame;
             mToTop = copy.mToTop;
             mReparentTopOnly = copy.mReparentTopOnly;
-            mMoveAdjacentTogether = copy.mMoveAdjacentTogether;
             mWindowingModes = copy.mWindowingModes;
             mActivityTypes = copy.mActivityTypes;
             mLaunchOptions = copy.mLaunchOptions;
@@ -1245,7 +1237,6 @@
             }
             mToTop = in.readBoolean();
             mReparentTopOnly = in.readBoolean();
-            mMoveAdjacentTogether = in.readBoolean();
             mWindowingModes = in.createIntArray();
             mActivityTypes = in.createIntArray();
             mLaunchOptions = in.readBundle();
@@ -1300,10 +1291,6 @@
             return mReparentTopOnly;
         }
 
-        public boolean getMoveAdjacentTogether() {
-            return mMoveAdjacentTogether;
-        }
-
         public int[] getWindowingModes() {
             return mWindowingModes;
         }
@@ -1356,8 +1343,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 +1399,6 @@
             }
             dest.writeBoolean(mToTop);
             dest.writeBoolean(mReparentTopOnly);
-            dest.writeBoolean(mMoveAdjacentTogether);
             dest.writeIntArray(mWindowingModes);
             dest.writeIntArray(mActivityTypes);
             dest.writeBundle(mLaunchOptions);
@@ -1458,8 +1443,6 @@
 
             private boolean mReparentTopOnly;
 
-            private boolean mMoveAdjacentTogether;
-
             @Nullable
             private int[]  mWindowingModes;
 
@@ -1515,11 +1498,6 @@
                 return this;
             }
 
-            Builder setMoveAdjacentTogether(boolean moveAdjacentTogether) {
-                mMoveAdjacentTogether = moveAdjacentTogether;
-                return this;
-            }
-
             Builder setWindowingModes(@Nullable int[] windowingModes) {
                 mWindowingModes = windowingModes;
                 return this;
@@ -1570,7 +1548,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/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 488fb180..12571b1 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -912,6 +912,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/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 ac60235..bd84ba1 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3755,6 +3755,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 +5136,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 +5161,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 is used when an app doesn't specify
+         android:minAspectRatio in accordance with CDD 7.1.1.2 requirement:
+         https://source.android.com/compatibility/12/android-12-cdd#7112_screen_aspect_ratio.
+         An exception will be thrown if the given aspect ratio < 4:3.  -->
+    <item name="config_letterboxDefaultMinAspectRatioForUnresizableApps" format="float" type="dimen">1.5</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>
@@ -5813,4 +5843,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 8f60562..ad02128d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -394,6 +394,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" />
@@ -3336,6 +3337,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 +4389,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/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 51ed8567..05e9b3d 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",
@@ -469,6 +475,12 @@
       "group": "WM_DEBUG_ADD_REMOVE",
       "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java"
     },
+    "-1635750891": {
+      "message": "Received remote change for Display[%d], applied: [%dx%d, rot = %d]",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONFIGURATION",
+      "at": "com\/android\/server\/wm\/RemoteDisplayChangeController.java"
+    },
     "-1633115609": {
       "message": "Key dispatch not paused for screen off",
       "level": "VERBOSE",
@@ -757,6 +769,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",
@@ -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",
@@ -2143,6 +2167,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",
@@ -2533,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",
@@ -2803,12 +2827,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",
@@ -3055,6 +3073,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",
@@ -3385,12 +3409,6 @@
       "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",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
     "1252594551": {
       "message": "Window types in WindowContext and LayoutParams.type should match! Type from LayoutParams is %d, but type from WindowContext is %d",
       "level": "WARN",
@@ -3487,6 +3505,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",
@@ -3511,6 +3535,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",
@@ -3853,6 +3883,12 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
     },
+    "1764619787": {
+      "message": "Remote change for Display[%d]: timeout reached",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONFIGURATION",
+      "at": "com\/android\/server\/wm\/RemoteDisplayChangeController.java"
+    },
     "1774661765": {
       "message": "Devices still not ready after waiting %d milliseconds before attempting to detect safe mode.",
       "level": "WARN",
@@ -4177,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",
@@ -4230,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/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/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index a6f6388..cfb3205 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -43,7 +43,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;
 
@@ -63,7 +62,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);
@@ -80,8 +79,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();
     }
 
     /**
@@ -89,18 +92,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
@@ -108,7 +101,6 @@
         return mWindowLayoutChangeListeners.keySet();
     }
 
-    @NonNull
     private boolean isListeningForLayoutChanges(IBinder token) {
         for (Activity activity: getActivitiesListeningForLayoutChanges()) {
             if (token.equals(activity.getWindow().getAttributes().token)) {
@@ -125,12 +117,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
@@ -144,17 +136,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);
     }
 
     /**
@@ -172,26 +171,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 (activity.isInMultiWindowMode()) {
+        } else if (activity.isInMultiWindowMode()) {
             // 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;
@@ -205,8 +199,8 @@
                     features.add(new FoldingFeature(featureRect, baseFeature.getType(), state));
                 }
             }
+            return features;
         }
-        return features;
     }
 
     /**
@@ -233,7 +227,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/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/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/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..f6a3e7f 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;
@@ -34,6 +33,7 @@
 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.UnfoldTransitionHandler;
 
@@ -53,7 +53,6 @@
     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;
@@ -75,7 +74,6 @@
             KidsModeTaskOrganizer kidsModeTaskOrganizer,
             Optional<BubbleController> bubblesOptional,
             Optional<SplitScreenController> splitScreenOptional,
-            Optional<AppPairsController> appPairsOptional,
             Optional<PipTouchHandler> pipTouchHandlerOptional,
             FullscreenTaskListener fullscreenTaskListener,
             Optional<FullscreenUnfoldController> fullscreenUnfoldTransitionController,
@@ -93,7 +91,6 @@
         mKidsModeTaskOrganizer = kidsModeTaskOrganizer;
         mBubblesOptional = bubblesOptional;
         mSplitScreenOptional = splitScreenOptional;
-        mAppPairsOptional = appPairsOptional;
         mFullscreenTaskListener = fullscreenTaskListener;
         mPipTouchHandlerOptional = pipTouchHandlerOptional;
         mFullscreenUnfoldController = fullscreenUnfoldTransitionController;
@@ -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
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..ea3712b 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;
     }
@@ -1468,6 +1476,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 +1566,7 @@
         public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
             mBubblePositioner.setImeVisible(imeVisible, imeHeight);
             if (mStackView != null) {
-                mStackView.animateForIme(imeVisible);
+                mStackView.setImeVisible(imeVisible);
             }
         }
     }
@@ -1843,6 +1863,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 a089585..bf8406c 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,48 @@
 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 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 +135,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 +144,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 +159,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 +316,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 +349,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 +433,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 +478,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 +559,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,15 +573,128 @@
     }
 
     /**
-     * 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);
         }
-        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);
     }
 
     /**
@@ -543,13 +705,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 +722,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 +887,9 @@
             mTaskView.onLocationChanged();
         }
         if (mIsOverflow) {
-            mOverflowView.show();
+            post(() -> {
+                mOverflowView.show();
+            });
         }
     }
 
@@ -728,28 +930,48 @@
         post(() -> {
             mCurrentPointer = showVertically ? onLeft ? mLeftPointer : mRightPointer : mTopPointer;
             updatePointerView();
-            float pointerY;
-            float pointerX;
             if (showVertically) {
-                pointerY = bubbleCenter - (mPointerWidth / 2f);
-                pointerX = onLeft
+                mPointerPos.y = bubbleCenter - (mPointerWidth / 2f);
+                mPointerPos.x = onLeft
                         ? -mPointerHeight + mPointerOverlap
                         : getWidth() - mPaddingRight - mPointerOverlap;
             } else {
-                pointerY = mPointerOverlap;
-                pointerX = bubbleCenter - (mPointerWidth / 2f);
+                mPointerPos.y = mPointerOverlap;
+                mPointerPos.x = 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..9770a3f 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
@@ -366,6 +366,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;
@@ -749,4 +757,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 0e8dc63..33a5fa1 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;
@@ -97,6 +104,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", false);
+
     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. */
@@ -148,7 +161,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,6 +210,7 @@
     private PhysicsAnimationLayout mBubbleContainer;
     private StackAnimationController mStackAnimationController;
     private ExpandedAnimationController mExpandedAnimationController;
+    private ExpandedViewAnimationController mExpandedViewAnimationController;
 
     private View mScrim;
     private View mManageMenuScrim;
@@ -276,6 +290,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 +710,67 @@
         }
     };
 
+    /** 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
+            float collapsed = Math.min(dy, 0);
+            mExpandedViewAnimationController.updateDrag((int) -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();
+            }
+        }
+    };
+
     /** Click listener set on the flyout, which expands the stack when the flyout is tapped. */
     private OnClickListener mFlyoutClickListener = new OnClickListener() {
         @Override
@@ -766,7 +844,7 @@
             ShellExecutor mainExecutor) {
         super(context);
 
-        mDelayedAnimationExecutor = mainExecutor;
+        mMainExecutor = mainExecutor;
         mBubbleController = bubbleController;
         mBubbleData = data;
 
@@ -796,6 +874,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 +1057,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 +1071,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().setAlpha(alpha);
             }
         });
 
@@ -1795,6 +1882,7 @@
     private void showNewlySelectedBubble(BubbleViewProvider bubbleToSelect) {
         final BubbleViewProvider previouslySelected = mExpandedBubble;
         mExpandedBubble = bubbleToSelect;
+        mExpandedViewAnimationController.setExpandedView(mExpandedBubble.getExpandedView());
 
         if (mIsExpanded) {
             hideCurrentInputMethod();
@@ -1843,12 +1931,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 +1951,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() {
@@ -2072,11 +2214,12 @@
         mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
 
         if (mExpandedBubble.getExpandedView() != null) {
-            mExpandedBubble.getExpandedView().setTaskViewAlpha(0f);
+            mExpandedBubble.getExpandedView().setContentAlpha(0f);
+            mExpandedBubble.getExpandedView().setAlpha(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 +2257,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 +2360,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) {
@@ -2278,7 +2483,7 @@
 
         mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
 
-        mDelayedAnimationExecutor.executeDelayed(() -> {
+        mMainExecutor.executeDelayed(() -> {
             if (!mIsExpanded) {
                 mIsBubbleSwitchAnimating = false;
                 return;
@@ -2309,7 +2514,7 @@
      * animating flags for those animations.
      */
     private void cancelDelayedExpandCollapseSwitchAnimations() {
-        mDelayedAnimationExecutor.removeCallbacks(mDelayedAnimation);
+        mMainExecutor.removeCallbacks(mDelayedAnimation);
 
         mIsExpansionAnimating = false;
         mIsBubbleSwitchAnimating = false;
@@ -2333,9 +2538,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(() -> {
@@ -2386,6 +2600,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) {
@@ -2821,7 +3091,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..c24efb9 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
@@ -17,11 +17,13 @@
 package com.android.wm.shell.bubbles.animation;
 
 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 +63,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 +78,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. */
@@ -278,11 +288,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 +544,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..ca54232
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java
@@ -0,0 +1,432 @@
+/*
+ * 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 android.view.View.ALPHA;
+
+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.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.setAlpha(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, 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/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index db6131a..1d10bbe 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;
@@ -70,8 +68,6 @@
 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;
@@ -319,26 +315,27 @@
     @WMSingleton
     @Provides
     static Optional<FullscreenUnfoldController> provideFullscreenUnfoldController(
-            @DynamicOverride Optional<FullscreenUnfoldController> fullscreenUnfoldController,
+            @DynamicOverride Lazy<Optional<FullscreenUnfoldController>> 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();
     }
@@ -561,29 +558,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,7 +638,6 @@
             KidsModeTaskOrganizer kidsModeTaskOrganizer,
             Optional<BubbleController> bubblesOptional,
             Optional<SplitScreenController> splitScreenOptional,
-            Optional<AppPairsController> appPairsOptional,
             Optional<PipTouchHandler> pipTouchHandlerOptional,
             FullscreenTaskListener fullscreenTaskListener,
             Optional<FullscreenUnfoldController> appUnfoldTransitionController,
@@ -682,7 +655,6 @@
                 kidsModeTaskOrganizer,
                 bubblesOptional,
                 splitScreenOptional,
-                appPairsOptional,
                 pipTouchHandlerOptional,
                 fullscreenTaskListener,
                 appUnfoldTransitionController,
@@ -709,17 +681,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..47c9214 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,11 @@
 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,6 +63,7 @@
 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;
@@ -75,6 +72,8 @@
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
 import com.android.wm.shell.unfold.UnfoldBackgroundController;
+import com.android.wm.shell.unfold.UnfoldTransitionHandler;
+import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator;
 
 import java.util.Optional;
 
@@ -182,31 +181,6 @@
                 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);
-    }
-
     //
     // Pip
     //
@@ -215,7 +189,8 @@
     @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,
             PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
             WindowManagerShellWrapper windowManagerShellWrapper,
@@ -224,7 +199,8 @@
             Optional<OneHandedController> oneHandedController,
             @ShellMainThread ShellExecutor mainExecutor) {
         return Optional.ofNullable(PipController.create(context, displayController,
-                pipAppOpsListener, pipBoundsAlgorithm, pipBoundsState,
+                pipAppOpsListener, pipBoundsAlgorithm, pipKeepClearAlgorithm, pipBoundsState,
+                pipMotionHelper,
                 pipMediaController, phonePipMenuController, pipTaskOrganizer,
                 pipTouchHandler, pipTransitionController, windowManagerShellWrapper,
                 taskStackListener, pipParamsChangedForwarder, oneHandedController, mainExecutor));
@@ -244,6 +220,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);
@@ -356,15 +338,37 @@
     @Provides
     @DynamicOverride
     static FullscreenUnfoldController provideFullscreenUnfoldController(
-            Context context,
             Optional<ShellUnfoldProgressProvider> progressProvider,
-            Lazy<UnfoldBackgroundController> unfoldBackgroundController,
-            DisplayInsetsController displayInsetsController,
+            Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
+            FullscreenUnfoldTaskAnimator fullscreenUnfoldTaskAnimator,
+            UnfoldBackgroundController unfoldBackgroundController,
             @ShellMainThread ShellExecutor mainExecutor
     ) {
-        return new FullscreenUnfoldController(context, mainExecutor,
-                unfoldBackgroundController.get(), progressProvider.get(),
-                displayInsetsController);
+        return new FullscreenUnfoldController(mainExecutor,
+                unfoldBackgroundController, progressProvider.get(),
+                unfoldTransitionHandler.get(), fullscreenUnfoldTaskAnimator);
+    }
+
+    @Provides
+    static FullscreenUnfoldTaskAnimator provideFullscreenUnfoldTaskAnimator(
+            Context context,
+            DisplayInsetsController displayInsetsController
+    ) {
+        return new FullscreenUnfoldTaskAnimator(context, displayInsetsController);
+    }
+
+    @WMSingleton
+    @Provides
+    @DynamicOverride
+    static UnfoldTransitionHandler provideUnfoldTransitionHandler(
+            Optional<ShellUnfoldProgressProvider> progressProvider,
+            FullscreenUnfoldTaskAnimator animator,
+            UnfoldBackgroundController backgroundController,
+            TransactionPool transactionPool,
+            Transitions transitions,
+            @ShellMainThread ShellExecutor executor) {
+        return new UnfoldTransitionHandler(progressProvider.get(), animator,
+                transactionPool, backgroundController, executor, transitions);
     }
 
     @Provides
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..1fc1215 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
@@ -76,6 +76,8 @@
                 taskInfo.taskId);
         final Point positionInParent = taskInfo.positionInParent;
         mDataByTaskId.put(taskInfo.taskId, new TaskData(leash, positionInParent));
+        mAnimatableTasksListener.onTaskAppeared(taskInfo);
+
         if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
         mSyncQueue.runInSync(t -> {
             // Reset several properties back to fullscreen (PiP, for example, leaves all these
@@ -87,15 +89,15 @@
             t.show(leash);
         });
 
-        mAnimatableTasksListener.onTaskAppeared(taskInfo);
         updateRecentsForVisibleFullscreenTask(taskInfo);
     }
 
     @Override
     public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
+        mAnimatableTasksListener.onTaskInfoChanged(taskInfo);
+
         if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
 
-        mAnimatableTasksListener.onTaskInfoChanged(taskInfo);
         updateRecentsForVisibleFullscreenTask(taskInfo);
 
         final TaskData data = mDataByTaskId.get(taskInfo.taskId);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java
index aa3868c..99f15f6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenUnfoldController.java
@@ -17,213 +17,119 @@
 package com.android.wm.shell.fullscreen;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-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;
-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.unfold.ShellUnfoldProgressProvider;
 import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener;
 import com.android.wm.shell.unfold.UnfoldBackgroundController;
+import com.android.wm.shell.unfold.UnfoldTransitionHandler;
+import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator;
 
 import java.util.concurrent.Executor;
 
 /**
  * Controls full screen app unfold transition: animating cropping window and scaling when
  * folding or unfolding a foldable device.
+ *
+ * - When Shell transitions are disabled (legacy mode) this controller animates task surfaces
+ *   when doing both fold and unfold.
+ *
+ * - When Shell transitions are enabled this controller animates the surfaces only when
+ *   folding a foldable device. It's not done as a shell transition because we are not committed
+ *   to the display size WM changes yet.
+ *   In this case unfolding is handled by
+ *   {@link com.android.wm.shell.unfold.UnfoldTransitionHandler}.
  */
-public final class FullscreenUnfoldController implements UnfoldListener,
-        OnInsetsChangedListener {
-
-    private static final float[] FLOAT_9 = new float[9];
-    private static final TypeEvaluator<Rect> RECT_EVALUATOR = new RectEvaluator(new Rect());
-
-    private static final float HORIZONTAL_START_MARGIN = 0.08f;
-    private static final float VERTICAL_START_MARGIN = 0.03f;
-    private static final float END_SCALE = 1f;
-    private static final float START_SCALE = END_SCALE - VERTICAL_START_MARGIN * 2;
+public final class FullscreenUnfoldController implements UnfoldListener {
 
     private final Executor mExecutor;
     private final ShellUnfoldProgressProvider mProgressProvider;
-    private final DisplayInsetsController mDisplayInsetsController;
-
-    private final SparseArray<AnimationContext> mAnimationContextByTaskId = new SparseArray<>();
     private final UnfoldBackgroundController mBackgroundController;
-
-    private InsetsSource mTaskbarInsetsSource;
-
-    private final float mWindowCornerRadiusPx;
-    private final float mExpandedTaskBarHeight;
-
     private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
+    private final FullscreenUnfoldTaskAnimator mAnimator;
+    private final UnfoldTransitionHandler mUnfoldTransitionHandler;
+
+    private boolean mShouldHandleAnimation = false;
 
     public FullscreenUnfoldController(
-            @NonNull Context context,
             @NonNull Executor executor,
             @NonNull UnfoldBackgroundController backgroundController,
             @NonNull ShellUnfoldProgressProvider progressProvider,
-            @NonNull DisplayInsetsController displayInsetsController
+            @NonNull UnfoldTransitionHandler unfoldTransitionHandler,
+            @NonNull FullscreenUnfoldTaskAnimator animator
     ) {
         mExecutor = executor;
         mProgressProvider = progressProvider;
-        mDisplayInsetsController = displayInsetsController;
-        mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(context);
-        mExpandedTaskBarHeight = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.taskbar_frame_height);
         mBackgroundController = backgroundController;
+        mUnfoldTransitionHandler = unfoldTransitionHandler;
+        mAnimator = animator;
     }
 
     /**
      * Initializes the controller
      */
     public void init() {
+        mAnimator.init();
         mProgressProvider.addListener(mExecutor, this);
-        mDisplayInsetsController.addInsetsChangedListener(DEFAULT_DISPLAY, this);
+    }
+
+    @Override
+    public void onStateChangeStarted() {
+        mShouldHandleAnimation = !mUnfoldTransitionHandler.willHandleTransition();
     }
 
     @Override
     public void onStateChangeProgress(float progress) {
-        if (mAnimationContextByTaskId.size() == 0) return;
+        if (!mAnimator.hasActiveTasks() || !mShouldHandleAnimation) 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);
-        }
-
+        mAnimator.applyAnimationProgress(progress, mTransaction);
         mTransaction.apply();
     }
 
     @Override
     public void onStateChangeFinished() {
-        for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
-            final AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-            resetSurface(context);
+        if (!mShouldHandleAnimation) {
+            return;
         }
 
+        mShouldHandleAnimation = false;
+        mAnimator.resetAllSurfaces(mTransaction);
         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--) {
-            AnimationContext context = mAnimationContextByTaskId.valueAt(i);
-            context.update(mTaskbarInsetsSource, context.mTaskInfo);
-        }
-    }
-
     /**
      * Called when a new matching task appeared
      */
     public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
-        AnimationContext animationContext = new AnimationContext(leash, mTaskbarInsetsSource,
-                taskInfo);
-        mAnimationContextByTaskId.put(taskInfo.taskId, animationContext);
+        mAnimator.addTask(taskInfo, leash);
     }
 
     /**
      * Called when matching task changed
      */
     public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
-        AnimationContext animationContext = mAnimationContextByTaskId.get(taskInfo.taskId);
-        if (animationContext != null) {
-            animationContext.update(mTaskbarInsetsSource, taskInfo);
-        }
+        mAnimator.onTaskInfoChanged(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);
+        // PiP task has its own cleanup path, ignore surface reset to avoid conflict.
+        if (taskInfo.getWindowingMode() != WINDOWING_MODE_PINNED) {
+            mAnimator.resetSurface(taskInfo, mTransaction);
         }
+        mAnimator.removeTask(taskInfo);
 
-        if (mAnimationContextByTaskId.size() == 0) {
+        if (!mAnimator.hasActiveTasks()) {
             mBackgroundController.removeBackground(mTransaction);
         }
 
         mTransaction.apply();
     }
-
-    private void resetSurface(AnimationContext context) {
-        mTransaction
-                .setWindowCrop(context.mLeash, null)
-                .setCornerRadius(context.mLeash, 0.0F)
-                .setMatrix(context.mLeash, 1.0F, 0.0F, 0.0F, 1.0F)
-                .setPosition(context.mLeash,
-                        (float) context.mTaskInfo.positionInParent.x,
-                        (float) context.mTaskInfo.positionInParent.y);
-    }
-
-    private class AnimationContext {
-        final SurfaceControl mLeash;
-        final Rect mStartCropRect = new Rect();
-        final Rect mEndCropRect = new Rect();
-        final Rect mCurrentCropRect = new Rect();
-        final Matrix mMatrix = new Matrix();
-
-        TaskInfo mTaskInfo;
-
-        private AnimationContext(SurfaceControl leash,
-                                InsetsSource taskBarInsetsSource,
-                                TaskInfo taskInfo) {
-            this.mLeash = leash;
-            update(taskBarInsetsSource, taskInfo);
-        }
-
-        private void update(InsetsSource taskBarInsetsSource, TaskInfo taskInfo) {
-            mTaskInfo = taskInfo;
-            mStartCropRect.set(mTaskInfo.getConfiguration().windowConfiguration.getBounds());
-
-            if (taskBarInsetsSource != null) {
-                // Only insets the cropping window with task bar when it's expanded
-                if (taskBarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight) {
-                    mStartCropRect.inset(taskBarInsetsSource
-                            .calculateVisibleInsets(mStartCropRect));
-                }
-            }
-
-            mEndCropRect.set(mStartCropRect);
-
-            int horizontalMargin = (int) (mEndCropRect.width() * HORIZONTAL_START_MARGIN);
-            mStartCropRect.left = mEndCropRect.left + horizontalMargin;
-            mStartCropRect.right = mEndCropRect.right - horizontalMargin;
-            int verticalMargin = (int) (mEndCropRect.height() * VERTICAL_START_MARGIN);
-            mStartCropRect.top = mEndCropRect.top + verticalMargin;
-            mStartCropRect.bottom = mEndCropRect.bottom - verticalMargin;
-        }
-    }
 }
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/DividerState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerState.java
deleted file mode 100644
index af2ab15..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerState.java
+++ /dev/null
@@ -1,25 +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;
-
-/**
- * Class to hold state of divider that needs to persist across configuration changes.
- */
-final class DividerState {
-    public boolean animateAfterRecentsDrawn;
-    public float mRatioPositionBeforeMinimized;
-}
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/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index c05654a..e6fde67 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();
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..28427a8 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;
@@ -52,6 +51,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 +145,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 +222,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);
         }
@@ -245,16 +257,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 +267,22 @@
     }
 
     @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 boolean handleRotateDisplay(int startRotation, int endRotation,
             WindowContainerTransaction wct) {
         if (mRequestedEnterTransition != null && mOneShotAnimationType == ANIM_TYPE_ALPHA) {
@@ -315,11 +336,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 +596,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,7 +696,6 @@
             computeEnterPipRotatedBounds(rotationDelta, startRotation, endRotation, taskInfo,
                     destinationBounds, sourceHintRect);
         }
-        PipAnimationController.PipTransitionAnimator animator;
         // Set corner radius for entering pip.
         mSurfaceTransactionHelper
                 .crop(finishTransaction, leash, destinationBounds)
@@ -694,7 +732,7 @@
                         null /* callback */, false /* withStartDelay */);
             }
             mPipTransitionState.setInSwipePipToHomeTransition(false);
-            return true;
+            return;
         }
 
         if (rotationDelta != Surface.ROTATION_0) {
@@ -702,6 +740,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 +756,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 +763,6 @@
             throw new RuntimeException("Unrecognized animation type: "
                     + mOneShotAnimationType);
         }
-        startTransaction.apply();
         animator.setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
                 .setPipAnimationCallback(mPipAnimationCallback)
                 .setDuration(mEnterExitAnimationDuration);
@@ -731,8 +773,6 @@
             animator.setDestinationBounds(mPipBoundsAlgorithm.getEntryDestinationBounds());
         }
         animator.start();
-
-        return true;
     }
 
     /** Computes destination bounds in old rotation and updates source hint rect if available. */
@@ -852,27 +892,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..d3f69f6 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;
@@ -28,10 +29,16 @@
 import android.content.pm.ActivityInfo;
 import android.graphics.Rect;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Looper;
 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;
 
@@ -206,6 +213,30 @@
         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) {
+    }
+
     /**
      * Callback interface for PiP transitions (both from and to PiP mode)
      */
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..c3e6d82 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
@@ -110,7 +110,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;
@@ -156,7 +158,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,7 +288,8 @@
     @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,
             PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
             WindowManagerShellWrapper windowManagerShellWrapper,
@@ -301,7 +304,7 @@
         }
 
         return new PipController(context, displayController, pipAppOpsListener, pipBoundsAlgorithm,
-                pipBoundsState, pipMediaController,
+                pipKeepClearAlgorithm, pipBoundsState, pipMotionHelper, pipMediaController,
                 phonePipMenuController, pipTaskOrganizer, pipTouchHandler, pipTransitionController,
                 windowManagerShellWrapper, taskStackListener, pipParamsChangedForwarder,
                 oneHandedController, mainExecutor)
@@ -312,7 +315,9 @@
             DisplayController displayController,
             PipAppOpsListener pipAppOpsListener,
             PipBoundsAlgorithm pipBoundsAlgorithm,
+            PipKeepClearAlgorithm pipKeepClearAlgorithm,
             @NonNull PipBoundsState pipBoundsState,
+            PipMotionHelper pipMotionHelper,
             PipMediaController pipMediaController,
             PhonePipMenuController phonePipMenuController,
             PipTaskOrganizer pipTaskOrganizer,
@@ -335,7 +340,9 @@
         mWindowManagerShellWrapper = windowManagerShellWrapper;
         mDisplayController = displayController;
         mPipBoundsAlgorithm = pipBoundsAlgorithm;
+        mPipKeepClearAlgorithm = pipKeepClearAlgorithm;
         mPipBoundsState = pipBoundsState;
+        mPipMotionHelper = pipMotionHelper;
         mPipTaskOrganizer = pipTaskOrganizer;
         mMainExecutor = mainExecutor;
         mMediaController = pipMediaController;
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/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 31b510c..0d976d4 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
@@ -108,7 +108,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,
@@ -198,6 +198,10 @@
         return mStageCoordinator.isSplitScreenVisible();
     }
 
+    public StageCoordinator getTransitionHandler() {
+        return mStageCoordinator;
+    }
+
     @Nullable
     public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) {
         if (!isSplitScreenVisible() || splitPosition == SPLIT_POSITION_UNDEFINED) {
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..f8221d5 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,7 +66,7 @@
     IBinder mPendingRecent = null;
 
     private IBinder mAnimatingTransition = null;
-    private OneShotRemoteHandler mPendingRemoteHandler = null;
+    OneShotRemoteHandler mPendingRemoteHandler = null;
     private OneShotRemoteHandler mActiveRemoteHandler = null;
 
     private final Transitions.TransitionFinishCallback mRemoteFinishCB = this::onFinish;
@@ -94,7 +90,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 +101,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 +137,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 +187,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,7 +220,6 @@
 
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "  splitTransition "
                         + " deduced Enter recent panel");
-        return transition;
     }
 
     void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t,
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 7ea32a6..3cf8a45 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
@@ -28,6 +28,7 @@
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
 import static android.view.WindowManager.transitTypeToString;
+import static android.window.TransitionInfo.FLAG_FIRST_CUSTOM;
 import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
 
 import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
@@ -47,7 +48,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;
@@ -83,6 +83,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;
@@ -131,12 +132,15 @@
  * 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;
@@ -641,7 +645,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(
@@ -674,8 +678,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);
             }
         }
     }
@@ -738,10 +742,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) {
@@ -1024,8 +1025,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);
     }
@@ -1202,8 +1202,10 @@
         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
@@ -1321,7 +1323,7 @@
         if (displayId != DEFAULT_DISPLAY) {
             return;
         }
-        mDisplayController.addDisplayChangingController(this::onRotateDisplay);
+        mDisplayController.addDisplayChangingController(this::onDisplayChange);
     }
 
     @Override
@@ -1332,14 +1334,17 @@
         mDisplayLayout.set(mDisplayController.getDisplayLayout(displayId));
     }
 
-    private void onRotateDisplay(int displayId, int fromRotation, int toRotation,
-            WindowContainerTransaction wct) {
+    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();
     }
@@ -1392,7 +1397,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
@@ -1419,7 +1425,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"
@@ -1434,7 +1440,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) {
@@ -1444,12 +1450,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);
                 }
             }
@@ -1464,6 +1471,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,6 +1513,7 @@
             final SurfaceControl.Transaction t = mTransactionPool.acquire();
             finishEnterSplitScreen(t);
             mSplitTransitions.mPendingEnter = null;
+            mSplitTransitions.mPendingRemoteHandler = null;
             t.apply();
             mTransactionPool.release(t);
         }
@@ -1552,11 +1587,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
@@ -1620,8 +1657,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
@@ -1654,7 +1691,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
@@ -1671,30 +1708,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;
     }
 
@@ -1870,8 +1914,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..eb51338 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
@@ -266,13 +266,13 @@
             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
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 ac25c75..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() {
-                try {
-                    adapter.getRunner().onAnimationCancelled();
-                } 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/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
new file mode 100644
index 0000000..1ffe26df
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.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.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;
+
+        final int mType;
+        final IBinder mTransition;
+
+        Transitions.TransitionFinishCallback mFinishCallback = 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.remove(i);
+            break;
+        }
+        if (mixed == null) return false;
+
+        if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
+            return animateEnterPipFromSplit(mixed, info, startTransaction, finishTransaction,
+                    finishCallback);
+        } else {
+            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;
+            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.
+            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) {
+    }
+
+    @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..79e9cda 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;
@@ -684,6 +686,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 +730,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 +804,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) {
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/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..8e45e7d 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
@@ -34,15 +34,20 @@
 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 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 com.android.wm.shell.fullscreen.FullscreenUnfoldController}.
+ */
 public class UnfoldTransitionHandler implements TransitionHandler, UnfoldListener {
 
     private final ShellUnfoldProgressProvider mUnfoldProgressProvider;
     private final Transitions mTransitions;
+    private final UnfoldBackgroundController mUnfoldBackgroundController;
     private final Executor mExecutor;
     private final TransactionPool mTransactionPool;
 
@@ -51,17 +56,22 @@
     @Nullable
     private IBinder mTransition;
 
-    private final List<TransitionInfo.Change> mAnimatedFullscreenTasks = new ArrayList<>();
+    private final FullscreenUnfoldTaskAnimator mFullscreenAnimator;
 
     public UnfoldTransitionHandler(ShellUnfoldProgressProvider unfoldProgressProvider,
-            TransactionPool transactionPool, Executor executor, Transitions transitions) {
+            FullscreenUnfoldTaskAnimator animator, TransactionPool transactionPool,
+            UnfoldBackgroundController unfoldBackgroundController,
+            Executor executor, Transitions transitions) {
         mUnfoldProgressProvider = unfoldProgressProvider;
+        mFullscreenAnimator = animator;
         mTransactionPool = transactionPool;
+        mUnfoldBackgroundController = unfoldBackgroundController;
         mExecutor = executor;
         mTransitions = transitions;
     }
 
     public void init() {
+        mFullscreenAnimator.init();
         mTransitions.addHandler(this);
         mUnfoldProgressProvider.addListener(mExecutor, this);
     }
@@ -71,40 +81,36 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull TransitionFinishCallback finishCallback) {
-
         if (transition != mTransition) return false;
 
+        mUnfoldBackgroundController.ensureBackground(startTransaction);
         startTransaction.apply();
 
-        mAnimatedFullscreenTasks.clear();
+        mFullscreenAnimator.clearTasks();
         info.getChanges().forEach(change -> {
             final boolean allowedToAnimate = change.getTaskInfo() != null
+                    && change.getTaskInfo().isVisible()
                     && change.getTaskInfo().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
                     && change.getTaskInfo().getActivityType() != ACTIVITY_TYPE_HOME
                     && change.getMode() == TRANSIT_CHANGE;
 
             if (allowedToAnimate) {
-                mAnimatedFullscreenTasks.add(change);
+                mFullscreenAnimator.addTask(change.getTaskInfo(), change.getLeash());
             }
         });
 
+        mFullscreenAnimator.resetAllSurfaces(finishTransaction);
+        mUnfoldBackgroundController.removeBackground(finishTransaction);
         mFinishCallback = finishCallback;
-        mTransition = null;
         return true;
     }
 
     @Override
     public void onStateChangeProgress(float progress) {
-        mAnimatedFullscreenTasks.forEach(change -> {
-            final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
-
-            // 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);
-
-            transaction.apply();
-            mTransactionPool.release(transaction);
-        });
+        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
+        mFullscreenAnimator.applyAnimationProgress(progress, transaction);
+        transaction.apply();
+        mTransactionPool.release(transaction);
     }
 
     @Override
@@ -112,7 +118,8 @@
         if (mFinishCallback != null) {
             mFinishCallback.onTransitionFinished(null, null);
             mFinishCallback = null;
-            mAnimatedFullscreenTasks.clear();
+            mTransition = null;
+            mFullscreenAnimator.clearTasks();
         }
     }
 
@@ -127,4 +134,8 @@
         }
         return null;
     }
+
+    public boolean willHandleTransition() {
+        return mTransition != null;
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
new file mode 100644
index 0000000..6ec5512
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
@@ -0,0 +1,194 @@
+/*
+ * 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.util.MathUtils.lerp;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.animation.RectEvaluator;
+import android.animation.TypeEvaluator;
+import android.app.TaskInfo;
+import android.content.Context;
+import android.graphics.Matrix;
+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;
+
+/**
+ * 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 com.android.wm.shell.fullscreen.FullscreenUnfoldController}. They use independent
+ * instances of FullscreenUnfoldTaskAnimator.
+ */
+public class FullscreenUnfoldTaskAnimator implements
+        DisplayInsetsController.OnInsetsChangedListener {
+
+    private static final float[] FLOAT_9 = new float[9];
+    private static final TypeEvaluator<Rect> RECT_EVALUATOR = new RectEvaluator(new Rect());
+
+    private static final float HORIZONTAL_START_MARGIN = 0.08f;
+    private static final float VERTICAL_START_MARGIN = 0.03f;
+    private static final float END_SCALE = 1f;
+    private static final float START_SCALE = END_SCALE - VERTICAL_START_MARGIN * 2;
+
+    private final SparseArray<AnimationContext> mAnimationContextByTaskId = new SparseArray<>();
+    private final int mExpandedTaskBarHeight;
+    private final float mWindowCornerRadiusPx;
+    private final DisplayInsetsController mDisplayInsetsController;
+
+    private InsetsSource mTaskbarInsetsSource;
+
+    public FullscreenUnfoldTaskAnimator(Context context,
+            DisplayInsetsController displayInsetsController) {
+        mDisplayInsetsController = displayInsetsController;
+        mExpandedTaskBarHeight = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.taskbar_frame_height);
+        mWindowCornerRadiusPx = ScreenDecorationsUtils.getWindowCornerRadius(context);
+    }
+
+    public void init() {
+        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(mTaskbarInsetsSource, context.mTaskInfo);
+        }
+    }
+
+    public boolean hasActiveTasks() {
+        return mAnimationContextByTaskId.size() > 0;
+    }
+
+    public void addTask(TaskInfo taskInfo, SurfaceControl leash) {
+        AnimationContext animationContext = new AnimationContext(leash, mTaskbarInsetsSource,
+                taskInfo);
+        mAnimationContextByTaskId.put(taskInfo.taskId, animationContext);
+    }
+
+    public void onTaskInfoChanged(TaskInfo taskInfo) {
+        AnimationContext animationContext = mAnimationContextByTaskId.get(taskInfo.taskId);
+        if (animationContext != null) {
+            animationContext.update(mTaskbarInsetsSource, taskInfo);
+        }
+    }
+
+    public void removeTask(TaskInfo taskInfo) {
+        mAnimationContextByTaskId.remove(taskInfo.taskId);
+    }
+
+    public void clearTasks() {
+        mAnimationContextByTaskId.clear();
+    }
+
+    public void resetSurface(TaskInfo taskInfo, Transaction transaction) {
+        final AnimationContext context = mAnimationContextByTaskId.get(taskInfo.taskId);
+        if (context != null) {
+            resetSurface(context, transaction);
+        }
+    }
+
+    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)
+            ;
+        }
+    }
+
+    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)
+                .setPosition(context.mLeash,
+                        (float) context.mTaskInfo.positionInParent.x,
+                        (float) context.mTaskInfo.positionInParent.y);
+    }
+
+    private class AnimationContext {
+        final SurfaceControl mLeash;
+        final Rect mStartCropRect = new Rect();
+        final Rect mEndCropRect = new Rect();
+        final Rect mCurrentCropRect = new Rect();
+        final Matrix mMatrix = new Matrix();
+
+        TaskInfo mTaskInfo;
+
+        private AnimationContext(SurfaceControl leash, InsetsSource taskBarInsetsSource,
+                TaskInfo taskInfo) {
+            mLeash = leash;
+            update(taskBarInsetsSource, taskInfo);
+        }
+
+        private void update(InsetsSource taskBarInsetsSource, TaskInfo taskInfo) {
+            mTaskInfo = taskInfo;
+            mStartCropRect.set(mTaskInfo.getConfiguration().windowConfiguration.getBounds());
+
+            if (taskBarInsetsSource != null) {
+                // Only insets the cropping window with task bar when it's expanded
+                if (taskBarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight) {
+                    mStartCropRect.inset(taskBarInsetsSource
+                            .calculateVisibleInsets(mStartCropRect));
+                }
+            }
+
+            mEndCropRect.set(mStartCropRect);
+
+            int horizontalMargin = (int) (mEndCropRect.width() * HORIZONTAL_START_MARGIN);
+            mStartCropRect.left = mEndCropRect.left + horizontalMargin;
+            mStartCropRect.right = mEndCropRect.right - horizontalMargin;
+            int verticalMargin = (int) (mEndCropRect.height() * VERTICAL_START_MARGIN);
+            mStartCropRect.top = mEndCropRect.top + verticalMargin;
+            mStartCropRect.bottom = mEndCropRect.bottom - verticalMargin;
+        }
+    }
+}
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..5dacdbf 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,80 @@
     }
 }
 
+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 {
+        this.isInvisible(component)
+            .then()
+            .invoke("splitAppLayerBoundsBecomesVisible") {
+                val dividerRegion = it.layer(SPLIT_SCREEN_DIVIDER_COMPONENT).visibleRegion.region
+                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)
@@ -135,4 +209,24 @@
         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/SplitScreenHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/SplitScreenHelper.kt
index 0ec9b2d..b902e5d 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,7 +17,6 @@
 package com.android.wm.shell.flicker.helpers
 
 import android.app.Instrumentation
-import android.content.res.Resources
 import com.android.server.wm.traces.common.FlickerComponentName
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.wm.shell.flicker.testapp.Components
@@ -32,11 +31,6 @@
         const val TEST_REPETITIONS = 1
         const val TIMEOUT_MS = 3_000L
 
-        // 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)
-
         fun getPrimary(instrumentation: Instrumentation): SplitScreenHelper =
             SplitScreenHelper(instrumentation,
                 Components.SplitScreenActivity.LABEL,
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/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/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/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..21887c0
--- /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).setAlpha(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/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..abd55dd 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
@@ -76,6 +76,7 @@
     @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;
@@ -101,7 +102,8 @@
         }).when(mMockExecutor).execute(any());
         mPipController = new PipController(mContext, mMockDisplayController,
                 mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
-                mMockPipBoundsState, mMockPipMediaController,
+                mMockPipKeepClearAlgorithm,
+                mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
                 mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTouchHandler,
                 mMockPipTransitionController, mMockWindowManagerShellWrapper,
                 mMockTaskStackListener, mPipParamsChangedForwarder,
@@ -134,7 +136,8 @@
 
         assertNull(PipController.create(spyContext, mMockDisplayController,
                 mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
-                mMockPipBoundsState, mMockPipMediaController,
+                mMockPipKeepClearAlgorithm,
+                mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
                 mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTouchHandler,
                 mMockPipTransitionController, mMockWindowManagerShellWrapper,
                 mMockTaskStackListener, mPipParamsChangedForwarder,
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/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index ffaab65..b526904 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
@@ -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/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..9820b3e 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -598,6 +598,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..7551c3e 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -598,6 +598,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..a1342cd 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -598,6 +598,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..ea0e7a6 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -598,6 +598,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..8a2a2f7 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -598,6 +598,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..a91e9f7 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -598,6 +598,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..eace050 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -598,6 +598,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..e43bd01 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -598,6 +598,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..c20106f 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -598,6 +598,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 e394b03..9b1e0b1 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -598,6 +598,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..9261500 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -598,6 +598,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..a51f2ee 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -598,6 +598,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..f399164 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -598,6 +598,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..941f802 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -598,6 +598,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..c15ea10 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -598,6 +598,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..8a79c60 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -598,6 +598,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 d8537fa..36a1f77 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -598,6 +598,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..8a79c60 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -598,6 +598,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..8a79c60 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -598,6 +598,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..efdfc4f 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -598,6 +598,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..030b9d7 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -598,6 +598,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..71e0b0e 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -598,6 +598,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..ad2601a 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -598,6 +598,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 c31ec30..e728013 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -598,6 +598,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 04549b2..d049b7f 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -598,6 +598,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..0e697f5 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -598,6 +598,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..051347d 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -598,6 +598,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 580af17..0b43037 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -598,6 +598,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..f0e7172 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -598,6 +598,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..374c7d8 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -598,6 +598,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..d038c27 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -598,6 +598,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 ffd276b..ad6f75d 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -598,6 +598,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..1b906f8 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -598,6 +598,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 df2ac82..2b6ea25 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -598,6 +598,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..d4e642e 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -598,6 +598,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..d9e5a39 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -598,6 +598,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..fa84ed5 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -598,6 +598,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..90be29d 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -598,6 +598,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..54abcd4 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -598,6 +598,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..27d3a99 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -598,6 +598,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..3445095 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -598,6 +598,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..49f9ed3 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -598,6 +598,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..8dab685 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -598,6 +598,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..cb8b932 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -598,6 +598,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..e99d556 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -598,6 +598,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 f1ece44..15579a7 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -598,6 +598,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..8a85a21 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -598,6 +598,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..1b7ccf99 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -598,6 +598,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..6e2b7ca 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -598,6 +598,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..828fe45 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -598,6 +598,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..b25a57c 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -598,6 +598,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..12bbcee 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -598,6 +598,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..2b6f62d 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -598,6 +598,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 7998cbd..5aab523 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -599,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..8899644 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -598,6 +598,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..d59ceeb 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -598,6 +598,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..8a48761 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -598,6 +598,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 8bd364f..3ae906d 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -598,6 +598,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..84b0f8bd 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -598,6 +598,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 1eb1b6c..523ec7c 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -598,6 +598,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 d0a848a..d7d723ce 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -598,6 +598,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..1a8bd89 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -598,6 +598,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 d0a848a..d7d723ce 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -598,6 +598,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 4f142a8..9ef302c 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -598,6 +598,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..fd06154 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -598,6 +598,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..347c5c8 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -598,6 +598,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 b0e904c..7394985 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -598,6 +598,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..28824a3 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -598,6 +598,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 b5dfc5f..27fe454 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -598,6 +598,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..768cb1e 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -598,6 +598,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 6e2ea78..2be1898 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -598,6 +598,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 36509e9..b4bd3cb 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -598,6 +598,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..c79a2ed 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -598,6 +598,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..d0855a4 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -598,6 +598,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..fd4022b 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -598,6 +598,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..137a439 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -598,6 +598,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..f8b2304 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -598,6 +598,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..9666bd6 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -598,6 +598,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..c8f396e 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -598,6 +598,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..6c4763e 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -598,6 +598,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 2be2b5c..6be9b8a 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -598,6 +598,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..6f678f4 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -598,6 +598,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 282d05b..03d4559 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -598,6 +598,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..16baf82 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -598,6 +598,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..e2fab12 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -598,6 +598,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/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..4f59ab4 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -422,6 +422,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/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/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/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/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/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 929f6bc..b9153b4 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 2e84ade..c49226a 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 24111a3..d3478d3 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -230,6 +230,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>
@@ -359,6 +360,9 @@
     <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>
@@ -717,7 +721,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>
@@ -985,4 +990,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 3e86b9e..e9ffa0c 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 32c16cb5..0963b76 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 175819f..17be879 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -227,6 +227,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>
@@ -353,6 +354,9 @@
     <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>
@@ -702,7 +706,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>
@@ -964,4 +969,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 fc42bc4d..70bb2d1 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -228,6 +228,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>
@@ -355,6 +356,9 @@
     <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>
@@ -707,7 +711,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>
@@ -971,4 +976,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 638fc34..d75bea4 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 d2ff864..2540356 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 180fd54..d0341d3 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -227,6 +227,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>
@@ -353,6 +354,9 @@
     <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>
@@ -702,7 +706,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>
@@ -964,4 +969,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 4416b2f..b249fac 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 5977679..242cbd3 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 33a247f..c2fb813 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -228,6 +228,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>
@@ -355,6 +356,9 @@
     <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>
@@ -707,7 +711,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>
@@ -971,4 +976,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 39a5c1d..43e3aa2 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 69f0b93..47ed427 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 1a859c4..092485b 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 13030c4..819ea0b 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 21d03dc..bf97682 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 13030c4..819ea0b 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 13030c4..819ea0b 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 48ab4d7..f36bfc1 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 a8b9e3f..c8abf0b 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 6b572e49..2dca610 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 bb6f2eb..c9c7f7c 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 1a1e08a..e1082bf 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 dc9bdd5..73dfbc7 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 58f92ae..41e47dd 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 075c35b..2106bdc 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 6d54797..b3a3c05 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 7512905..24d4967 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 73524d0..29ef79f 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -226,6 +226,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>
@@ -349,6 +350,9 @@
     <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>
@@ -695,7 +699,10 @@
     <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>
+    <!-- no translation found for notification_channel_instant (7556135423486752680) -->
+    <skip />
+    <!-- no translation found for notification_channel_setup (7660580986090760350) -->
+    <skip />
     <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>
@@ -956,4 +963,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 f79ce78..148366c 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 b753035..7ba9a99 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 ef931f8..842aa6a 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 7e26bc6..77ca45f 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -227,6 +227,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>
@@ -353,6 +354,9 @@
     <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>
@@ -702,7 +706,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>
@@ -964,4 +969,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 47a0840..4708f98 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 e1e766a..7f53aa8 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 7c41228..c2bf59b 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 19beb13..eb075f2 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 5b2f9d1..dcbd6af 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 d08318b..25a8bee 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -228,6 +228,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>
@@ -355,6 +356,9 @@
     <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>
@@ -707,7 +711,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>
@@ -971,4 +976,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 ac436ac..5414c8d 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 d866989..691ad8d 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 a1ca48a..b0ca261 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 23ae642..381e679 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 d716380..e572397 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 2fc1978..ec1cd02 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 93e683c..55fa0be 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 f7237d4..cc200ce 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 9768859..491cb17 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -228,6 +228,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>
@@ -355,6 +356,9 @@
     <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>
@@ -707,7 +711,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>
@@ -971,4 +976,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 cef9a1d..0e37594 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -227,6 +227,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>
@@ -353,6 +354,9 @@
     <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>
@@ -702,7 +706,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>
@@ -964,4 +969,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 e37639b..b6826af 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 7892ccf..ebf8fd6 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 ec6a573..06ef868 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 95999be..739e0fd 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 80c8d67..1312979 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 d83c827..6ae71c4 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 93774b5..7b4e6458 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -226,6 +226,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>
@@ -349,6 +350,9 @@
     <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>
@@ -695,7 +699,10 @@
     <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>
+    <!-- no translation found for notification_channel_instant (7556135423486752680) -->
+    <skip />
+    <!-- no translation found for notification_channel_setup (7660580986090760350) -->
+    <skip />
     <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>
@@ -956,4 +963,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 f6f5c6b..8712b483 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 29e5a40..c2a29f1 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 ce3cc36..6fe0f69 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 0663056..5f41202 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 7debaca..ce225f1 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -228,6 +228,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>
@@ -353,6 +354,9 @@
     <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>
@@ -705,7 +709,10 @@
     <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>
+    <!-- no translation found for notification_channel_instant (7556135423486752680) -->
+    <skip />
+    <!-- no translation found for notification_channel_setup (7660580986090760350) -->
+    <skip />
     <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>
@@ -970,4 +977,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 448f7f9..8c05911 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 bee70f8..7128bbf 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 448f7f9..8c05911 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 0b274fa..ca47e05 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -227,6 +227,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>
@@ -353,6 +354,9 @@
     <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>
@@ -702,7 +706,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>
@@ -964,4 +969,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 ba04e88..297d810 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -228,6 +228,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>
@@ -355,6 +356,9 @@
     <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>
@@ -707,7 +711,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>
@@ -971,4 +976,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 a96b931..60f50ca 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 3d5b5f3..ddaebb0 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -228,6 +228,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>
@@ -355,6 +356,9 @@
     <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>
@@ -707,7 +711,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>
@@ -971,4 +976,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 2d2de6c..c29674b 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -228,6 +228,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>
@@ -355,6 +356,9 @@
     <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>
@@ -707,7 +711,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>
@@ -971,4 +976,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 9f55455..0bae296 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 3059122..3f86e9e 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -227,6 +227,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>
@@ -353,6 +354,9 @@
     <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>
@@ -702,7 +706,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>
@@ -964,4 +969,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 3229d74..2008e99 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 6153a13..a413c36 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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-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-port/dimens.xml b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
index 2abc9e3..4de7bb7 100644
--- a/packages/SystemUI/res/values-sw720dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
@@ -29,5 +29,11 @@
 
     <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 7c2d165..4cd0905 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 7ef8298..afba454 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 7419e21..51cad22 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 78e1768..bd1cfdb 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 a40be47..69cdbf2 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 f725a5a..8b9c658 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -228,6 +228,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>
@@ -353,6 +354,9 @@
     <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>
@@ -705,7 +709,10 @@
     <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>
+    <!-- no translation found for notification_channel_instant (7556135423486752680) -->
+    <skip />
+    <!-- no translation found for notification_channel_setup (7660580986090760350) -->
+    <skip />
     <string name="notification_channel_storage" msgid="2720725707628094977">"Пам’ять"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Поради"</string>
     <string name="instant_apps" msgid="8337185853050247304">"Додатки з миттєвим запуском"</string>
@@ -970,4 +977,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 dbbf50c..874314a 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 0f581b4..95b9157 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 722516d..8ca6ee48 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 1285d58..3021eb2 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 2109c8e..72212e3 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 01df07f..baf6f6d 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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 0f78a1c..8ad5a45 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -226,6 +226,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>
@@ -351,6 +352,9 @@
     <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>
@@ -697,7 +701,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>
@@ -957,4 +962,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/config.xml b/packages/SystemUI/res/values/config.xml
index ed3a825..5cb7d46 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)  -->
@@ -625,11 +628,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. -->
@@ -693,7 +696,7 @@
     <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>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 4066499..bfd76c5 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -48,7 +48,50 @@
     <!-- 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>
+
+    <!-- stretch @412 dp -->
+    <dimen name="navigation_edge_stretch_threshold">412dp</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_left_corners">30dp</dimen>
+    <dimen name="navigation_edge_stretch_right_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>
@@ -1464,4 +1507,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 ca60171..6f33986 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -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] -->
@@ -911,6 +913,17 @@
     <!-- 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>
 
@@ -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] -->
@@ -2544,4 +2559,18 @@
     =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>
+
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 0c25f54..8b2481c 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -1196,4 +1196,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/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/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/system/RemoteAnimationAdapterCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java
index 618d2d2..76a09b3 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
@@ -137,6 +137,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 +175,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;
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..4ce110b 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,10 @@
         // 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());
+        t.setPosition(leash, change.getStartAbsBounds().left - info.getRootOffset().x,
+                change.getStartAbsBounds().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 +183,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 +255,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..e9ac261 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());
             }
@@ -222,12 +225,13 @@
         private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null;
         private PictureInPictureSurfaceTransaction mPipTransaction = null;
         private IBinder mTransition = null;
+        private boolean mKeyguardLocked = false;
 
         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,6 +244,7 @@
             mRecentsTask = recentsTask;
             mLeashMap = leashMap;
             mTransition = transition;
+            mKeyguardLocked = keyguardLocked;
         }
 
         @SuppressLint("NewApi")
@@ -374,6 +379,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 +392,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/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/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/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/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/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/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..3dd4386 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayNotificationCountProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayNotificationCountProvider.java
@@ -37,7 +37,7 @@
 
 /***
  * {@link DreamOverlayNotificationCountProvider} provides the current notification count to
- * registered callbacks.
+ * registered callbacks. Ongoing notifications are not included in the count.
  */
 @SysUISingleton
 public class DreamOverlayNotificationCountProvider
@@ -49,6 +49,10 @@
         @Override
         public void onNotificationPosted(
                 StatusBarNotification sbn, NotificationListenerService.RankingMap rankingMap) {
+            if (sbn.isOngoing()) {
+                // Don't count ongoing notifications.
+                return;
+            }
             mNotificationKeys.add(sbn.getKey());
             reportNotificationCountChanged();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
index a83e006df..7666eb8 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;
@@ -90,12 +90,12 @@
 
     private static class SmartSpaceComplicationViewHolder implements ViewHolder {
         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;
         }
@@ -120,12 +120,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/DreamWeatherComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java
index f5c5a43..3d1bc59 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.DreamWeatherComplicationComponent.DreamWeatherComplicationModule.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,6 +33,7 @@
 import com.android.systemui.R;
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent;
+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;
@@ -132,15 +135,21 @@
      */
     static class DreamWeatherViewController extends ViewController<TextView> {
         private final LockscreenSmartspaceController mSmartSpaceController;
+        private final ActivityStarter mActivityStarter;
+        private final String mSmartspaceTrampolineActivityComponent;
         private SmartspaceTargetListener mSmartspaceTargetListener;
 
         @Inject
         DreamWeatherViewController(
                 @Named(DREAM_WEATHER_COMPLICATION_VIEW) TextView view,
+                @Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT) String smartspaceTrampoline,
+                ActivityStarter activityStarter,
                 LockscreenSmartspaceController smartspaceController
         ) {
             super(view);
+            mActivityStarter = activityStarter;
             mSmartSpaceController = smartspaceController;
+            mSmartspaceTrampolineActivityComponent = smartspaceTrampoline;
         }
 
         @Override
@@ -172,6 +181,15 @@
                                                 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);
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..a1660f2 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
@@ -19,6 +19,7 @@
 
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
+import android.content.Context;
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 import android.widget.TextView;
@@ -76,6 +77,7 @@
         String DREAM_WEATHER_COMPLICATION_VIEW = "weather_complication_view";
         String DREAM_WEATHER_COMPLICATION_LAYOUT_PARAMS =
                 "weather_complication_layout_params";
+        String SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT = "smartspace_trampoline_activity";
         // Order weight of insert into parent container
         int INSERT_ORDER_WEIGHT = 1;
 
@@ -106,5 +108,15 @@
                     ComplicationLayoutParams.DIRECTION_END,
                     INSERT_ORDER_WEIGHT);
         }
+
+        /**
+         * Provides the smartspace trampoline activity component.
+         */
+        @Provides
+        @DreamWeatherComplicationScope
+        @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..cd23f14 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,14 @@
 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.qualifiers.Main;
 import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule;
 
+import javax.inject.Named;
+
 import dagger.Module;
 import dagger.Provides;
 
@@ -34,6 +38,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 +49,19 @@
     static DreamBackend providesDreamBackend(Context context) {
         return DreamBackend.getInstance(context);
     }
+
+    /** */
+    @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 98%
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..da2cf84 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamsSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
@@ -46,7 +46,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 +58,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
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/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index afa7d5e..55bbcb6 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -158,12 +158,21 @@
     // 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", false);
+
     // 1200 - predictive back
     @Keep
     public static final SysPropBooleanFlag WM_ENABLE_PREDICTIVE_BACK = new SysPropBooleanFlag(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index e379d76..7e3d253 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;
@@ -921,6 +922,8 @@
                     }
 
                     final RemoteAnimationTarget primary = apps[0];
+                    final boolean isDream = (apps[0].taskInfo.topActivityType
+                            == WindowConfiguration.ACTIVITY_TYPE_DREAM);
 
                     final SyncRtSurfaceTransactionApplier applier =
                             new SyncRtSurfaceTransactionApplier(
@@ -942,20 +945,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
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 972e93b..d8bde55 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 360f865..b2ab12a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -215,5 +215,8 @@
     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
 )
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 8558859..b552d9f 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/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/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index aa38b78..47b1bff 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -215,8 +215,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;
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..56ad19a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
@@ -0,0 +1,340 @@
+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 backgroundDragCornerRadius = 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())
+
+    /**
+     * Canvas vertical translation. How far up/down the arrow and background appear relative to the
+     * canvas.
+     */
+    private var verticalTranslation: AnimatedFloat =
+        AnimatedFloat("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)
+        }
+
+        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 (horizontalTranslation.animation.isRunning) {
+            horizontalTranslation.animation.addEndListener(endListener)
+            true
+        } else {
+            endListener.runNow()
+            false
+        }
+    }
+
+    fun setStretch(
+        arrowLengthStretch: Float,
+        arrowHeightStretch: Float,
+        backgroundWidthStretch: Float,
+        backgroundHeightStretch: Float,
+        backgroundEdgeCornerRadiusStretch: Float,
+        backgroundDragCornerRadiusStretch: Float,
+        horizontalTranslationStretch: Float
+    ) {
+        arrowLength.stretchTo(arrowLengthStretch)
+        arrowHeight.stretchTo(arrowHeightStretch)
+        backgroundWidth.stretchTo(backgroundWidthStretch)
+        backgroundHeight.stretchTo(backgroundHeightStretch)
+        backgroundEdgeCornerRadius.stretchTo(backgroundEdgeCornerRadiusStretch)
+        backgroundDragCornerRadius.stretchTo(backgroundDragCornerRadiusStretch)
+        horizontalTranslation.stretchTo(horizontalTranslationStretch)
+    }
+
+    fun resetStretch() {
+        setStretch(0f, 0f, 0f, 0f, 0f, 0f, 0f)
+    }
+
+    /**
+     * Updates resting arrow and background size not accounting for stretch
+     */
+    internal fun updateRestingArrowDimens(
+        backgroundWidth: Float,
+        backgroundHeight: Float,
+        backgroundEdgeCornerRadius: Float,
+        backgroundDragCornerRadius: Float,
+        arrowLength: Float,
+        arrowHeight: Float,
+        horizontalTranslation: Float,
+        animate: Boolean
+    ) {
+        this.arrowLength.updateRestingPosition(arrowLength, animate)
+        this.arrowHeight.updateRestingPosition(arrowHeight, animate)
+        this.backgroundWidth.updateRestingPosition(backgroundWidth, animate)
+        this.backgroundHeight.updateRestingPosition(backgroundHeight, animate)
+        this.backgroundEdgeCornerRadius.updateRestingPosition(backgroundEdgeCornerRadius, animate)
+        this.backgroundDragCornerRadius.updateRestingPosition(backgroundDragCornerRadius, animate)
+        this.horizontalTranslation.updateRestingPosition(horizontalTranslation, 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 = backgroundDragCornerRadius.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)
+    }
+}
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..100411b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -0,0 +1,735 @@
+/*
+ * 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.AccelerateInterpolator
+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_PAUSE_DURATION_MS = 50L
+
+/**
+ * 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 ACCELERATE_INTERPOLATOR = AccelerateInterpolator(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 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
+    }
+
+    /**
+     * Wrapper around OnAnimationEndListener which runs the given runnable after a delay. The
+     * runnable is not called if the animation is cancelled
+     */
+    class DelayedOnAnimationEndListener(
+        private val handler: Handler,
+        private val runnable: Runnable,
+        private val delay: Long
+    ) : DynamicAnimation.OnAnimationEndListener {
+
+        override fun onAnimationEnd(
+            animation: DynamicAnimation<*>,
+            canceled: Boolean,
+            value: Float,
+            velocity: Float
+        ) {
+            animation.removeEndListener(this)
+            if (!canceled) {
+                handler.postDelayed(runnable, delay)
+            }
+        }
+
+        fun runNow() {
+            runnable.run()
+        }
+    }
+
+    private val setCommittedEndListener =
+        DelayedOnAnimationEndListener(
+            mainHandler,
+            { updateArrowState(GestureState.COMMITTED) },
+            delay = FLING_PAUSE_DURATION_MS
+        )
+
+    private val setGoneEndListener =
+        DelayedOnAnimationEndListener(
+            mainHandler,
+            {
+                cancelFailsafe()
+                updateArrowState(GestureState.GONE)
+            },
+            delay = 0
+        )
+
+    // Vibration
+    private var vibrationTime: Long = 0
+
+    // Minimum size of the screen's width or height
+    private var screenSize = 0
+
+    /**
+     * Used for initialization and configuration changes
+     */
+    private fun updateConfiguration() {
+        params.update(resources)
+        initializeBackAnimation()
+        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,
+            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
+
+                // 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) {
+        when (currentState) {
+            GestureState.GONE, GestureState.FLUNG, GestureState.COMMITTED, GestureState.CANCELLED ->
+                return
+        }
+
+        updateArrowState(
+            when {
+                // Check if we should transition from ENTRY to ACTIVE
+                currentState == GestureState.ENTRY && xTranslation > params.swipeTriggerThreshold ->
+                    GestureState.ACTIVE
+
+                // Abort if we had continuous motion toward the edge for a while, OR the direction
+                // in Y is bigger than X * 2
+                currentState == GestureState.ACTIVE &&
+                        ((totalTouchDelta < 0 && -totalTouchDelta > params.minDeltaForSwitch) ||
+                                (yTranslation > xTranslation * 2)) ->
+                    GestureState.INACTIVE
+
+                //  Re-activate if we had continuous motion away from the edge for a while
+                currentState == GestureState.INACTIVE &&
+                        (totalTouchDelta > 0 && totalTouchDelta > params.minDeltaForSwitch) ->
+                    GestureState.ACTIVE
+
+                // By default assume the current direction is kept
+                else -> currentState
+            }
+        )
+    }
+
+    private fun handleMoveEvent(event: MotionEvent) {
+        when (currentState) {
+            GestureState.GONE, GestureState.FLUNG, GestureState.COMMITTED,
+            GestureState.CANCELLED -> 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 -> setActiveStretch(fullScreenStretchProgress(xTranslation))
+            GestureState.ENTRY ->
+                setEntryStretch(preThresholdStretchProgress(xTranslation))
+            GestureState.INACTIVE -> mView.resetStretch()
+        }
+
+        // set y translation
+        setVerticalTranslation(yOffset)
+    }
+
+    fun setVerticalTranslation(yOffset: Float) {
+        val yTranslation = abs(yOffset)
+        val maxYOffset = (mView.height / 2) - (params.entryBackgroundHeight / 2)
+        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)
+     */
+    fun fullScreenStretchProgress(xTranslation: Float): Float {
+        return saturate(
+            (xTranslation - params.swipeTriggerThreshold) /
+                    (min(
+                        params.fullyStretchedThreshold,
+                        screenSize.toFloat()
+                    ) - params.swipeTriggerThreshold)
+        )
+    }
+
+    /**
+     * Tracks the relative position of the drag from the entry until the threshold where the arrow
+     * activates (between 0.0 - 1.0f)
+     */
+    fun preThresholdStretchProgress(xTranslation: Float): Float {
+        return saturate(xTranslation / params.swipeTriggerThreshold)
+    }
+
+    fun setActiveStretch(progress: Float) {
+        val stretch = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress)
+        mView.setStretch(
+            arrowLengthStretch = stretch * (params.stretchedArrowLength - params.activeArrowLength),
+            arrowHeightStretch = stretch * (params.stretchedArrowHeight - params.activeArrowHeight),
+            backgroundWidthStretch =
+                stretch * (params.stretchBackgroundWidth - params.activeBackgroundWidth),
+            backgroundHeightStretch =
+                stretch * (params.stretchBackgroundHeight - params.activeBackgroundHeight),
+            backgroundEdgeCornerRadiusStretch =
+                stretch * (params.stretchEdgeCorners - params.activeEdgeCorners),
+            backgroundDragCornerRadiusStretch =
+                stretch * (params.stretchFarCorners - params.activeFarCorners),
+            horizontalTranslationStretch = stretch * (params.stretchMargin - params.activeMargin)
+        )
+    }
+
+    fun setEntryStretch(progress: Float) {
+        val bgStretch = ACCELERATE_INTERPOLATOR.getInterpolation(progress)
+        val arrowStretch = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress)
+        mView.setStretch(
+            arrowLengthStretch =
+                arrowStretch * (params.activeArrowLength - params.entryArrowLength),
+            arrowHeightStretch =
+                arrowStretch * (params.activeArrowHeight - params.entryArrowHeight),
+            backgroundWidthStretch =
+                bgStretch * (params.preThresholdBackgroundWidth - params.entryBackgroundWidth),
+            backgroundHeightStretch =
+                bgStretch * (params.preThresholdBackgroundHeight - params.entryBackgroundHeight),
+            backgroundEdgeCornerRadiusStretch =
+                bgStretch * (params.preThresholdEdgeCorners - params.entryEdgeCorners),
+            backgroundDragCornerRadiusStretch =
+                bgStretch * (params.preThresholdFarCorners - params.entryFarCorners),
+            horizontalTranslationStretch =
+                bgStretch * (params.preThresholdMargin - params.entryMargin)
+        )
+    }
+
+    fun setBackAnimation(backAnimation: BackAnimation?) {
+        this.backAnimation = backAnimation
+        initializeBackAnimation()
+    }
+
+    private fun initializeBackAnimation() {
+        backAnimation?.setSwipeThresholds(
+            params.swipeTriggerThreshold,
+            params.swipeProgressThreshold
+        )
+    }
+
+    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 = Math.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)
+        screenSize = Math.min(displaySize.x, displaySize.y)
+    }
+
+    /**
+     * Updates resting arrow and background size not accounting for stretch
+     */
+    private fun updateRestingArrowDimens(animated: Boolean, currentState: GestureState) {
+        mView.updateRestingArrowDimens(
+            backgroundWidth =
+                when (currentState) {
+                    GestureState.GONE, GestureState.ENTRY -> params.entryBackgroundWidth
+                    else -> params.activeBackgroundWidth
+                },
+            backgroundHeight =
+                when (currentState) {
+                    GestureState.GONE, GestureState.ENTRY -> params.entryBackgroundHeight
+                    else -> params.activeBackgroundHeight
+                },
+            backgroundEdgeCornerRadius =
+                when (currentState) {
+                    GestureState.GONE, GestureState.ENTRY, GestureState.INACTIVE ->
+                        params.entryEdgeCorners
+                    else ->
+                        params.activeEdgeCorners
+                },
+            backgroundDragCornerRadius =
+                when (currentState) {
+                    GestureState.GONE, GestureState.ENTRY -> params.entryFarCorners
+                    else -> params.activeFarCorners
+                },
+            arrowLength =
+                when (currentState) {
+                    GestureState.ACTIVE, GestureState.INACTIVE, GestureState.COMMITTED,
+                    GestureState.FLUNG -> params.activeArrowLength
+                    GestureState.CANCELLED -> params.cancelledArrowLength
+                    GestureState.GONE, GestureState.ENTRY -> params.entryArrowLength
+                },
+            arrowHeight =
+                when (currentState) {
+                    GestureState.ACTIVE, GestureState.INACTIVE, GestureState.COMMITTED,
+                    GestureState.FLUNG -> params.activeArrowHeight
+                    GestureState.CANCELLED -> params.cancelledArrowHeight
+                    GestureState.GONE, GestureState.ENTRY -> params.entryArrowHeight
+                },
+            horizontalTranslation =
+                when (currentState) {
+                    GestureState.GONE -> -params.activeBackgroundWidth
+                    // Position the cancelled/committed arrow slightly further off the screen so we
+                    // do not see part of it bouncing
+                    GestureState.CANCELLED, GestureState.COMMITTED ->
+                        -params.activeBackgroundWidth * 1.5f
+                    GestureState.FLUNG -> params.stretchMargin
+                    GestureState.ACTIVE -> params.activeMargin
+                    GestureState.ENTRY, GestureState.INACTIVE -> params.entryMargin
+                },
+            animate = animated
+        )
+        if (animated) {
+            when (currentState) {
+                GestureState.ENTRY, GestureState.ACTIVE, GestureState.FLUNG ->
+                    mView.setArrowStiffness(ARROW_APPEAR_STIFFNESS, ARROW_APPEAR_DAMPING_RATIO)
+                else ->
+                    mView.setArrowStiffness(
+                        ARROW_DISAPPEAR_STIFFNESS, ARROW_DISAPPEAR_DAMPING_RATIO)
+            }
+        }
+    }
+
+    /**
+     * 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
+        mView.visibility = if (currentState == GestureState.GONE) View.GONE else 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..d41837b 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;
@@ -182,6 +184,7 @@
     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;
@@ -199,6 +202,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;
@@ -230,6 +234,7 @@
     private boolean mIsBackGestureAllowed;
     private boolean mGestureBlockingActivityRunning;
     private boolean mIsInPipMode;
+    private boolean mIsPredictiveBackAnimEnabled;
 
     private InputMonitor mInputMonitor;
     private InputChannelCompat.InputEventReceiver mInputEventReceiver;
@@ -298,12 +303,22 @@
     };
 
 
-    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,
+            FalsingManager falsingManager,
+            LatencyTracker latencyTracker,
+            FeatureFlags featureFlags) {
         super(broadcastDispatcher);
         mContext = context;
         mDisplayId = context.getDisplayId();
@@ -313,11 +328,13 @@
         mPluginManager = pluginManager;
         mProtoTracer = protoTracer;
         mNavigationModeController = navigationModeController;
+        mBackPanelControllerFactory = backPanelControllerFactory;
         mViewConfiguration = viewConfiguration;
         mWindowManager = windowManager;
         mWindowManagerService = windowManagerService;
         mFalsingManager = falsingManager;
         mLatencyTracker = latencyTracker;
+        mFeatureFlags = featureFlags;
         ComponentName recentsComponentName = ComponentName.unflattenFromString(
                 context.getString(com.android.internal.R.string.config_recentsComponentName));
         if (recentsComponentName != null) {
@@ -507,8 +524,9 @@
                     Choreographer.getInstance(), this::onInputEvent);
 
             // Add a nav bar panel window
-            setEdgeBackPlugin(
-                    new NavigationBarEdgePanel(mContext, mBackAnimation, mLatencyTracker));
+            mIsPredictiveBackAnimEnabled =
+                    mFeatureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_ANIM);
+            resetEdgeBackPlugin();
             mPluginManager.addPluginListener(
                     this, NavigationEdgeBackPlugin.class, /*allowMultiple=*/ false);
         }
@@ -523,7 +541,17 @@
 
     @Override
     public void onPluginDisconnected(NavigationEdgeBackPlugin plugin) {
-        setEdgeBackPlugin(new NavigationBarEdgePanel(mContext, mBackAnimation, mLatencyTracker));
+        resetEdgeBackPlugin();
+    }
+
+    private void resetEdgeBackPlugin() {
+        if (mIsPredictiveBackAnimEnabled) {
+            setEdgeBackPlugin(
+                    mBackPanelControllerFactory.create(mContext, mBackAnimation));
+        } else {
+            setEdgeBackPlugin(
+                    new NavigationBarEdgePanel(mContext, mBackAnimation, mLatencyTracker));
+        }
     }
 
     private void setEdgeBackPlugin(NavigationEdgeBackPlugin edgeBackPlugin) {
@@ -948,8 +976,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 +999,29 @@
         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 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,
+                       FalsingManager falsingManager,
+                       LatencyTracker latencyTracker,
+                       FeatureFlags featureFlags) {
             mOverviewProxyService = overviewProxyService;
             mSysUiState = sysUiState;
             mPluginManager = pluginManager;
@@ -988,19 +1029,33 @@
             mBroadcastDispatcher = broadcastDispatcher;
             mProtoTracer = protoTracer;
             mNavigationModeController = navigationModeController;
+            mBackPanelControllerFactory = backPanelControllerFactory;
             mViewConfiguration = viewConfiguration;
             mWindowManager = windowManager;
             mWindowManagerService = windowManagerService;
             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,
+                    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..51566b0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -0,0 +1,139 @@
+package com.android.systemui.navigationbar.gestural
+
+import android.content.res.Resources
+import com.android.systemui.R
+
+data class EdgePanelParams(private var resources: Resources) {
+    var arrowThickness: Float = 0f
+        private set
+    var entryArrowLength: Float = 0f
+        private set
+    var entryArrowHeight: Float = 0f
+        private set
+    var activeArrowLength: Float = 0f
+        private set
+    var activeArrowHeight: Float = 0f
+        private set
+    var stretchedArrowLength: Float = 0f
+        private set
+    var stretchedArrowHeight: Float = 0f
+        private set
+    var cancelledArrowLength: Float = 0f
+        private set
+    var cancelledArrowHeight: Float = 0f
+        private set
+    var entryMargin: Float = 0f
+        private set
+    var entryBackgroundWidth: Float = 0f
+        private set
+    var entryBackgroundHeight: Float = 0f
+        private set
+    var entryEdgeCorners: Float = 0f
+        private set
+    var entryFarCorners: Float = 0f
+        private set
+    var preThresholdMargin: Float = 0f
+        private set
+    var preThresholdBackgroundWidth: Float = 0f
+        private set
+    var preThresholdBackgroundHeight: Float = 0f
+        private set
+    var preThresholdEdgeCorners: Float = 0f
+        private set
+    var preThresholdFarCorners: Float = 0f
+        private set
+    var activeMargin: Float = 0f
+        private set
+    var activeBackgroundWidth: Float = 0f
+        private set
+    var activeBackgroundHeight: Float = 0f
+        private set
+    var activeEdgeCorners: Float = 0f
+        private set
+    var activeFarCorners: Float = 0f
+        private set
+    var fullyStretchedThreshold: Float = 0f
+        private set
+    var stretchMargin: Float = 0f
+        private set
+    var stretchBackgroundWidth: Float = 0f
+        private set
+    var stretchBackgroundHeight: Float = 0f
+        private set
+    var stretchEdgeCorners: Float = 0f
+        private set
+    var stretchFarCorners: Float = 0f
+        private set
+
+    // 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)
+        entryArrowLength = getDimen(R.dimen.navigation_edge_entry_arrow_length)
+        entryArrowHeight = getDimen(R.dimen.navigation_edge_entry_arrow_height)
+        activeArrowLength = getDimen(R.dimen.navigation_edge_active_arrow_length)
+        activeArrowHeight = getDimen(R.dimen.navigation_edge_active_arrow_height)
+        stretchedArrowLength = getDimen(R.dimen.navigation_edge_stretched_arrow_length)
+        stretchedArrowHeight = getDimen(R.dimen.navigation_edge_stretched_arrow_height)
+        cancelledArrowLength = getDimen(R.dimen.navigation_edge_cancelled_arrow_length)
+        cancelledArrowHeight = getDimen(R.dimen.navigation_edge_cancelled_arrow_height)
+        entryMargin = getDimen(R.dimen.navigation_edge_entry_margin)
+        entryBackgroundWidth = getDimen(R.dimen.navigation_edge_entry_background_width)
+        entryBackgroundHeight = getDimen(R.dimen.navigation_edge_entry_background_height)
+        entryEdgeCorners = getDimen(R.dimen.navigation_edge_entry_edge_corners)
+        entryFarCorners = getDimen(R.dimen.navigation_edge_entry_far_corners)
+        preThresholdMargin = getDimen(R.dimen.navigation_edge_pre_threshold_margin)
+        preThresholdBackgroundWidth =
+            getDimen(R.dimen.navigation_edge_pre_threshold_background_width)
+        preThresholdBackgroundHeight =
+            getDimen(R.dimen.navigation_edge_pre_threshold_background_height)
+        preThresholdEdgeCorners = getDimen(R.dimen.navigation_edge_pre_threshold_edge_corners)
+        preThresholdFarCorners = getDimen(R.dimen.navigation_edge_pre_threshold_far_corners)
+        activeMargin = getDimen(R.dimen.navigation_edge_active_margin)
+        activeBackgroundWidth = getDimen(R.dimen.navigation_edge_active_background_width)
+        activeBackgroundHeight = getDimen(R.dimen.navigation_edge_active_background_height)
+        activeEdgeCorners = getDimen(R.dimen.navigation_edge_active_edge_corners)
+        activeFarCorners = getDimen(R.dimen.navigation_edge_active_far_corners)
+        fullyStretchedThreshold = getDimen(R.dimen.navigation_edge_stretch_threshold)
+        stretchMargin = getDimen(R.dimen.navigation_edge_stretch_margin)
+        stretchBackgroundWidth = getDimen(R.dimen.navigation_edge_stretch_background_width)
+        stretchBackgroundHeight = getDimen(R.dimen.navigation_edge_stretch_background_height)
+        stretchEdgeCorners = getDimen(R.dimen.navigation_edge_stretch_left_corners)
+        stretchFarCorners = getDimen(R.dimen.navigation_edge_stretch_right_corners)
+        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)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index d03a2e5..c3d7808 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -644,10 +644,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);
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..da5202b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -19,9 +19,7 @@
 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 +132,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 +144,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();
     }
 
@@ -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/DreamTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java
new file mode 100644
index 0000000..22e725b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java
@@ -0,0 +1,244 @@
+/*
+ * 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";
+    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_screen_saver);
+    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 final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            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);
+            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 = mIcon;
+
+        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/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/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 9768e70..da943d2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -736,7 +736,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/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/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/collection/ListDumper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
index 6be8a49..e98ae8d 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
@@ -121,6 +121,12 @@
             sb.append(" (parent=")
                     .append(entry.getParent() != null ? entry.getParent().getKey() : null)
                     .append(")");
+
+            NotificationEntry notifEntry = entry.getRepresentativeEntry();
+            if (notifEntry != null) {
+                sb.append(" rank=")
+                        .append(notifEntry.getRanking().getRank());
+            }
         }
 
         if (entry.getSection() != null) {
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..410593a 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
@@ -609,12 +609,21 @@
         }
         checkForReentrantCall();
 
+        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);
+        }
+
         if (!entry.mLifetimeExtenders.remove(extender)) {
             throw mEulogizer.record(new IllegalStateException(
-                    String.format(
-                            "Cannot end lifetime extension for extender \"%s\" (%s)",
-                            extender.getName(),
-                            extender)));
+                    String.format("Cannot end lifetime extension for extender \"%s\""
+                                    + " of entry %s (collection entry is %s)",
+                            extender.getName(), logKey, collectionEntryIs)));
         }
 
         mLogger.logLifetimeExtensionEnded(
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/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/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/notifcollection/NotifCollectionLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt
index 7e79367..ac0b1ee 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
@@ -248,6 +248,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
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..a063dbd 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
@@ -194,6 +194,10 @@
             return false;
         }
 
+        if (!canAlertHeadsUpCommon(entry)) {
+            return false;
+        }
+
         if (!canAlertAwakeCommon(entry)) {
             return false;
         }
@@ -267,6 +271,11 @@
             return false;
         }
 
+        if (!canAlertHeadsUpCommon(entry)) {
+            mLogger.logNoPulsingNoAlert(sbn);
+            return false;
+        }
+
         if (entry.shouldSuppressAmbient()) {
             mLogger.logNoPulsingNoAmbientEffect(sbn);
             return false;
@@ -294,12 +303,6 @@
             return false;
         }
 
-        // Don't alert notifications that are suppressed due to group alert behavior
-        if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) {
-            mLogger.logNoAlertingGroupAlertBehavior(sbn);
-            return false;
-        }
-
         for (int i = 0; i < mSuppressors.size(); i++) {
             if (mSuppressors.get(i).suppressInterruptions(entry)) {
                 mLogger.logNoAlertingSuppressedBy(sbn, mSuppressors.get(i), /* awake */ false);
@@ -307,13 +310,31 @@
             }
         }
 
-        if (entry.hasJustLaunchedFullScreenIntent()) {
-            mLogger.logNoAlertingRecentFullscreen(sbn);
+        if (mKeyguardNotificationVisibilityProvider.shouldHideNotification(entry)) {
+            mLogger.keyguardHideNotification(entry.getKey());
             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(sbn);
+            return false;
+        }
+
+        if (entry.hasJustLaunchedFullScreenIntent()) {
+            mLogger.logNoAlertingRecentFullscreen(sbn);
             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 1cae60b..2bef4de 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
@@ -2075,6 +2075,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/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index d71e7680..e042e9c 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;
@@ -477,14 +476,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/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index ba57d57..3681222 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
@@ -4531,31 +4531,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
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 485c018..a9692a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -443,6 +443,7 @@
      */
     protected int mState; // TODO: remove this. Just use StatusBarStateController
     protected boolean mBouncerShowing;
+    private boolean mBouncerShowingOverDream;
 
     private final PhoneStatusBarPolicy mIconPolicy;
 
@@ -2511,6 +2512,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)) {
@@ -3318,9 +3325,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();
@@ -3342,7 +3353,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();
             }
@@ -3555,6 +3567,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
@@ -4198,7 +4221,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..fd307df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -1195,10 +1195,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/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/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 82ca842..fc0c4d6 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
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 11e9ae9..e3c070e 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/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/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/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/condition/Monitor.java b/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java
index d3c6e9a..313d56f 100644
--- a/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/condition/Monitor.java
@@ -18,6 +18,7 @@
 
 import android.util.Log;
 
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.policy.CallbackController;
 
 import org.jetbrains.annotations.NotNull;
@@ -60,21 +61,13 @@
     };
 
     @Inject
-    public Monitor(Executor executor, Set<Condition> conditions, Set<Callback> callbacks) {
+    public Monitor(@Main Executor executor, Set<Condition> conditions) {
         mConditions = new HashSet<>();
         mExecutor = executor;
 
         if (conditions != null) {
             mConditions.addAll(conditions);
         }
-
-        if (callbacks == null) {
-            return;
-        }
-
-        for (Callback callback : callbacks) {
-            addCallbackLocked(callback);
-        }
     }
 
     private void updateConditionMetState() {
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
index fc67973..8e739d6 100644
--- a/packages/SystemUI/src/com/android/systemui/util/condition/dagger/MonitorComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/util/condition/dagger/MonitorComponent.java
@@ -34,8 +34,7 @@
      */
     @Subcomponent.Factory
     interface Factory {
-        MonitorComponent create(@BindsInstance Set<Condition> conditions,
-                @BindsInstance Set<Monitor.Callback> callbacks);
+        MonitorComponent create(@BindsInstance Set<Condition> conditions);
     }
 
     /**
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/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/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/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
index ed1cf69..cefdf28 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
@@ -27,7 +27,7 @@
 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 org.junit.Before;
@@ -47,7 +47,7 @@
     private Context mContext;
 
     @Mock
-    private DreamsSmartspaceController mSmartspaceController;
+    private DreamSmartspaceController mSmartspaceController;
 
     @Mock
     private DreamOverlayStateController mDreamOverlayStateController;
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/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 18ee791..11fe87d 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
@@ -57,6 +66,8 @@
 private const val SESSION_KEY = "SESSION_KEY"
 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)
@@ -80,6 +91,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()
@@ -88,12 +105,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
@@ -116,6 +136,7 @@
                 token = session.sessionToken)
         whenever(controllerFactory.create(session.sessionToken))
                 .thenReturn(controller)
+        setupLeAudioConfiguration(false)
     }
 
     @After
@@ -459,7 +480,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
@@ -474,12 +496,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/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/DreamTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
new file mode 100644
index 0000000..c2a41d5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
@@ -0,0 +1,241 @@
+/*
+ * 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.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+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.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.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());
+    }
+
+    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/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..2f0f0a0 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
@@ -39,6 +40,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Spy
 import org.mockito.Mockito
 import org.mockito.Mockito.`when`
 import org.mockito.Mockito.verify
@@ -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,8 @@
     @Mock
     private lateinit var session: SmartspaceSession
 
+    private lateinit var controller: DreamSmartspaceController
+
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
@@ -90,6 +94,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 +104,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)
 
@@ -130,8 +133,7 @@
      * 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 {
+    private class TestView(context: Context?) : View(context), SmartspaceView {
         override fun registerDataProvider(plugin: BcSmartspaceDataPlugin?) {}
 
         override fun setPrimaryTextColor(color: Int) {}
@@ -160,11 +162,6 @@
      */
     @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,16 @@
 
         verify(session).close()
     }
+
+    /**
+     * Ensures setIsDreaming(true) is called when the view is built.
+     */
+    @Test
+    fun testSetIsDreamingTrueOnViewCreate() {
+        `when`(precondition.conditionsMet()).thenReturn(true)
+
+        controller.buildAndConnectView(Mockito.mock(ViewGroup::class.java))
+
+        verify(smartspaceView).setIsDreaming(true)
+    }
 }
\ No newline at end of file
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/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/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index 8a2dc26..7b40ba8 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;
@@ -431,6 +432,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
@@ -497,16 +509,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/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/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/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..7589616 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,7 @@
         mCondition3 = spy(new FakeCondition());
         mConditions = new HashSet<>(Arrays.asList(mCondition1, mCondition2, mCondition3));
 
-        mConditionMonitor = new Monitor(mExecutor, mConditions, null /*callbacks*/);
+        mConditionMonitor = new Monitor(mExecutor, mConditions);
     }
 
     @Test
@@ -76,8 +76,10 @@
 
         final Monitor monitor = new Monitor(
                 mExecutor,
-                new HashSet<>(Arrays.asList(overridingCondition, regularCondition)),
-                new HashSet<>(Arrays.asList(callback)));
+                new HashSet<>(Arrays.asList(overridingCondition, regularCondition)));
+
+        monitor.addCallback(callback);
+        mExecutor.runAllReady();
 
         when(overridingCondition.isOverridingCondition()).thenReturn(true);
         when(overridingCondition.isConditionMet()).thenReturn(true);
@@ -123,8 +125,9 @@
         final Monitor monitor = new Monitor(
                 mExecutor,
                 new HashSet<>(Arrays.asList(overridingCondition, overridingCondition2,
-                        regularCondition)),
-                new HashSet<>(Arrays.asList(callback)));
+                        regularCondition)));
+        monitor.addCallback(callback);
+        mExecutor.runAllReady();
 
         when(overridingCondition.isOverridingCondition()).thenReturn(true);
         when(overridingCondition.isConditionMet()).thenReturn(true);
@@ -174,8 +177,8 @@
                 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, new HashSet<>(Arrays.asList(condition)));
+        monitor.addCallback(callback1);
 
         final Monitor.Callback callback2 =
                 mock(Monitor.Callback.class);
@@ -186,7 +189,7 @@
 
     @Test
     public void addCallback_noConditions_reportAllConditionsMet() {
-        final Monitor monitor = new Monitor(mExecutor, new HashSet<>(), null /*callbacks*/);
+        final Monitor monitor = new Monitor(mExecutor, new HashSet<>());
         final Monitor.Callback callback = mock(Monitor.Callback.class);
 
         monitor.addCallback(callback);
@@ -196,7 +199,7 @@
 
     @Test
     public void addCallback_withMultipleInstancesOfTheSameCallback_registerOnlyOne() {
-        final Monitor monitor = new Monitor(mExecutor, new HashSet<>(), null /*callbacks*/);
+        final Monitor monitor = new Monitor(mExecutor, new HashSet<>());
         final Monitor.Callback callback = mock(Monitor.Callback.class);
 
         // Adds the same instance multiple times.
@@ -212,8 +215,7 @@
     @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, new HashSet<>(Arrays.asList(condition)));
         final Monitor.Callback callback =
                 mock(Monitor.Callback.class);
         monitor.addCallback(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/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 a2106f9..47a87bf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2291,13 +2291,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;
@@ -2305,33 +2301,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;
@@ -2340,7 +2330,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 =
@@ -2476,7 +2466,7 @@
         }
 
         mInternal = new LocalService();
-        mPendingStartActivityUids = new PendingStartActivityUids(mContext);
+        mPendingStartActivityUids = new PendingStartActivityUids();
         mTraceErrorLogger = new TraceErrorLogger();
         mComponentAliasResolver = new ComponentAliasResolver(this);
     }
@@ -17324,7 +17314,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/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/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..de9102a 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();
@@ -685,9 +695,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 +799,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 +895,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 +1227,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/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/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 7ca09ab..e8a3dcd 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;
@@ -343,6 +342,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);
     }
 
     /**
@@ -391,8 +406,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 3c13abf..c56369e 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -110,6 +110,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;
@@ -4951,6 +4952,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/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index f6748de..47aa587 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -737,7 +737,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 +853,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 +877,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;
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index d6c0ab6..622de57 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -68,6 +68,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 +102,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 +782,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);
             }
         }
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 8192ab2..ff6ec69 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2786,7 +2786,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;
         }
@@ -3000,25 +3000,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());
     }
@@ -4469,12 +4450,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());
     }
 
     /**
@@ -5530,7 +5516,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*/);
         }
@@ -7734,7 +7723,7 @@
         if (isFixedOrientationLetterboxAllowed || mCompatDisplayInsets != null
                 // In fullscreen, can be letterboxed for aspect ratio.
                 || !inMultiWindowMode()) {
-            updateResolvedBoundsHorizontalPosition(newParentConfiguration);
+            updateResolvedBoundsPosition(newParentConfiguration);
         }
 
         if (mVisibleRequested) {
@@ -7837,39 +7826,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.
@@ -7897,6 +7907,10 @@
         return mLetterboxBoundsForFixedOrientationAndAspectRatio != null;
     }
 
+    boolean isAspectRatioApplied() {
+        return mIsAspectRatioApplied;
+    }
+
     /**
      * Whether this activity is eligible for letterbox eduction.
      *
@@ -8068,21 +8082,13 @@
         resolvedBounds.set(containingBounds);
 
         final float letterboxAspectRatioOverride =
-                mLetterboxUiController.getFixedOrientationLetterboxAspectRatio(newParentConfig);
+                mWmService.mLetterboxConfiguration.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(
@@ -8106,10 +8112,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();
@@ -8121,7 +8126,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);
         }
@@ -8255,22 +8260,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) {
@@ -8330,9 +8324,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) {
@@ -8520,7 +8514,7 @@
     private boolean applyAspectRatio(Rect outBounds, Rect containingAppBounds,
             Rect containingBounds) {
         return applyAspectRatio(outBounds, containingAppBounds, containingBounds,
-                0 /* desiredAspectRatio */, false /* fixedOrientationLetterboxed */);
+                0 /* desiredAspectRatio */);
     }
 
     /**
@@ -8531,23 +8525,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;
         }
 
@@ -8646,7 +8635,18 @@
      * Returns the min aspect ratio of this activity.
      */
     private float getMinAspectRatio() {
-        return info.getMinAspectRatio(getRequestedOrientation());
+        float infoAspectRatio = info.getMinAspectRatio(getRequestedOrientation());
+        // Complying with the CDD 7.1.1.2 requirement for unresizble apps:
+        // https://source.android.com/compatibility/12/android-12-cdd#7112_screen_aspect_ratio
+        return infoAspectRatio < 1f && info.resizeMode == RESIZE_MODE_UNRESIZEABLE
+                    // TODO(233582832): Consider removing fixed-orientation condition.
+                    // Some apps switching from tablet to phone layout at the certain size
+                    // threshold. This may lead to flickering on tablets in landscape orientation
+                    // if an app sets orientation to portrait dynamically because of aspect ratio
+                    // restriction applied here.
+                    && getRequestedConfigurationOrientation() != ORIENTATION_UNDEFINED
+                ? mLetterboxUiController.getDefaultMinAspectRatioForUnresizableApps()
+                : infoAspectRatio;
     }
 
     /**
@@ -9595,7 +9595,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);
 
@@ -9675,6 +9675,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..d59f696 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;
@@ -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 d60981f..4e2d1aa 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 7723a46..f4aafe0 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -211,6 +211,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
@@ -633,6 +634,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");
@@ -1247,6 +1250,10 @@
         mController.onExecutionComplete(this);
     }
 
+    private void onExecutionStarted() {
+        mController.onExecutionStarted(this);
+    }
+
     private boolean isHomeApp(int uid, @Nullable String packageName) {
         if (mService.mHomeProcess != null) {
             // Fast check
@@ -1667,6 +1674,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 =
@@ -1726,19 +1734,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,
@@ -2372,6 +2403,7 @@
         mAvoidMoveToFront = false;
         mFrozeTaskList = false;
         mTransientLaunch = false;
+        mDisplayLockAndOccluded = false;
 
         mVoiceSession = null;
         mVoiceInteractor = null;
@@ -2439,6 +2471,11 @@
             }
         }
 
+        if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0 && mSourceRecord == null) {
+            // ignore the flag if there is no the sourceRecord
+            mLaunchFlags &= ~FLAG_ACTIVITY_LAUNCH_ADJACENT;
+        }
+
         // We'll invoke onUserLeaving before onPause only if the launching
         // activity did not explicitly state that this is an automated launch.
         mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;
@@ -2475,6 +2512,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) {
@@ -2742,17 +2789,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...
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index f75d73b..6152676 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -666,9 +666,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 b8162cd..6ae8887 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,13 @@
     /** The time at which the previous process was last visible. */
     private long mPreviousProcessVisibleTime;
 
+    /**
+     * It can be true from keyguard-going-away to set-keyguard-shown. And getTopProcessState() will
+     * return {@link ActivityManager#PROCESS_STATE_IMPORTANT_FOREGROUND} to avoid top app from
+     * preempting CPU while keyguard is animating.
+     */
+    private volatile boolean mDemoteTopAppDuringUnlocking;
+
     /** 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. */
@@ -2830,12 +2839,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 (mDemoteTopAppDuringUnlocking) {
+                mDemoteTopAppDuringUnlocking = false;
+                // 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 +2883,7 @@
         // animation of system UI. Even if AOD is not enabled, it should be no harm.
         final WindowProcessController proc;
         synchronized (mGlobalLockWithoutBoost) {
+            mDemoteTopAppDuringUnlocking = false;
             final WindowState notificationShade = mRootWindowContainer.getDefaultDisplay()
                     .getDisplayPolicy().getNotificationShade();
             proc = notificationShade != null
@@ -3399,8 +3421,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.
+                    mDemoteTopAppDuringUnlocking = true;
                 }
 
                 mRootWindowContainer.forAllDisplays(displayContent -> {
@@ -3448,10 +3473,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 +3491,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 +3514,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 +3532,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;
     }
@@ -5595,12 +5662,17 @@
         @HotPath(caller = HotPath.OOM_ADJUSTMENT)
         @Override
         public int getTopProcessState() {
+            final int topState = mTopProcessState;
+            if (mDemoteTopAppDuringUnlocking && topState == ActivityManager.PROCESS_STATE_TOP) {
+                // The unlocking UI is more important, so defer the top state of 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)
@@ -6624,15 +6696,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 95de040..752edaa 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;
@@ -93,6 +94,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 +123,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;
@@ -154,6 +155,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
@@ -245,6 +247,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;
 
@@ -1313,7 +1318,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();
@@ -1386,8 +1391,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();
@@ -1797,7 +1801,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();
@@ -2458,8 +2462,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();
@@ -2620,6 +2623,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..caaaf47 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;
@@ -645,9 +650,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;
@@ -835,14 +846,26 @@
                             ? 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;
             }
-            a = animAttr != 0 ? loadAnimationAttr(lp, animAttr, transit) : null;
 
+            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);
 
@@ -1157,6 +1180,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 fa506ca..ad3bb2d 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;
@@ -315,6 +318,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)
@@ -322,7 +328,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
@@ -337,6 +343,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;
@@ -400,11 +415,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) {
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 61deb59..b519dad 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -144,8 +144,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();
         }
     }
@@ -214,10 +213,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 +350,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;
     }
@@ -463,10 +482,10 @@
         final boolean keepUntilStartTransaction =
                 !mIsStartTransactionCommitted && op.mAction == Operation.ACTION_SEAMLESS;
         if (!keepUntilTransitionFinish && !keepUntilStartTransaction) return false;
-        if (op.mCapturedDrawTransaction == null) {
-            op.mCapturedDrawTransaction = postDrawTransaction;
+        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);
         return true;
@@ -512,7 +531,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/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a059ac6..a870ed3 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -558,7 +558,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<>();
@@ -1054,6 +1055,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 +1437,7 @@
         if (!isReady()) {
             return;
         }
-        if (mDisplayRotation.isWaitingForRemoteRotation()) {
+        if (mRemoteDisplayChangeController.isWaitingForRemoteDisplayChange()) {
             return;
         }
 
@@ -1535,8 +1537,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 +1585,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,12 +1600,12 @@
     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) {
@@ -1611,6 +1615,15 @@
         if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
             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 +1637,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 +1704,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
@@ -1813,8 +1833,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.
@@ -2015,7 +2035,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 +2224,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 +2409,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 +2432,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 +2778,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 +2839,8 @@
             reconfigureDisplayLocked();
 
             if (physicalDisplayChanged) {
-                mDisplaySwitchTransitionLauncher.onDisplayUpdated();
+                mDisplaySwitchTransitionLauncher.onDisplayUpdated(currentRotation, getRotation(),
+                        getDisplayAreaInfo());
             }
         }
     }
@@ -6081,7 +6103,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.
@@ -6250,7 +6273,6 @@
     /**
      * Sets if Display APIs should be sandboxed to the activity window bounds.
      */
-    @VisibleForTesting
     void setSandboxDisplayApis(boolean sandboxDisplayApis) {
         mSandboxDisplayApis = sandboxDisplayApis;
     }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 7e91989a..8733316a 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;
@@ -778,7 +779,22 @@
     }
 
     public void setAwake(boolean awake) {
+        if (awake == mAwake) {
+            return;
+        }
         mAwake = awake;
+        synchronized (mService.mGlobalLock) {
+            if (!mDisplayContent.isDefaultDisplay) {
+                return;
+            }
+            if (mAwake) {
+                // 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() {
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 03e1429..a78d25f 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();
         }
     }
 
@@ -1571,8 +1522,8 @@
         }
 
         @Override
-        public boolean isKeyguardLocked() {
-            return mService.isKeyguardLocked();
+        public boolean isKeyguardShowingAndNotOccluded() {
+            return mService.isKeyguardShowingAndNotOccluded();
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index c47d778..73f0d31 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;
@@ -207,8 +208,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");
             }
@@ -236,7 +235,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();
                 }
             }
@@ -320,7 +319,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),
@@ -336,7 +334,7 @@
             endDragLocked();
             return false;
         } finally {
-            if (myPid != touchedWin.mSession.mPid) {
+            if (MY_PID != touchedWin.mSession.mPid) {
                 event.recycle();
             }
         }
@@ -364,8 +362,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
@@ -477,7 +475,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/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 358e93d..178e299 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -290,7 +290,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 +325,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;
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 01c9414..4d971a9 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -72,6 +72,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 +81,7 @@
     private final ActivityTaskManagerService mService;
     private RootWindowContainer mRootWindowContainer;
     private final ActivityTaskManagerInternal.SleepTokenAcquirer mSleepTokenAcquirer;
-
+    private boolean mWaitingForWakeTransition;
 
     KeyguardController(ActivityTaskManagerService service,
             ActivityTaskSupervisor taskSupervisor) {
@@ -171,6 +173,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 +204,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 +221,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 +531,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;
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..2d227b6 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;
@@ -38,6 +37,11 @@
      */
     static final float MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO = 1.0f;
 
+    // Min allowed aspect ratio for unresizable apps which is used when an app doesn't specify
+    // android:minAspectRatio in accordance with the CDD 7.1.1.2 requirement:
+    // https://source.android.com/compatibility/12/android-12-cdd#7112_screen_aspect_ratio
+    static final float MIN_UNRESIZABLE_ASPECT_RATIO = 4 / 3f;
+
     /** Enum for Letterbox background type. */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({LETTERBOX_BACKGROUND_SOLID_COLOR, LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND,
@@ -56,25 +60,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 +109,11 @@
     // MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO will be ignored.
     private float mFixedOrientationLetterboxAspectRatio;
 
+    // Default min aspect ratio for unresizable apps which is used when an app doesn't specify
+    // android:minAspectRatio in accordance with the CDD 7.1.1.2 requirement:
+    // https://source.android.com/compatibility/12/android-12-cdd#7112_screen_aspect_ratio
+    private float mDefaultMinAspectRatioForUnresizableApps;
+
     // Corners radius for activities presented in the letterbox mode, values < 0 will be ignored.
     private int mLetterboxActivityCornersRadius;
 
@@ -107,29 +139,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 +203,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 +229,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 +237,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 +250,62 @@
     }
 
     /**
+     * Resets the min aspect ratio for unresizable apps which is used when an app doesn't specify
+     * {@code android:minAspectRatio} to {@link
+     * R.dimen.config_letterboxDefaultMinAspectRatioForUnresizableApps}.
+     *
+     * @throws AssertionError if {@link
+     * R.dimen.config_letterboxDefaultMinAspectRatioForUnresizableApps} is < {@link
+     * #MIN_UNRESIZABLE_ASPECT_RATIO}.
+     */
+    void resetDefaultMinAspectRatioForUnresizableApps() {
+        setDefaultMinAspectRatioForUnresizableApps(mContext.getResources().getFloat(
+                R.dimen.config_letterboxDefaultMinAspectRatioForUnresizableApps));
+    }
+
+    /**
+     * Gets the min aspect ratio for unresizable apps which is used when an app doesn't specify
+     * {@code android:minAspectRatio}.
+     */
+    float getDefaultMinAspectRatioForUnresizableApps() {
+        return mDefaultMinAspectRatioForUnresizableApps;
+    }
+
+    /**
+     * Overrides the min aspect ratio for unresizable apps which is used when an app doesn't
+     * specify {@code android:minAspectRatio}.
+     *
+     * @throws AssertionError if given value is < {@link #MIN_UNRESIZABLE_ASPECT_RATIO}.
+     */
+    void setDefaultMinAspectRatioForUnresizableApps(float aspectRatio) {
+        if (aspectRatio < MIN_UNRESIZABLE_ASPECT_RATIO) {
+            throw new AssertionError(
+                    "Unexpected min aspect ratio for unresizable apps, it should be <= "
+                            + MIN_UNRESIZABLE_ASPECT_RATIO + " but was " + 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 +336,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 +373,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 +415,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 +443,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 +485,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 +675,108 @@
      * <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) {
+    /** 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 +789,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..df9a87e 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -163,7 +163,8 @@
                         this::hasWallpaperBackgroudForLetterbox,
                         this::getLetterboxWallpaperBlurRadius,
                         this::getLetterboxWallpaperDarkScrimAlpha,
-                        this::handleDoubleTap);
+                        this::handleHorizontalDoubleTap,
+                        this::handleVerticalDoubleTap);
                 mLetterbox.attachInput(w);
             }
             mActivityRecord.getPosition(mTmpPoint);
@@ -193,18 +194,27 @@
     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 getDefaultMinAspectRatioForUnresizableApps() {
+        if (!mLetterboxConfiguration.getIsSplitScreenAspectRatioForUnresizableAppsEnabled()
+                || mActivityRecord.getDisplayContent() == null) {
+            return mLetterboxConfiguration.getDefaultMinAspectRatioForUnresizableApps();
         }
 
         int dividerWindowWidth =
@@ -214,10 +224,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, /* dy */ 0);
+            bounds.right = bounds.centerX();
+        } else {
+            bounds.inset(/* dx */ 0, /* dy */ dividerSize);
+            bounds.bottom = bounds.centerY();
+        }
         return computeAspectRatio(bounds);
     }
 
@@ -225,8 +239,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;
         }
 
@@ -237,10 +251,32 @@
 
         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();
         } 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();
+        }
+
+        // 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;
+        }
+
+        if (mLetterbox.getInnerFrame().top > y) {
+            // Moving to the next stop on the top side of the app window: bottom > center > top.
+            mLetterboxConfiguration.movePositionForVerticalReachabilityToNextTopStop();
+        } else if (mLetterbox.getInnerFrame().bottom < y) {
+            // Moving to the next stop on the bottom side of the app window: top > center > bottom.
+            mLetterboxConfiguration.movePositionForVerticalReachabilityToNextBottomStop();
         }
 
         // TODO(197549949): Add animation for transition.
@@ -248,25 +284,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 +532,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,6 +561,9 @@
         if (mainWin.isLetterboxedForDisplayCutout()) {
             return "DISPLAY_CUTOUT";
         }
+        if (mActivityRecord.isAspectRatioApplied()) {
+            return "ASPECT_RATIO";
+        }
         return "UNKNOWN_REASON";
     }
 
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/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..326c450 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1977,23 +1977,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 +2016,6 @@
 
             final TaskFragment organizedTf = r.getOrganizedTaskFragment();
             final boolean singleActivity = task.getNonFinishingActivityCount() == 1;
-            final Task rootTask;
             if (singleActivity) {
                 rootTask = task;
 
@@ -2044,6 +2048,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 +2084,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 +2097,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 +2139,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);
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/StartingSurfaceController.java b/services/core/java/com/android/server/wm/StartingSurfaceController.java
index e8445ab..68dbb06 100644
--- a/services/core/java/com/android/server/wm/StartingSurfaceController.java
+++ b/services/core/java/com/android/server/wm/StartingSurfaceController.java
@@ -221,6 +221,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 1bec2a5..b739878 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -67,6 +67,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.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;
@@ -76,7 +77,6 @@
 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;
@@ -197,6 +197,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 +427,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 +1402,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) {
@@ -1708,23 +1697,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());
     }
@@ -2032,10 +2004,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;
@@ -3385,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.
@@ -3401,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
@@ -3423,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
@@ -3473,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() {
@@ -3719,42 +3669,6 @@
         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++;
-            }
-        }
-    }
-
     /**
      * Saves this {@link Task} to XML using given serializer.
      */
@@ -4653,22 +4567,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;
         }
@@ -5582,23 +5486,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;
         }
 
@@ -5606,7 +5497,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);
             }
@@ -5624,15 +5515,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);
@@ -6029,8 +5975,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 dd1b50f..d983572 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;
         }
@@ -728,12 +715,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);
     }
 
     /**
@@ -761,19 +743,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++);
         }
 
@@ -800,31 +769,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 */);
     }
@@ -870,12 +814,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();
     }
@@ -1898,15 +1836,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
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 324f029..24a8250 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -173,14 +173,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;
@@ -332,15 +324,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);
         }
     }
 
@@ -349,11 +340,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,
@@ -1532,7 +1521,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 {
@@ -1570,8 +1559,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;
             }
 
@@ -1864,19 +1856,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);
     }
@@ -2038,13 +2030,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;
@@ -2061,9 +2054,15 @@
                 final boolean inPipTransition = windowingMode == WINDOWING_MODE_PINNED
                         && !mTmpFullBounds.isEmpty() && mTmpFullBounds.equals(parentBounds);
                 if (WindowConfiguration.isFloating(windowingMode) && !inPipTransition) {
-                    // For floating tasks, calculate the smallest width from the bounds of the task
-                    inOutConfig.smallestScreenWidthDp = (int) (
-                            Math.min(mTmpFullBounds.width(), mTmpFullBounds.height()) / density);
+                    // For floating tasks, calculate the smallest width from the bounds of the
+                    // task, because they should not be affected by insets.
+                    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.
+                    inOutConfig.smallestScreenWidthDp =
+                            Math.min(inOutConfig.screenWidthDp, inOutConfig.screenHeightDp);
                 }
                 // otherwise, it will just inherit
             }
@@ -2077,8 +2076,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) {
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/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index f6f9020..47eb715 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;
 
@@ -210,10 +214,26 @@
             mTransientLaunches = new ArrayMap<>();
         }
         mTransientLaunches.put(activity, restoreBelow);
+        setTransientLaunchToChanges(activity);
+
+        if (restoreBelow != null) {
+            final ChangeInfo info = mChanges.get(restoreBelow);
+            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 +258,20 @@
         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;
+        }
+    }
+
     @VisibleForTesting
     int getSyncId() {
         return mSyncId;
@@ -296,7 +330,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);
@@ -419,7 +458,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 +467,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 +509,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 +576,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 +587,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 +603,6 @@
                         }
                         ar.commitVisibility(false /* visible */, false /* performLayout */,
                                 true /* fromTransition */);
-                        activitiesWentInvisible = true;
                     }
                 }
                 if (mChanges.get(ar).mVisible != visibleAtTransitionEnd) {
@@ -567,12 +629,10 @@
                 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();
-        }
+        // 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);
 
@@ -675,7 +735,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 +746,6 @@
 
         handleNonAppWindowsInTransition(dc, mType, mFlags);
 
-        reportStartReasonsToLogger();
-
         // The callback is only populated for custom activity-level client animations
         sendRemoteCallback(mClientAnimationStartCallback);
 
@@ -728,6 +787,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());
         }
 
@@ -775,6 +837,8 @@
         }
         mSyncId = -1;
         mOverrideOptions = null;
+
+        reportStartReasonsToLogger();
     }
 
     /**
@@ -987,11 +1051,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 +1088,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 +1298,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 +1318,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 +1348,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 +1393,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 +1403,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());
@@ -1497,10 +1576,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 +1620,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 +1640,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 +1693,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 +1704,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 +1746,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 +1793,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..15ab3a2 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -207,6 +207,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 +226,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 +246,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 +282,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 +477,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.
@@ -526,6 +566,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/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..483f51a 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -188,7 +188,8 @@
                 && animatingContainer.getAnimation().getShowWallpaper();
         final boolean hasWallpaper = w.hasWallpaper() || animationWallpaper;
         final boolean isRecentsTransitionTarget = (recentsAnimationController != null
-                && recentsAnimationController.isWallpaperVisible(w));
+                && recentsAnimationController.isWallpaperVisible(w))
+                || w.mTransitionController.isTransientHide(w.getTask());
         if (isRecentsTransitionTarget) {
             if (DEBUG_WALLPAPER) Slog.v(TAG, "Found recents animation wallpaper target: " + w);
             mFindResults.setWallpaperTarget(w);
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 9022186..e67aea8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -238,10 +238,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;
@@ -397,9 +397,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;
 
@@ -682,9 +681,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 +1066,6 @@
 
     Function<SurfaceSession, SurfaceControl.Builder> mSurfaceControlFactory;
     Supplier<SurfaceControl.Transaction> mTransactionFactory;
-    final Supplier<Surface> mSurfaceFactory;
 
     private final SurfaceControl.Transaction mTransaction;
 
@@ -1150,7 +1148,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 +1161,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 +1175,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 +1190,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 +1204,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 +1228,6 @@
 
         mSurfaceControlFactory = surfaceControlFactory;
         mTransactionFactory = transactionFactory;
-        mSurfaceFactory = surfaceFactory;
         mTransaction = mTransactionFactory.get();
 
         mPolicy = policy;
@@ -2704,7 +2698,7 @@
     }
 
     boolean checkCallingPermission(String permission, String func, boolean printLog) {
-        if (Binder.getCallingPid() == myPid()) {
+        if (Binder.getCallingPid() == MY_PID) {
             return true;
         }
 
@@ -2864,7 +2858,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 +4254,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 +4292,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 +5689,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;
@@ -6087,24 +6101,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;
@@ -8753,7 +8767,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..d9d804c 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":
@@ -331,6 +357,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 +610,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 +1175,66 @@
         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 runReset(PrintWriter pw) throws RemoteException {
         int displayId = getDisplayId(getNextArg());
 
@@ -651,6 +1259,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 +1299,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 +1317,83 @@
         }
     }
 
+    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 doesn't specify android:minAspectRatio. An exception will be");
+        pw.println("        thrown if aspectRatio < "
+                + LetterboxConfiguration.MIN_UNRESIZABLE_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 ff3b4a5..8652bc8 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.view.Display.DEFAULT_DISPLAY;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
@@ -42,6 +43,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;
@@ -395,6 +397,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();
@@ -413,17 +417,42 @@
                 }
                 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());
                 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) {
@@ -431,8 +460,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) {
@@ -544,6 +571,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()) {
@@ -580,6 +614,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;
     }
 
@@ -764,7 +820,7 @@
                     sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception);
                     break;
                 }
-                tf1.setAdjacentTaskFragment(tf2, false /* moveAdjacentTogether */);
+                tf1.setAdjacentTaskFragment(tf2);
                 effects |= TRANSACT_EFFECTS_LIFECYCLE;
 
                 final Bundle bundle = hop.getLaunchOptions();
@@ -1153,7 +1209,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 1abe24e..c91bec9 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -116,7 +116,6 @@
 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_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 +150,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;
@@ -616,11 +616,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;
@@ -1541,13 +1536,11 @@
                 || configChanged
                 || insetsChanged
                 || dragResizingChanged
-                || mReportOrientationChanged
                 || shouldSendRedrawForSync()) {
             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);
@@ -2178,6 +2171,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.
@@ -3580,10 +3574,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();
         }
@@ -3900,12 +3890,10 @@
             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();
 
@@ -3914,7 +3902,7 @@
         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();
@@ -3941,7 +3929,7 @@
             mClient.resized(mClientWindowFrames, reportDraw, mLastReportedConfiguration,
                     getCompatInsetsState(), forceRelayout, alwaysConsumeSystemBars, displayId,
                     mSyncSeqId, resizeMode);
-            if (drawPending && reportOrientation && mOrientationChanging) {
+            if (drawPending && mOrientationChanging) {
                 mOrientationChangeRedrawRequestTime = SystemClock.elapsedRealtime();
                 ProtoLog.v(WM_DEBUG_ORIENTATION,
                         "Requested redraw for orientation change: %s", this);
@@ -4366,12 +4354,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=");
@@ -5572,7 +5559,7 @@
                 mLastSurfaceInsets.set(mAttrs.surfaceInsets);
             }
             if (surfaceSizeChanged && mWinAnimator.getShown() && !canPlayMoveAnimation()
-                    && okToDisplay()) {
+                    && okToDisplay() && mSyncState == SYNC_STATE_NONE) {
                 applyWithNextDraw(mSetSurfacePositionConsumer);
             } else {
                 mSetSurfacePositionConsumer.accept(t);
@@ -6009,7 +5996,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
@@ -6046,6 +6032,11 @@
         if (mRedrawForSyncReported) {
             return false;
         }
+        if (mInRelayout) {
+            // 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();
     }
 
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 d2e56fa..ddbb930 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -18,7 +18,6 @@
 
 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;
@@ -37,6 +36,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 +363,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.COLOR_FADE_LAYER + 1);
         } else {
             super.assignLayer(t, layer);
@@ -569,13 +565,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 +586,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();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 8702578..48ad622 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -12517,8 +12517,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/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/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 12e5653..b8f0b72 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -1786,13 +1786,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 +1833,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();
@@ -2165,39 +2168,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 77f884c..8656a4f 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..b270608 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;
@@ -123,8 +124,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 +136,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;
 
@@ -1097,6 +1099,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(
@@ -1693,8 +1714,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 +1802,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 +1845,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 +2215,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());
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..db3a51c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -39,6 +39,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -168,7 +169,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());
@@ -209,8 +211,10 @@
         assertThat(activityConfigBounds.width()).isEqualTo(activityBounds.width());
         assertThat(activityConfigBounds.height()).isEqualTo(activityBounds.height());
         assertThat(activitySizeCompatBounds.height()).isEqualTo(newTaskBounds.height());
-        assertThat(activitySizeCompatBounds.width()).isEqualTo(
-                newTaskBounds.height() * newTaskBounds.height() / newTaskBounds.width());
+        final float defaultAspectRatio = mFirstActivity.mWmService.mLetterboxConfiguration
+                .getDefaultMinAspectRatioForUnresizableApps();
+        assertEquals(activitySizeCompatBounds.width(),
+                newTaskBounds.height() / defaultAspectRatio, 0.5);
     }
 
     @Test
@@ -230,8 +234,9 @@
         assertThat(mFirstActivity.inSizeCompatMode()).isFalse();
         assertThat(taskBounds).isEqualTo(dagBounds);
         assertThat(activityBounds.width()).isEqualTo(dagBounds.width());
-        assertThat(activityBounds.height())
-                .isEqualTo(dagBounds.width() * dagBounds.width() / dagBounds.height());
+        final float defaultAspectRatio = mFirstActivity.mWmService.mLetterboxConfiguration
+                .getDefaultMinAspectRatioForUnresizableApps();
+        assertEquals(activityBounds.height(), dagBounds.width() / defaultAspectRatio, 0.5);
     }
 
     @Test
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/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..7f70882 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,103 @@
     }
 
     @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);
+        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.
+        setUpDisplaySizeWithApp(1600, 1400);
+        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");
+        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 landscape and ignoring orientation request.
+        setUpDisplaySizeWithApp(1400, 1600);
+        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");
+        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 +2033,7 @@
     }
 
     @Test
-    public void testSupportsNonResizableInSplitScreen_fillTaskForSameOrientation() {
+    public void testSupportsNonResizableInSplitScreen_aspectRatioLetterboxInSameOrientation() {
         // Support non resizable in multi window
         mAtm.mDevEnableNonResizableMultiWindow = true;
         setUpDisplaySizeWithApp(1000, 2800);
@@ -1946,7 +2071,12 @@
         // Activity bounds fill split screen.
         final Rect primarySplitBounds = new Rect(organizer.mPrimary.getBounds());
         final Rect letterboxedBounds = new Rect(mActivity.getBounds());
-        assertEquals(primarySplitBounds, letterboxedBounds);
+        // Activity is letterboxed for aspect ratio.
+        assertEquals(primarySplitBounds.height(), letterboxedBounds.height());
+        final float defaultAspectRatio = mActivity.mWmService.mLetterboxConfiguration
+                .getDefaultMinAspectRatioForUnresizableApps();
+        assertEquals(primarySplitBounds.height() / defaultAspectRatio,
+                letterboxedBounds.width(), 0.5);
     }
 
     @Test
@@ -1960,7 +2090,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 +2207,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 +2232,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);
 
@@ -2399,6 +2627,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 +2652,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..18c4eb9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -66,7 +66,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 +76,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 +92,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 +121,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 +283,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 +294,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 +310,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 +331,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,10 +430,6 @@
                 .spiedInstance(sWakeLock).stubOnly());
     }
 
-    void setSurfaceFactory(Supplier<Surface> factory) {
-        mSurfaceFactory = factory;
-    }
-
     void cleanupWindowManagerHandlers() {
         final WindowManagerService wm = getWindowManagerService();
         if (wm == null) {
@@ -618,32 +590,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..2a9fcb9 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,7 +756,7 @@
         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,
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 5340a79..7cdf5a8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -32,7 +32,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;
@@ -412,7 +411,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);
 
@@ -630,7 +629,7 @@
 
         verify(mAtm.mWindowOrganizerController).sendTaskFragmentOperationFailure(eq(mIOrganizer),
                 eq(errorToken), any(IllegalArgumentException.class));
-        verify(mTaskFragment, never()).setAdjacentTaskFragment(any(), anyBoolean());
+        verify(mTaskFragment, never()).setAdjacentTaskFragment(any());
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 3ed484a..228cb65 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);
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 9304761..7138714 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..d9d819b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -85,6 +85,7 @@
 @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);
@@ -121,7 +122,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 +131,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 +139,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 +147,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 +188,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 +198,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 +235,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 +244,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 +275,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 +312,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 +362,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 +396,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 +478,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 +531,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 +572,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());
 
@@ -608,7 +615,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);
         };
@@ -814,8 +821,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.
@@ -955,6 +965,29 @@
         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);
+        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/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 724204f..378aff8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -673,6 +673,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 9957d05..d299a86 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -229,14 +229,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 +260,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();
     }
 
     /**
@@ -1541,7 +1559,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/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 42d446d..434663b 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -46,11 +46,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;
@@ -1162,11 +1160,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/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..933a3a0 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
@@ -23,16 +23,16 @@
 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.statusBarLayerRotatesScales
 import com.android.server.wm.flicker.statusBarWindowIsVisible
@@ -43,7 +43,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 +54,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 +98,7 @@
 
     @Presubmit
     @Test
-    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales()
+    fun navBarLayerRotatesAndScales() = testSpec.navBarLayerPositionEnd()
 
     @FlakyTest(bugId = 206753786)
     fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales()
@@ -112,7 +120,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/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");