Merge "Fix the legacy BatterySaverUtilsTest failed test cases" into udc-dev
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 6eeff82..577260e 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1577,8 +1577,6 @@
                 mJobPackageTracker.notePending(jobStatus);
                 mPendingJobQueue.add(jobStatus);
                 maybeRunPendingJobsLocked();
-            } else {
-                evaluateControllerStatesLocked(jobStatus);
             }
         }
         return JobScheduler.RESULT_SUCCESS;
@@ -3050,8 +3048,6 @@
                     Slog.d(TAG, "    queued " + job.toShortString());
                 }
                 newReadyJobs.add(job);
-            } else {
-                evaluateControllerStatesLocked(job);
             }
         }
 
@@ -3171,7 +3167,6 @@
                 } else if (mPendingJobQueue.remove(job)) {
                     noteJobNonPending(job);
                 }
-                evaluateControllerStatesLocked(job);
             }
         }
 
@@ -3297,7 +3292,7 @@
 
     @GuardedBy("mLock")
     boolean isReadyToBeExecutedLocked(JobStatus job, boolean rejectActive) {
-        final boolean jobReady = job.isReady();
+        final boolean jobReady = job.isReady() || evaluateControllerStatesLocked(job);
 
         if (DEBUG) {
             Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
@@ -3372,12 +3367,17 @@
         return !appIsBad;
     }
 
+    /**
+     * Gets each controller to evaluate the job's state
+     * and then returns the value of {@link JobStatus#isReady()}.
+     */
     @VisibleForTesting
-    void evaluateControllerStatesLocked(final JobStatus job) {
+    boolean evaluateControllerStatesLocked(final JobStatus job) {
         for (int c = mControllers.size() - 1; c >= 0; --c) {
             final StateController sc = mControllers.get(c);
             sc.evaluateStateLocked(job);
         }
+        return job.isReady();
     }
 
     /**
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 63da0a2..d375760 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -2916,6 +2916,14 @@
             }
         }
 
+        if (isStyle(CallStyle.class) & extras != null) {
+            Person callPerson = extras.getParcelable(EXTRA_CALL_PERSON);
+            if (callPerson != null) {
+                visitor.accept(callPerson.getIconUri());
+            }
+            visitIconUri(visitor, extras.getParcelable(EXTRA_VERIFICATION_ICON));
+        }
+
         if (mBubbleMetadata != null) {
             visitIconUri(visitor, mBubbleMetadata.getIcon());
         }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 048289f..960d10a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2628,6 +2628,15 @@
             return Build.VERSION_CODES.CUR_DEVELOPMENT;
         }
 
+        // STOPSHIP: hack for the pre-release SDK
+        if (platformSdkCodenames.length == 0
+                && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+                targetCode)) {
+            Slog.w(TAG, "Package requires development platform " + targetCode
+                    + ", returning current version " + Build.VERSION.SDK_INT);
+            return Build.VERSION.SDK_INT;
+        }
+
         // Otherwise, we're looking at an incompatible pre-release SDK.
         if (platformSdkCodenames.length > 0) {
             outError[0] = "Requires development platform " + targetCode
@@ -2699,6 +2708,15 @@
             return Build.VERSION_CODES.CUR_DEVELOPMENT;
         }
 
+        // STOPSHIP: hack for the pre-release SDK
+        if (platformSdkCodenames.length == 0
+                && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+                minCode)) {
+            Slog.w(TAG, "Package requires min development platform " + minCode
+                    + ", returning current version " + Build.VERSION.SDK_INT);
+            return Build.VERSION.SDK_INT;
+        }
+
         // Otherwise, we're looking at an incompatible pre-release SDK.
         if (platformSdkCodenames.length > 0) {
             outError[0] = "Requires development platform " + minCode
diff --git a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
index 3e1c5bb..8cc4cdb 100644
--- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
@@ -316,6 +316,15 @@
             return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
         }
 
+        // STOPSHIP: hack for the pre-release SDK
+        if (platformSdkCodenames.length == 0
+                && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+                        minCode)) {
+            Slog.w(TAG, "Parsed package requires min development platform " + minCode
+                    + ", returning current version " + Build.VERSION.SDK_INT);
+            return input.success(Build.VERSION.SDK_INT);
+        }
+
         // Otherwise, we're looking at an incompatible pre-release SDK.
         if (platformSdkCodenames.length > 0) {
             return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
@@ -368,19 +377,27 @@
             return input.success(targetVers);
         }
 
+        // If it's a pre-release SDK and the codename matches this platform, it
+        // definitely targets this SDK.
+        if (matchTargetCode(platformSdkCodenames, targetCode)) {
+            return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
+        }
+
+        // STOPSHIP: hack for the pre-release SDK
+        if (platformSdkCodenames.length == 0
+                && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals(
+                        targetCode)) {
+            Slog.w(TAG, "Parsed package requires development platform " + targetCode
+                    + ", returning current version " + Build.VERSION.SDK_INT);
+            return input.success(Build.VERSION.SDK_INT);
+        }
+
         try {
             if (allowUnknownCodenames && UnboundedSdkLevel.isAtMost(targetCode)) {
                 return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
             }
         } catch (IllegalArgumentException e) {
-            // isAtMost() throws it when encountering an older SDK codename
-            return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, e.getMessage());
-        }
-
-        // If it's a pre-release SDK and the codename matches this platform, it
-        // definitely targets this SDK.
-        if (matchTargetCode(platformSdkCodenames, targetCode)) {
-            return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
+            return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, "Bad package SDK");
         }
 
         // Otherwise, we're looking at an incompatible pre-release SDK.
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index ce6e1c7..08ba5b6 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -557,15 +557,25 @@
             boolean applyToSize) {
         inoutDm.density = inoutDm.noncompatDensity * invertedRatio;
         inoutDm.densityDpi = (int) ((inoutDm.noncompatDensityDpi * invertedRatio) + .5f);
+        // Note: since this is changing the scaledDensity, you might think we also need to change
+        // inoutDm.fontScaleConverter to accurately calculate non-linear font scaling. But we're not
+        // going to do that, for a couple of reasons (see b/265695259 for details):
+        // 1. The first case is only for apps targeting SDK < 4. These ancient apps will just have
+        //    to live with linear font scaling. We don't want to make anything more unpredictable.
+        // 2. The second case where this is called is for scaling down games. But it is called in
+        //    two situations:
+        //    a. When from ResourcesImpl.updateConfiguration(), we will set the fontScaleConverter
+        //       *after* this method is called. That's the only place where the app will actually
+        //       use the DisplayMetrics for scaling fonts in its resources.
+        //    b. Sometime later by WindowManager in onResume or other windowing events. In this case
+        //       the DisplayMetrics object is never used by the app/resources, so it's ok if
+        //       fontScaleConverter is null because it's not being used to scale fonts anyway.
         inoutDm.scaledDensity = inoutDm.noncompatScaledDensity * invertedRatio;
         inoutDm.xdpi = inoutDm.noncompatXdpi * invertedRatio;
         inoutDm.ydpi = inoutDm.noncompatYdpi * invertedRatio;
         if (applyToSize) {
             inoutDm.widthPixels = (int) (inoutDm.widthPixels * invertedRatio + 0.5f);
             inoutDm.heightPixels = (int) (inoutDm.heightPixels * invertedRatio + 0.5f);
-
-            float fontScale = inoutDm.scaledDensity / inoutDm.density;
-            inoutDm.fontScaleConverter = FontScaleConverterFactory.forScale(fontScale);
         }
     }
 
diff --git a/core/java/android/service/credentials/CredentialProviderInfoFactory.java b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
index fb2f4ad..1a1df6f 100644
--- a/core/java/android/service/credentials/CredentialProviderInfoFactory.java
+++ b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
@@ -165,8 +165,7 @@
             Slog.w(TAG, "Context is null in isSystemProviderWithValidPermission");
             return false;
         }
-        return PermissionUtils.isSystemApp(context, serviceInfo.packageName)
-                && PermissionUtils.hasPermission(context, serviceInfo.packageName,
+        return PermissionUtils.hasPermission(context, serviceInfo.packageName,
                 Manifest.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE);
     }
 
diff --git a/core/java/android/service/credentials/PermissionUtils.java b/core/java/android/service/credentials/PermissionUtils.java
index d958111..2baf709 100644
--- a/core/java/android/service/credentials/PermissionUtils.java
+++ b/core/java/android/service/credentials/PermissionUtils.java
@@ -17,7 +17,6 @@
 package android.service.credentials;
 
 import android.content.Context;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 
 /**
@@ -33,21 +32,5 @@
         return context.getPackageManager().checkPermission(permission, packageName)
                 == PackageManager.PERMISSION_GRANTED;
     }
-
-    /** Checks whether the given package name is a system app on the device **/
-    public static boolean isSystemApp(Context context, String packageName) {
-        try {
-            ApplicationInfo appInfo =
-                    context.getPackageManager()
-                            .getApplicationInfo(packageName,
-                                    PackageManager.ApplicationInfoFlags.of(
-                                            PackageManager.MATCH_SYSTEM_ONLY));
-            if (appInfo != null) {
-                return true;
-            }
-        } catch (PackageManager.NameNotFoundException e) {
-        }
-        return false;
-    }
 }
 
diff --git a/core/java/android/util/IntArray.java b/core/java/android/util/IntArray.java
index bc0e35d..511cb2d 100644
--- a/core/java/android/util/IntArray.java
+++ b/core/java/android/util/IntArray.java
@@ -43,7 +43,7 @@
      * Creates an empty IntArray with the default initial capacity.
      */
     public IntArray() {
-        this(10);
+        this(0);
     }
 
     /**
diff --git a/core/java/android/util/LongArray.java b/core/java/android/util/LongArray.java
index 53dddeb..9f269ed 100644
--- a/core/java/android/util/LongArray.java
+++ b/core/java/android/util/LongArray.java
@@ -48,7 +48,7 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public LongArray() {
-        this(10);
+        this(0);
     }
 
     /**
diff --git a/core/java/android/window/BackNavigationInfo.java b/core/java/android/window/BackNavigationInfo.java
index e0ee683..e44f436 100644
--- a/core/java/android/window/BackNavigationInfo.java
+++ b/core/java/android/window/BackNavigationInfo.java
@@ -94,26 +94,29 @@
     @Nullable
     private final IOnBackInvokedCallback mOnBackInvokedCallback;
     private final boolean mPrepareRemoteAnimation;
+    private final boolean mAnimationCallback;
     @Nullable
     private final CustomAnimationInfo mCustomAnimationInfo;
 
     /**
      * Create a new {@link BackNavigationInfo} instance.
      *
-     * @param type                    The {@link BackTargetType} of the destination (what will be
-     * @param onBackNavigationDone    The callback to be called once the client is done with the
-     *                                back preview.
-     * @param onBackInvokedCallback   The back callback registered by the current top level window.
+     * @param type                  The {@link BackTargetType} of the destination (what will be
+     * @param onBackNavigationDone  The callback to be called once the client is done with the
+     *                              back preview.
+     * @param onBackInvokedCallback The back callback registered by the current top level window.
      */
     private BackNavigationInfo(@BackTargetType int type,
             @Nullable RemoteCallback onBackNavigationDone,
             @Nullable IOnBackInvokedCallback onBackInvokedCallback,
             boolean isPrepareRemoteAnimation,
+            boolean isAnimationCallback,
             @Nullable CustomAnimationInfo customAnimationInfo) {
         mType = type;
         mOnBackNavigationDone = onBackNavigationDone;
         mOnBackInvokedCallback = onBackInvokedCallback;
         mPrepareRemoteAnimation = isPrepareRemoteAnimation;
+        mAnimationCallback = isAnimationCallback;
         mCustomAnimationInfo = customAnimationInfo;
     }
 
@@ -122,6 +125,7 @@
         mOnBackNavigationDone = in.readTypedObject(RemoteCallback.CREATOR);
         mOnBackInvokedCallback = IOnBackInvokedCallback.Stub.asInterface(in.readStrongBinder());
         mPrepareRemoteAnimation = in.readBoolean();
+        mAnimationCallback = in.readBoolean();
         mCustomAnimationInfo = in.readTypedObject(CustomAnimationInfo.CREATOR);
     }
 
@@ -132,6 +136,7 @@
         dest.writeTypedObject(mOnBackNavigationDone, flags);
         dest.writeStrongInterface(mOnBackInvokedCallback);
         dest.writeBoolean(mPrepareRemoteAnimation);
+        dest.writeBoolean(mAnimationCallback);
         dest.writeTypedObject(mCustomAnimationInfo, flags);
     }
 
@@ -159,7 +164,7 @@
     }
 
     /**
-     * Return true if the core is preparing a back gesture nimation.
+     * Return true if the core is preparing a back gesture animation.
      * @hide
      */
     public boolean isPrepareRemoteAnimation() {
@@ -167,6 +172,14 @@
     }
 
     /**
+     * Return true if the callback is {@link OnBackAnimationCallback}.
+     * @hide
+     */
+    public boolean isAnimationCallback() {
+        return mAnimationCallback;
+    }
+
+    /**
      * Callback to be called when the back preview is finished in order to notify the server that
      * it can clean up the resources created for the animation.
      * @hide
@@ -214,6 +227,8 @@
                 + "mType=" + typeToString(mType) + " (" + mType + ")"
                 + ", mOnBackNavigationDone=" + mOnBackNavigationDone
                 + ", mOnBackInvokedCallback=" + mOnBackInvokedCallback
+                + ", mPrepareRemoteAnimation=" + mPrepareRemoteAnimation
+                + ", mAnimationCallback=" + mAnimationCallback
                 + ", mCustomizeAnimationInfo=" + mCustomAnimationInfo
                 + '}';
     }
@@ -343,6 +358,7 @@
         private IOnBackInvokedCallback mOnBackInvokedCallback = null;
         private boolean mPrepareRemoteAnimation;
         private CustomAnimationInfo mCustomAnimationInfo;
+        private boolean mAnimationCallback = false;
 
         /**
          * @see BackNavigationInfo#getType()
@@ -387,6 +403,7 @@
             mCustomAnimationInfo.mWindowAnimations = windowAnimations;
             return this;
         }
+
         /**
          * Set resources ids for customize activity animation.
          */
@@ -402,12 +419,21 @@
         }
 
         /**
+         * @param isAnimationCallback whether the callback is {@link OnBackAnimationCallback}
+         */
+        public Builder setAnimationCallback(boolean isAnimationCallback) {
+            mAnimationCallback = isAnimationCallback;
+            return this;
+        }
+
+        /**
          * Builds and returns an instance of {@link BackNavigationInfo}
          */
         public BackNavigationInfo build() {
             return new BackNavigationInfo(mType, mOnBackNavigationDone,
                     mOnBackInvokedCallback,
                     mPrepareRemoteAnimation,
+                    mAnimationCallback,
                     mCustomAnimationInfo);
         }
     }
diff --git a/core/java/android/window/OnBackInvokedCallbackInfo.java b/core/java/android/window/OnBackInvokedCallbackInfo.java
index 6480da3..bb5fe96 100644
--- a/core/java/android/window/OnBackInvokedCallbackInfo.java
+++ b/core/java/android/window/OnBackInvokedCallbackInfo.java
@@ -28,15 +28,20 @@
     @NonNull
     private final IOnBackInvokedCallback mCallback;
     private @OnBackInvokedDispatcher.Priority int mPriority;
+    private final boolean mIsAnimationCallback;
 
-    public OnBackInvokedCallbackInfo(@NonNull IOnBackInvokedCallback callback, int priority) {
+    public OnBackInvokedCallbackInfo(@NonNull IOnBackInvokedCallback callback,
+            int priority,
+            boolean isAnimationCallback) {
         mCallback = callback;
         mPriority = priority;
+        mIsAnimationCallback = isAnimationCallback;
     }
 
     private OnBackInvokedCallbackInfo(@NonNull Parcel in) {
         mCallback = IOnBackInvokedCallback.Stub.asInterface(in.readStrongBinder());
         mPriority = in.readInt();
+        mIsAnimationCallback = in.readBoolean();
     }
 
     @Override
@@ -48,6 +53,7 @@
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeStrongInterface(mCallback);
         dest.writeInt(mPriority);
+        dest.writeBoolean(mIsAnimationCallback);
     }
 
     public static final Creator<OnBackInvokedCallbackInfo> CREATOR =
@@ -77,9 +83,16 @@
         return mPriority;
     }
 
+    public boolean isAnimationCallback() {
+        return mIsAnimationCallback;
+    }
+
     @Override
     public String toString() {
         return "OnBackInvokedCallbackInfo{"
-                + "mCallback=" + mCallback + ", mPriority=" + mPriority + '}';
+                + "mCallback=" + mCallback
+                + ", mPriority=" + mPriority
+                + ", mIsAnimationCallback=" + mIsAnimationCallback
+                + '}';
     }
 }
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 8066f50..51382a4 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -193,7 +193,10 @@
                                 ? ((ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback)
                                         callback).getIOnBackInvokedCallback()
                                 : new OnBackInvokedCallbackWrapper(callback);
-                callbackInfo = new OnBackInvokedCallbackInfo(iCallback, priority);
+                callbackInfo = new OnBackInvokedCallbackInfo(
+                        iCallback,
+                        priority,
+                        callback instanceof OnBackAnimationCallback);
             }
             mWindowSession.setOnBackInvokedCallbackInfo(mWindow, callbackInfo);
         } catch (RemoteException e) {
diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
index 2b08a55..853fe2f 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
@@ -77,6 +77,10 @@
         /** Gating the removal of sorting-notifications-by-interruptiveness. */
         public static final Flag NO_SORT_BY_INTERRUPTIVENESS =
                 devFlag("persist.sysui.notification.no_sort_by_interruptiveness");
+
+        /** Gating the logging of DND state change events. */
+        public static final Flag LOG_DND_STATE_EVENTS =
+                devFlag("persist.sysui.notification.log_dnd_state_events");
     }
 
     //// == End of flags.  Everything below this line is the implementation. == ////
diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
index 1b4afd6..bb8bdf5 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodDebug.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
@@ -255,6 +255,12 @@
                 return "HIDE_SOFT_INPUT_IMM_DEPRECATION";
             case SoftInputShowHideReason.HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR:
                 return "HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR";
+            case SoftInputShowHideReason.SHOW_IME_SCREENSHOT_FROM_IMMS:
+                return "SHOW_IME_SCREENSHOT_FROM_IMMS";
+            case SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS:
+                return "REMOVE_IME_SCREENSHOT_FROM_IMMS";
+            case SoftInputShowHideReason.HIDE_WHEN_INPUT_TARGET_INVISIBLE:
+                return "HIDE_WHEN_INPUT_TARGET_INVISIBLE";
             default:
                 return "Unknown=" + reason;
         }
diff --git a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
index ec9184b..6e9cd44 100644
--- a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
+++ b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
@@ -65,7 +65,10 @@
         SoftInputShowHideReason.HIDE_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT,
         SoftInputShowHideReason.HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED,
         SoftInputShowHideReason.HIDE_SOFT_INPUT_IMM_DEPRECATION,
-        SoftInputShowHideReason.HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR
+        SoftInputShowHideReason.HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR,
+        SoftInputShowHideReason.SHOW_IME_SCREENSHOT_FROM_IMMS,
+        SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS,
+        SoftInputShowHideReason.HIDE_WHEN_INPUT_TARGET_INVISIBLE,
 })
 public @interface SoftInputShowHideReason {
     /** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */
@@ -259,4 +262,20 @@
      */
     int HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR =
             ImeProtoEnums.REASON_HIDE_WINDOW_GAINED_FOCUS_WITHOUT_EDITOR;
+
+    /**
+     * Shows ime screenshot by {@link com.android.server.inputmethod.InputMethodManagerService}.
+     */
+    int SHOW_IME_SCREENSHOT_FROM_IMMS = ImeProtoEnums.REASON_SHOW_IME_SCREENSHOT_FROM_IMMS;
+
+    /**
+     * Removes ime screenshot by {@link com.android.server.inputmethod.InputMethodManagerService}.
+     */
+    int REMOVE_IME_SCREENSHOT_FROM_IMMS = ImeProtoEnums.REASON_REMOVE_IME_SCREENSHOT_FROM_IMMS;
+
+    /**
+     * Hide soft input when the input target being removed or being obscured by an non-IME
+     * focusable overlay window.
+     */
+    int HIDE_WHEN_INPUT_TARGET_INVISIBLE = ImeProtoEnums.REASON_HIDE_WHEN_INPUT_TARGET_INVISIBLE;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e62477f..f6c9fab 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1036,9 +1036,9 @@
         android:protectionLevel="dangerous" />
 
     <!-- @SystemApi @hide Allows an application to communicate over satellite.
-         Only granted if the application is a system app. -->
+         Only granted if the application is a system app or privileged app. -->
     <permission android:name="android.permission.SATELLITE_COMMUNICATION"
-                android:protectionLevel="internal|role" />
+                android:protectionLevel="role|signature|privileged" />
 
     <!-- ====================================================================== -->
     <!-- Permissions for accessing external storage                             -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index cd25726..7de36a71 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1335,7 +1335,15 @@
         <!-- The container color of surface, which replaces the previous surface at elevation level
              2. @hide -->
         <attr name="materialColorSurfaceContainer" format="color"/>
-
+         <!-- The primary branding color for the app. By default, this is the color applied to the
+             action bar background. @hide -->
+        <attr name="materialColorPrimary" format="color"/>
+        <!-- The secondary branding color for the app, usually a bright complement to the primary
+             branding color. @hide -->
+        <attr name="materialColorSecondary" format="color"/>
+        <!-- A color that passes accessibility guidelines for text/iconography when drawn on top
+             of tertiary. @hide -->
+        <attr name="materialColorTertiary" format="color"/>
     </declare-styleable>
 
     <!-- **************************************************************** -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b0932d6..c6462f1 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5897,9 +5897,9 @@
     <string name="resolver_cant_access_personal_apps_explanation">This content can\u2019t be opened with personal apps</string>
 
     <!-- Error message. This text lets the user know that they need to turn on work apps in order to share or open content. There's also a button a user can tap to turn on the apps. [CHAR LIMIT=NONE] -->
-    <string name="resolver_turn_on_work_apps">Work profile is paused</string>
-    <!-- Button text. This button turns on a user's work profile so they can access their work apps and data. [CHAR LIMIT=NONE] -->
-    <string name="resolver_switch_on_work">Tap to turn on</string>
+    <string name="resolver_turn_on_work_apps">Work apps are paused</string>
+    <!-- Button text. This button unpauses a user's work apps and data. [CHAR LIMIT=NONE] -->
+    <string name="resolver_switch_on_work">Unpause</string>
 
     <!-- Error message. This text lets the user know that their current work apps don't support the specific content. [CHAR LIMIT=NONE] -->
     <string name="resolver_no_work_apps_available">No work apps</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b93a786..b7df6a4 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -5035,11 +5035,9 @@
   <java-symbol name="materialColorOnTertiary" type="attr"/>
   <java-symbol name="materialColorSurfaceDim" type="attr"/>
   <java-symbol name="materialColorSurfaceBright" type="attr"/>
-  <java-symbol name="materialColorSecondary" type="attr"/>
   <java-symbol name="materialColorOnError" type="attr"/>
   <java-symbol name="materialColorSurface" type="attr"/>
   <java-symbol name="materialColorSurfaceContainerHigh" type="attr"/>
-  <java-symbol name="materialColorTertiary" type="attr"/>
   <java-symbol name="materialColorSurfaceContainerHighest" type="attr"/>
   <java-symbol name="materialColorOnSurfaceVariant" type="attr"/>
   <java-symbol name="materialColorOutline" type="attr"/>
@@ -5047,8 +5045,71 @@
   <java-symbol name="materialColorOnPrimary" type="attr"/>
   <java-symbol name="materialColorOnSurface" type="attr"/>
   <java-symbol name="materialColorSurfaceContainer" type="attr"/>
-  <java-symbol name="materialColorSurfaceContainer" type="attr"/>
+  <java-symbol name="materialColorPrimary" type="attr"/>
+  <java-symbol name="materialColorSecondary" type="attr"/>
+  <java-symbol name="materialColorTertiary" type="attr"/>
 
   <java-symbol type="attr" name="actionModeUndoDrawable" />
   <java-symbol type="attr" name="actionModeRedoDrawable" />
+
+  <!-- Remaining symbols for Themes -->
+  <java-symbol type="style" name="Theme.DeviceDefault.Autofill.Save" />
+  <java-symbol type="style" name="Theme.DeviceDefault.AutofillHalfScreenDialogButton" />
+  <java-symbol type="style" name="Theme.DeviceDefault.AutofillHalfScreenDialogList" />
+  <java-symbol type="style" name="Theme.DeviceDefault.DayNight" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.Alert.DayNight" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.FixedSize" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.MinWidth" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.NoActionBar.FixedSize" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.NoActionBar.MinWidth" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.NoActionBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog.Presentation" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Dialog" />
+  <java-symbol type="style" name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.DialogWhenLarge" />
+  <java-symbol type="style" name="Theme.DeviceDefault.DocumentsUI" />
+  <java-symbol type="style" name="Theme.DeviceDefault.InputMethod" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.DarkActionBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.FixedSize" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.MinWidth" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.NoActionBar.FixedSize" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.NoActionBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.Presentation" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.DialogWhenLarge" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.NoActionBar.Fullscreen" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.NoActionBar.Overscan" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.NoActionBar.TranslucentDecor" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.NoActionBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Panel" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.SearchBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light.Voice" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Light" />
+  <java-symbol type="style" name="Theme.DeviceDefault.NoActionBar.Fullscreen" />
+  <java-symbol type="style" name="Theme.DeviceDefault.NoActionBar.Overscan" />
+  <java-symbol type="style" name="Theme.DeviceDefault.NoActionBar.TranslucentDecor" />
+  <java-symbol type="style" name="Theme.DeviceDefault.NoActionBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Notification" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Panel" />
+  <java-symbol type="style" name="Theme.DeviceDefault.ResolverCommon" />
+  <java-symbol type="style" name="Theme.DeviceDefault.SearchBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Settings.Dark.NoActionBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Settings.Dialog.Alert" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Settings.Dialog.NoActionBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Settings.Dialog" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Settings.DialogBase" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Settings.DialogWhenLarge" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Settings" />
+  <java-symbol type="style" name="Theme.DeviceDefault.System.Dialog.Alert" />
+  <java-symbol type="style" name="Theme.DeviceDefault.System.Dialog" />
+  <java-symbol type="style" name="Theme.DeviceDefault.SystemUI.Dialog" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Wallpaper.NoTitleBar" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Wallpaper" />
+  <java-symbol type="style" name="Theme.DeviceDefault" />
+  <java-symbol type="style" name="Theme.DeviceDefaultBase" />
+  <java-symbol type="style" name="ThemeOverlay.DeviceDefault.Accent" />
+  <java-symbol type="style" name="ThemeOverlay.DeviceDefault.Accent.Light" />
+  <java-symbol type="style" name="ThemeOverlay.DeviceDefault.Dark.ActionBar.Accent" />
 </resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 7068453..a2d54b2 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -270,11 +270,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -282,6 +280,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault" parent="Theme.DeviceDefaultBase" />
@@ -364,11 +365,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -376,6 +375,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar.  This theme
@@ -457,11 +459,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -469,6 +469,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar and
@@ -552,11 +555,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -564,6 +565,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} that has no title bar and translucent
@@ -646,11 +650,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -658,6 +660,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- DeviceDefault theme for dialog windows and activities. This changes the window to be
@@ -748,11 +753,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -760,6 +763,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a
@@ -841,11 +847,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -853,6 +857,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar -->
@@ -933,11 +940,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -945,6 +950,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width
@@ -1026,11 +1034,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -1038,6 +1044,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -1135,11 +1144,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -1147,6 +1154,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- DeviceDefault theme for a window without an action bar that will be displayed either
@@ -1229,11 +1239,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -1241,6 +1249,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- DeviceDefault theme for a presentation window on a secondary display. -->
@@ -1321,11 +1332,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -1333,6 +1342,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- DeviceDefault theme for panel windows. This removes all extraneous window
@@ -1415,11 +1427,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -1427,6 +1437,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -1508,11 +1521,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -1520,6 +1531,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -1601,11 +1615,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -1613,6 +1625,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- DeviceDefault style for input methods, which is used by the
@@ -1694,11 +1709,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -1706,6 +1719,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- DeviceDefault style for input methods, which is used by the
@@ -1787,11 +1803,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -1799,6 +1813,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Material.Dialog.Alert">
@@ -1880,11 +1897,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -1892,6 +1907,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- Theme for the dialog shown when an app crashes or ANRs. -->
@@ -1978,11 +1996,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -1990,6 +2006,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame">
@@ -2069,11 +2088,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -2081,6 +2098,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with a light-colored style -->
@@ -2298,11 +2318,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -2310,6 +2328,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of the DeviceDefault (light) theme that has a solid (opaque) action bar with an
@@ -2391,11 +2412,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -2403,6 +2422,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar -->
@@ -2483,11 +2505,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -2495,6 +2515,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar.
@@ -2576,11 +2599,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -2588,6 +2609,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar
@@ -2671,11 +2695,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -2683,6 +2705,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} that has no title bar and translucent
@@ -2765,11 +2790,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -2777,6 +2800,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be
@@ -2865,11 +2891,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -2877,6 +2901,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} that has a nice minimum width for a
@@ -2961,11 +2988,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -2973,6 +2998,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} without an action bar -->
@@ -3056,11 +3084,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3068,6 +3094,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog_NoActionBar} that has a nice minimum
@@ -3152,11 +3181,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3164,6 +3191,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -3229,11 +3259,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3241,6 +3269,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog.NoActionBar that has a fixed size. -->
@@ -3306,11 +3337,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3318,6 +3347,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- DeviceDefault light theme for a window that will be displayed either full-screen on smaller
@@ -3402,11 +3434,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3414,6 +3444,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- DeviceDefault light theme for a window without an action bar that will be displayed either
@@ -3499,11 +3532,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3511,6 +3542,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- DeviceDefault light theme for a presentation window on a secondary display. -->
@@ -3594,11 +3628,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3606,6 +3638,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- DeviceDefault light theme for panel windows. This removes all extraneous window
@@ -3688,11 +3723,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3700,6 +3733,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Material.Light.Dialog.Alert">
@@ -3781,11 +3817,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3793,6 +3827,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.Alert.DayNight" parent="Theme.DeviceDefault.Light.Dialog.Alert" />
@@ -3874,11 +3911,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3886,6 +3921,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Voice" parent="Theme.Material.Light.Voice">
@@ -3965,11 +4003,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -3977,6 +4013,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- DeviceDefault theme for a window that should look like the Settings app.  -->
@@ -4063,11 +4102,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -4075,7 +4112,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.SystemUI" parent="Theme.DeviceDefault.Light">
@@ -4143,11 +4182,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -4155,7 +4192,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.SystemUI.Dialog" parent="Theme.DeviceDefault.Light.Dialog">
@@ -4215,11 +4254,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -4227,7 +4264,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Settings_Dark} with no action bar -->
@@ -4309,11 +4348,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -4321,6 +4358,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.DialogBase" parent="Theme.Material.Light.BaseDialog">
@@ -4386,11 +4426,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -4398,7 +4436,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
-
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog" parent="Theme.DeviceDefault.Settings.DialogBase">
@@ -4504,11 +4544,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -4516,6 +4554,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.Alert">
@@ -4599,11 +4640,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -4611,6 +4650,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog.NoActionBar" parent="Theme.DeviceDefault.Light.Dialog.NoActionBar" />
@@ -4720,11 +4762,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -4732,7 +4772,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
-
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <style name="ThemeOverlay.DeviceDefault.Accent.Light">
@@ -4772,11 +4814,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -4784,6 +4824,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <!-- Theme overlay that replaces colorAccent with the colorAccent from {@link #Theme_DeviceDefault_DayNight}. -->
@@ -4827,11 +4870,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -4839,6 +4880,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" parent="Theme.DeviceDefault.NoActionBar.Fullscreen">
@@ -4878,11 +4922,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_light</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_light</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_light</item>
-        <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorOnError">@color/system_on_error_light</item>
         <item name="materialColorSurface">@color/system_surface_light</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_light</item>
-        <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
         <item name="materialColorOutline">@color/system_outline_light</item>
@@ -4890,6 +4932,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_light</item>
         <item name="materialColorOnSurface">@color/system_on_surface_light</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
+        <item name="materialColorPrimary">@color/system_primary_light</item>
+        <item name="materialColorSecondary">@color/system_secondary_light</item>
+        <item name="materialColorTertiary">@color/system_tertiary_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Notification" parent="@style/Theme.Material.Notification">
@@ -4940,11 +4985,9 @@
         <item name="materialColorOnTertiary">@color/system_on_tertiary_dark</item>
         <item name="materialColorSurfaceDim">@color/system_surface_dim_dark</item>
         <item name="materialColorSurfaceBright">@color/system_surface_bright_dark</item>
-        <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorOnError">@color/system_on_error_dark</item>
         <item name="materialColorSurface">@color/system_surface_dark</item>
         <item name="materialColorSurfaceContainerHigh">@color/system_surface_container_high_dark</item>
-        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
         <item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
         <item name="materialColorOutline">@color/system_outline_dark</item>
@@ -4952,6 +4995,9 @@
         <item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
         <item name="materialColorOnSurface">@color/system_on_surface_dark</item>
         <item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
+        <item name="materialColorPrimary">@color/system_primary_dark</item>
+        <item name="materialColorSecondary">@color/system_secondary_dark</item>
+        <item name="materialColorTertiary">@color/system_tertiary_dark</item>
     </style>
     <style name="Theme.DeviceDefault.AutofillHalfScreenDialogList" parent="Theme.DeviceDefault.DayNight">
         <item name="colorListDivider">@color/list_divider_opacity_device_default_light</item>
diff --git a/core/tests/coretests/res/drawable-nodpi/test_too_big.png b/core/tests/coretests/res/drawable-nodpi/test_too_big.png
new file mode 100644
index 0000000..3754072
--- /dev/null
+++ b/core/tests/coretests/res/drawable-nodpi/test_too_big.png
Binary files differ
diff --git a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
index a53d57f..a102b3e 100644
--- a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
+++ b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
@@ -1127,6 +1127,31 @@
         mActivityRule.runOnUiThread(() -> {});
     }
 
+    @Test
+    public void restartValueAnimator() throws Throwable {
+        CountDownLatch latch = new CountDownLatch(1);
+        ValueAnimator.AnimatorUpdateListener listener = new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                if (((float) animation.getAnimatedValue()) != A1_START_VALUE) {
+                    latch.countDown();
+                }
+            }
+        };
+        a1.addUpdateListener(listener);
+
+        mActivityRule.runOnUiThread(() -> {
+            a1.start();
+        });
+
+        // wait for a change in the value
+        assertTrue(latch.await(2, TimeUnit.SECONDS));
+
+        mActivityRule.runOnUiThread(() -> {
+            a1.start();
+            assertEquals(A1_START_VALUE, a1.getAnimatedValue());
+        });
+    }
     class MyUpdateListener implements ValueAnimator.AnimatorUpdateListener {
         boolean wasRunning = false;
         long firstRunningFrameTime = -1;
diff --git a/core/tests/coretests/src/android/graphics/drawable/IconTest.java b/core/tests/coretests/src/android/graphics/drawable/IconTest.java
index 75390a2..5d92296 100644
--- a/core/tests/coretests/src/android/graphics/drawable/IconTest.java
+++ b/core/tests/coretests/src/android/graphics/drawable/IconTest.java
@@ -20,6 +20,7 @@
 
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
 import android.graphics.Region;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -371,6 +372,90 @@
         }
     }
 
+    private int getMaxWidth(int origWidth, int origHeight, int maxNumPixels) {
+        float aspRatio = (float) origWidth / (float) origHeight;
+        int newHeight = (int) Math.sqrt(maxNumPixels / aspRatio);
+        return (int) (newHeight * aspRatio);
+    }
+
+    private int getMaxHeight(int origWidth, int origHeight, int maxNumPixels) {
+        float aspRatio = (float) origWidth / (float) origHeight;
+        return (int) Math.sqrt(maxNumPixels / aspRatio);
+    }
+
+    @SmallTest
+    public void testScaleDownMaxSizeWithBitmap() throws Exception {
+        final int bmpWidth = 13_000;
+        final int bmpHeight = 10_000;
+        final int bmpBpp = 4;
+        final int maxNumPixels = RecordingCanvas.MAX_BITMAP_SIZE / bmpBpp;
+        final int maxWidth = getMaxWidth(bmpWidth, bmpHeight, maxNumPixels);
+        final int maxHeight = getMaxHeight(bmpWidth, bmpHeight, maxNumPixels);
+
+        final Bitmap bm = Bitmap.createBitmap(bmpWidth, bmpHeight, Bitmap.Config.ARGB_8888);
+        final Icon ic = Icon.createWithBitmap(bm);
+        final Drawable drawable = ic.loadDrawable(mContext);
+
+        assertThat(drawable.getIntrinsicWidth()).isEqualTo(maxWidth);
+        assertThat(drawable.getIntrinsicHeight()).isEqualTo(maxHeight);
+    }
+
+    @SmallTest
+    public void testScaleDownMaxSizeWithAdaptiveBitmap() throws Exception {
+        final int bmpWidth = 20_000;
+        final int bmpHeight = 10_000;
+        final int bmpBpp = 4;
+        final int maxNumPixels = RecordingCanvas.MAX_BITMAP_SIZE / bmpBpp;
+        final int maxWidth = getMaxWidth(bmpWidth, bmpHeight, maxNumPixels);
+        final int maxHeight = getMaxHeight(bmpWidth, bmpHeight, maxNumPixels);
+
+        final Bitmap bm = Bitmap.createBitmap(bmpWidth, bmpHeight, Bitmap.Config.ARGB_8888);
+        final Icon ic = Icon.createWithAdaptiveBitmap(bm);
+        final AdaptiveIconDrawable adaptiveDrawable = (AdaptiveIconDrawable) ic.loadDrawable(
+                mContext);
+        final Drawable drawable = adaptiveDrawable.getForeground();
+
+        assertThat(drawable.getIntrinsicWidth()).isEqualTo(maxWidth);
+        assertThat(drawable.getIntrinsicHeight()).isEqualTo(maxHeight);
+    }
+
+    @SmallTest
+    public void testScaleDownMaxSizeWithResource() throws Exception {
+        final Icon ic = Icon.createWithResource(getContext(), R.drawable.test_too_big);
+        final BitmapDrawable drawable = (BitmapDrawable) ic.loadDrawable(mContext);
+
+        assertThat(drawable.getBitmap().getByteCount()).isAtMost(RecordingCanvas.MAX_BITMAP_SIZE);
+    }
+
+    @SmallTest
+    public void testScaleDownMaxSizeWithFile() throws Exception {
+        final Bitmap bit1 = ((BitmapDrawable) getContext().getDrawable(R.drawable.test_too_big))
+                .getBitmap();
+        final File dir = getContext().getExternalFilesDir(null);
+        final File file1 = new File(dir, "file1-too-big.png");
+        bit1.compress(Bitmap.CompressFormat.PNG, 100,
+                new FileOutputStream(file1));
+
+        final Icon ic = Icon.createWithFilePath(file1.toString());
+        final BitmapDrawable drawable = (BitmapDrawable) ic.loadDrawable(mContext);
+
+        assertThat(drawable.getBitmap().getByteCount()).isAtMost(RecordingCanvas.MAX_BITMAP_SIZE);
+    }
+
+    @SmallTest
+    public void testScaleDownMaxSizeWithData() throws Exception {
+        final int bmpBpp = 4;
+        final Bitmap originalBits = ((BitmapDrawable) getContext().getDrawable(
+                R.drawable.test_too_big)).getBitmap();
+        final ByteArrayOutputStream ostream = new ByteArrayOutputStream(
+                originalBits.getWidth() * originalBits.getHeight() * bmpBpp);
+        originalBits.compress(Bitmap.CompressFormat.PNG, 100, ostream);
+        final byte[] pngdata = ostream.toByteArray();
+        final Icon ic = Icon.createWithData(pngdata, 0, pngdata.length);
+        final BitmapDrawable drawable = (BitmapDrawable) ic.loadDrawable(mContext);
+
+        assertThat(drawable.getBitmap().getByteCount()).isAtMost(RecordingCanvas.MAX_BITMAP_SIZE);
+    }
 
     // ======== utils ========
 
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index f233c6e..6a1f3f9 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -54,6 +54,12 @@
     src: "hiddenapi-package-whitelist.xml",
 }
 
+prebuilt_etc {
+    name: "preinstalled-packages-asl-files.xml",
+    sub_dir: "sysconfig",
+    src: "preinstalled-packages-asl-files.xml",
+}
+
 // Privapp permission whitelist files
 
 prebuilt_etc {
diff --git a/data/etc/preinstalled-packages-asl-files.xml b/data/etc/preinstalled-packages-asl-files.xml
new file mode 100644
index 0000000..6b5401c
--- /dev/null
+++ b/data/etc/preinstalled-packages-asl-files.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!--
+This XML file declares which preinstalled apps have Android Security Label data by declaring the
+path to the XML file containing this data.
+
+Example usage:
+    <asl-file package="com.foo.bar" path="/vendor/etc/asl/com.foo.bar.xml"/>
+-->
+
+<config></config>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 8ece337..40cb7f2 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -518,6 +518,8 @@
         <permission name="android.permission.LOG_FOREGROUND_RESOURCE_USE"/>
         <!-- Permission required for CTS test - CtsVoiceInteractionTestCases -->
         <permission name="android.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER"/>
+        <!-- Permission required for CTS test - SatelliteManagerTest -->
+        <permission name="android.permission.SATELLITE_COMMUNICATION"/>
     </privapp-permissions>
 
     <privapp-permissions package="com.android.statementservice">
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index a76d74e..708feeb 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -35,6 +35,7 @@
 import android.graphics.BitmapFactory;
 import android.graphics.BlendMode;
 import android.graphics.PorterDuff;
+import android.graphics.RecordingCanvas;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Build;
@@ -70,6 +71,7 @@
 
 public final class Icon implements Parcelable {
     private static final String TAG = "Icon";
+    private static final boolean DEBUG = false;
 
     /**
      * An icon that was created using {@link Icon#createWithBitmap(Bitmap)}.
@@ -361,15 +363,52 @@
     }
 
     /**
+     * Resizes image if size too large for Canvas to draw
+     * @param bitmap Bitmap to be resized if size > {@link RecordingCanvas.MAX_BITMAP_SIZE}
+     * @return resized bitmap
+     */
+    private Bitmap fixMaxBitmapSize(Bitmap bitmap) {
+        if (bitmap != null && bitmap.getByteCount() > RecordingCanvas.MAX_BITMAP_SIZE) {
+            int bytesPerPixel = bitmap.getRowBytes() / bitmap.getWidth();
+            int maxNumPixels = RecordingCanvas.MAX_BITMAP_SIZE / bytesPerPixel;
+            float aspRatio = (float) bitmap.getWidth() / (float) bitmap.getHeight();
+            int newHeight = (int) Math.sqrt(maxNumPixels / aspRatio);
+            int newWidth = (int) (newHeight * aspRatio);
+
+            if (DEBUG) {
+                Log.d(TAG,
+                        "Image size too large: " + bitmap.getByteCount() + ". Resizing bitmap to: "
+                                + newWidth + " " + newHeight);
+            }
+
+            return scaleDownIfNecessary(bitmap, newWidth, newHeight);
+        }
+        return bitmap;
+    }
+
+    /**
+     * Resizes BitmapDrawable if size too large for Canvas to draw
+     * @param drawable Drawable to be resized if size > {@link RecordingCanvas.MAX_BITMAP_SIZE}
+     * @return resized Drawable
+     */
+    private Drawable fixMaxBitmapSize(Resources res, Drawable drawable) {
+        if (drawable instanceof BitmapDrawable) {
+            Bitmap scaledBmp = fixMaxBitmapSize(((BitmapDrawable) drawable).getBitmap());
+            return new BitmapDrawable(res, scaledBmp);
+        }
+        return drawable;
+    }
+
+    /**
      * Do the heavy lifting of loading the drawable, but stop short of applying any tint.
      */
     private Drawable loadDrawableInner(Context context) {
         switch (mType) {
             case TYPE_BITMAP:
-                return new BitmapDrawable(context.getResources(), getBitmap());
+                return new BitmapDrawable(context.getResources(), fixMaxBitmapSize(getBitmap()));
             case TYPE_ADAPTIVE_BITMAP:
                 return new AdaptiveIconDrawable(null,
-                    new BitmapDrawable(context.getResources(), getBitmap()));
+                    new BitmapDrawable(context.getResources(), fixMaxBitmapSize(getBitmap())));
             case TYPE_RESOURCE:
                 if (getResources() == null) {
                     // figure out where to load resources from
@@ -400,7 +439,8 @@
                     }
                 }
                 try {
-                    return getResources().getDrawable(getResId(), context.getTheme());
+                    return fixMaxBitmapSize(getResources(),
+                            getResources().getDrawable(getResId(), context.getTheme()));
                 } catch (RuntimeException e) {
                     Log.e(TAG, String.format("Unable to load resource 0x%08x from pkg=%s",
                                     getResId(),
@@ -409,21 +449,21 @@
                 }
                 break;
             case TYPE_DATA:
-                return new BitmapDrawable(context.getResources(),
-                    BitmapFactory.decodeByteArray(getDataBytes(), getDataOffset(), getDataLength())
-                );
+                return new BitmapDrawable(context.getResources(), fixMaxBitmapSize(
+                        BitmapFactory.decodeByteArray(getDataBytes(), getDataOffset(),
+                                getDataLength())));
             case TYPE_URI:
                 InputStream is = getUriInputStream(context);
                 if (is != null) {
                     return new BitmapDrawable(context.getResources(),
-                            BitmapFactory.decodeStream(is));
+                            fixMaxBitmapSize(BitmapFactory.decodeStream(is)));
                 }
                 break;
             case TYPE_URI_ADAPTIVE_BITMAP:
                 is = getUriInputStream(context);
                 if (is != null) {
                     return new AdaptiveIconDrawable(null, new BitmapDrawable(context.getResources(),
-                            BitmapFactory.decodeStream(is)));
+                            fixMaxBitmapSize(BitmapFactory.decodeStream(is))));
                 }
                 break;
         }
diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml b/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
index dcce4698..ab64f9e 100644
--- a/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
@@ -67,7 +67,7 @@
 
     <!-- Temporarily extending the background to show an edu text hint for opening the menu -->
     <FrameLayout
-        android:id="@+id/tv_pip_menu_edu_text_drawer_placeholder"
+        android:id="@+id/tv_pip_menu_edu_text_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_below="@+id/tv_pip"
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 47d3a5c..dc27ceb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -20,6 +20,9 @@
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;
 import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_BACK_ANIMATION;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityTaskManager;
@@ -37,7 +40,9 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings.Global;
+import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.MathUtils;
 import android.util.SparseArray;
 import android.view.IRemoteAnimationRunner;
 import android.view.InputDevice;
@@ -56,6 +61,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.view.AppearanceRegion;
+import com.android.wm.shell.animation.FlingAnimationUtils;
 import com.android.wm.shell.common.ExternalInterfaceBinder;
 import com.android.wm.shell.common.RemoteCallable;
 import com.android.wm.shell.common.ShellExecutor;
@@ -80,6 +86,17 @@
     public static boolean IS_U_ANIMATION_ENABLED =
             SystemProperties.getInt("persist.wm.debug.predictive_back_anim",
                     SETTING_VALUE_ON) == SETTING_VALUE_ON;
+
+    public static final float FLING_MAX_LENGTH_SECONDS = 0.1f;     // 100ms
+    public static final float FLING_SPEED_UP_FACTOR = 0.6f;
+
+    /**
+     * The maximum additional progress in case of fling gesture.
+     * The end animation starts after the user lifts the finger from the screen, we continue to
+     * fire {@link BackEvent}s until the velocity reaches 0.
+     */
+    private static final float MAX_FLING_PROGRESS = 0.3f; /* 30% of the screen */
+
     /** Predictive back animation developer option */
     private final AtomicBoolean mEnableAnimations = new AtomicBoolean(false);
     /**
@@ -96,6 +113,7 @@
     private boolean mShouldStartOnNextMoveEvent = false;
     /** @see #setTriggerBack(boolean) */
     private boolean mTriggerBack;
+    private FlingAnimationUtils mFlingAnimationUtils;
 
     @Nullable
     private BackNavigationInfo mBackNavigationInfo;
@@ -174,6 +192,11 @@
         mBgHandler = bgHandler;
         shellInit.addInitCallback(this::onInit, this);
         mAnimationBackground = backAnimationBackground;
+        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
+        mFlingAnimationUtils = new FlingAnimationUtils.Builder(displayMetrics)
+                .setMaxLengthSeconds(FLING_MAX_LENGTH_SECONDS)
+                .setSpeedUpFactor(FLING_SPEED_UP_FACTOR)
+                .build();
     }
 
     @VisibleForTesting
@@ -465,6 +488,78 @@
         }
     }
 
+
+    /**
+     * Allows us to manage the fling gesture, it smoothly animates the current progress value to
+     * the final position, calculated based on the current velocity.
+     *
+     * @param callback the callback to be invoked when the animation ends.
+     */
+    private void dispatchOrAnimateOnBackInvoked(IOnBackInvokedCallback callback) {
+        if (callback == null) {
+            return;
+        }
+
+        boolean animationStarted = false;
+
+        if (mBackNavigationInfo != null && mBackNavigationInfo.isAnimationCallback()) {
+
+            final BackMotionEvent backMotionEvent = mTouchTracker.createProgressEvent();
+            if (backMotionEvent != null) {
+                // Constraints - absolute values
+                float minVelocity = mFlingAnimationUtils.getMinVelocityPxPerSecond();
+                float maxVelocity = mFlingAnimationUtils.getHighVelocityPxPerSecond();
+                float maxX = mTouchTracker.getMaxX(); // px
+                float maxFlingDistance = maxX * MAX_FLING_PROGRESS; // px
+
+                // Current state
+                float currentX = backMotionEvent.getTouchX();
+                float velocity = MathUtils.constrain(backMotionEvent.getVelocityX(),
+                        -maxVelocity, maxVelocity);
+
+                // Target state
+                float animationFaction = velocity / maxVelocity; // value between -1 and 1
+                float flingDistance = animationFaction * maxFlingDistance; // px
+                float endX = MathUtils.constrain(currentX + flingDistance, 0f, maxX);
+
+                if (!Float.isNaN(endX)
+                        && currentX != endX
+                        && Math.abs(velocity) >= minVelocity) {
+                    ValueAnimator animator = ValueAnimator.ofFloat(currentX, endX);
+
+                    mFlingAnimationUtils.apply(
+                            /* animator = */ animator,
+                            /* currValue = */ currentX,
+                            /* endValue = */ endX,
+                            /* velocity = */ velocity,
+                            /* maxDistance = */ maxFlingDistance
+                    );
+
+                    animator.addUpdateListener(animation -> {
+                        Float animatedValue = (Float) animation.getAnimatedValue();
+                        float progress = mTouchTracker.getProgress(animatedValue);
+                        final BackMotionEvent backEvent = mTouchTracker
+                                .createProgressEvent(progress);
+                        dispatchOnBackProgressed(mActiveCallback, backEvent);
+                    });
+
+                    animator.addListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            dispatchOnBackInvoked(callback);
+                        }
+                    });
+                    animator.start();
+                    animationStarted = true;
+                }
+            }
+        }
+
+        if (!animationStarted) {
+            dispatchOnBackInvoked(callback);
+        }
+    }
+
     private void dispatchOnBackInvoked(IOnBackInvokedCallback callback) {
         if (callback == null) {
             return;
@@ -530,7 +625,7 @@
         if (mBackNavigationInfo != null) {
             final IOnBackInvokedCallback callback = mBackNavigationInfo.getOnBackInvokedCallback();
             if (mTriggerBack) {
-                dispatchOnBackInvoked(callback);
+                dispatchOrAnimateOnBackInvoked(callback);
             } else {
                 dispatchOnBackCancelled(callback);
             }
@@ -605,7 +700,7 @@
 
         // The next callback should be {@link #onBackAnimationFinished}.
         if (mTriggerBack) {
-            dispatchOnBackInvoked(mActiveCallback);
+            dispatchOrAnimateOnBackInvoked(mActiveCallback);
         } else {
             dispatchOnBackCancelled(mActiveCallback);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
index 904574b..7a00f5b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
@@ -16,7 +16,10 @@
 
 package com.android.wm.shell.back;
 
+import android.annotation.FloatRange;
 import android.os.SystemProperties;
+import android.util.MathUtils;
+import android.view.MotionEvent;
 import android.view.RemoteAnimationTarget;
 import android.window.BackEvent;
 import android.window.BackMotionEvent;
@@ -99,28 +102,42 @@
     }
 
     BackMotionEvent createProgressEvent() {
-        float progressThreshold = PROGRESS_THRESHOLD >= 0
-                ? PROGRESS_THRESHOLD : mProgressThreshold;
-        progressThreshold = progressThreshold == 0 ? 1 : progressThreshold;
         float progress = 0;
         // Progress is always 0 when back is cancelled and not restarted.
         if (!mCancelled) {
-            // If back is committed, progress is the distance between the last and first touch
-            // point, divided by the max drag distance. Otherwise, it's the distance between
-            // the last touch point and the starting threshold, divided by max drag distance.
-            // The starting threshold is initially the first touch location, and updated to
-            // the location everytime back is restarted after being cancelled.
-            float startX = mTriggerBack ? mInitTouchX : mStartThresholdX;
-            float deltaX = Math.max(
-                    mSwipeEdge == BackEvent.EDGE_LEFT
-                            ? mLatestTouchX - startX
-                            : startX - mLatestTouchX,
-                    0);
-            progress = Math.min(Math.max(deltaX / progressThreshold, 0), 1);
+            progress = getProgress(mLatestTouchX);
         }
         return createProgressEvent(progress);
     }
 
+    /**
+     * Progress value computed from the touch position.
+     *
+     * @param touchX the X touch position of the {@link MotionEvent}.
+     * @return progress value
+     */
+    @FloatRange(from = 0.0, to = 1.0)
+    float getProgress(float touchX) {
+        // If back is committed, progress is the distance between the last and first touch
+        // point, divided by the max drag distance. Otherwise, it's the distance between
+        // the last touch point and the starting threshold, divided by max drag distance.
+        // The starting threshold is initially the first touch location, and updated to
+        // the location everytime back is restarted after being cancelled.
+        float startX = mTriggerBack ? mInitTouchX : mStartThresholdX;
+        float deltaX = Math.abs(startX - touchX);
+        float maxX = getMaxX();
+        maxX = maxX == 0 ? 1 : maxX;
+        return MathUtils.constrain(deltaX / maxX, 0, 1);
+    }
+
+    /**
+     * Maximum X value (in pixels).
+     * Progress is considered to be completed (1f) when this limit is exceeded.
+     */
+    float getMaxX() {
+        return PROGRESS_THRESHOLD >= 0 ? PROGRESS_THRESHOLD : mProgressThreshold;
+    }
+
     BackMotionEvent createProgressEvent(float progress) {
         return new BackMotionEvent(
                 /* touchX = */ mLatestTouchX,
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 713ace6..b6216b3 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
@@ -623,11 +623,11 @@
      * Removes PiP immediately.
      */
     public void removePip() {
-        if (!mPipTransitionState.isInPip() || mToken == null) {
+        if (!mPipTransitionState.isInPip() || mToken == null || mLeash == null) {
             ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                     "%s: Not allowed to removePip in current state"
-                            + " mState=%d mToken=%s", TAG, mPipTransitionState.getTransitionState(),
-                    mToken);
+                            + " mState=%d mToken=%s mLeash=%s", TAG,
+                    mPipTransitionState.getTransitionState(), mToken, mLeash);
             return;
         }
 
@@ -1532,6 +1532,9 @@
             if (snapshotSurface != null) {
                 mSyncTransactionQueue.queue(wct);
                 mSyncTransactionQueue.runInSync(t -> {
+                    // reset the pinch gesture
+                    maybePerformFinishResizeCallback();
+
                     // Scale the snapshot from its pre-resize bounds to the post-resize bounds.
                     mSurfaceTransactionHelper.scale(t, snapshotSurface, preResizeBounds,
                             snapshotDest);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipAction.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipAction.java
index 222307f..5f6b3fe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipAction.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipAction.java
@@ -31,6 +31,12 @@
 
 abstract class TvPipAction {
 
+    /**
+     * Extras key for adding a boolean to the {@link Notification.Action} to differentiate custom
+     * from system actions, most importantly to identify custom close actions.
+     **/
+    public static final String EXTRA_IS_PIP_CUSTOM_ACTION = "EXTRA_IS_PIP_CUSTOM_ACTION";
+
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"ACTION_"}, value = {
             ACTION_FULLSCREEN,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java
index bca27a5..977aad4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java
@@ -86,7 +86,7 @@
         Bundle extras = new Bundle();
         extras.putCharSequence(Notification.EXTRA_PICTURE_CONTENT_DESCRIPTION,
                 mRemoteAction.getContentDescription());
-        extras.putBoolean(Notification.EXTRA_CONTAINS_CUSTOM_VIEW, true);
+        extras.putBoolean(TvPipAction.EXTRA_IS_PIP_CUSTOM_ACTION, true);
         builder.addExtras(extras);
 
         builder.setSemanticAction(isCloseAction()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java
index 6eef225..f86f987 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java
@@ -23,6 +23,7 @@
 
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE;
 
+import android.animation.Animator;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
@@ -115,6 +116,10 @@
         scheduleLifecycleEvents();
     }
 
+    int getEduTextDrawerHeight() {
+        return getVisibility() == GONE ? 0 : getHeight();
+    }
+
     private void scheduleLifecycleEvents() {
         final int startScrollDelay = mContext.getResources().getInteger(
                 R.integer.pip_edu_text_start_scroll_delay);
@@ -226,20 +231,41 @@
                 .start();
 
         // Start animation to close the drawer by animating its height to 0
-        final ValueAnimator heightAnimation = ValueAnimator.ofInt(getHeight(), 0);
-        heightAnimation.setDuration(eduTextSlideExitAnimationDuration);
-        heightAnimation.setInterpolator(TvPipInterpolators.BROWSE);
-        heightAnimation.addUpdateListener(animator -> {
+        final ValueAnimator heightAnimator = ValueAnimator.ofInt(getHeight(), 0);
+        heightAnimator.setDuration(eduTextSlideExitAnimationDuration);
+        heightAnimator.setInterpolator(TvPipInterpolators.BROWSE);
+        heightAnimator.addUpdateListener(animator -> {
             final ViewGroup.LayoutParams params = getLayoutParams();
             params.height = (int) animator.getAnimatedValue();
             setLayoutParams(params);
-            if (params.height == 0) {
-                setVisibility(GONE);
+        });
+        heightAnimator.addListener(new Animator.AnimatorListener() {
+            @Override
+            public void onAnimationStart(@NonNull Animator animator) {
+            }
+
+            @Override
+            public void onAnimationEnd(@NonNull Animator animator) {
+                onCloseEduTextAnimationEnd();
+            }
+
+            @Override
+            public void onAnimationCancel(@NonNull Animator animator) {
+                onCloseEduTextAnimationEnd();
+            }
+
+            @Override
+            public void onAnimationRepeat(@NonNull Animator animator) {
             }
         });
-        heightAnimation.start();
+        heightAnimator.start();
 
-        mListener.onCloseEduText();
+        mListener.onCloseEduTextAnimationStart();
+    }
+
+    public void onCloseEduTextAnimationEnd() {
+        setVisibility(GONE);
+        mListener.onCloseEduTextAnimationEnd();
     }
 
     /**
@@ -270,11 +296,8 @@
      * A listener for edu text drawer event states.
      */
     interface Listener {
-        /**
-         *  The edu text closing impacts the size of the Picture-in-Picture window and influences
-         *  how it is positioned on the screen.
-         */
-        void onCloseEduText();
+        void onCloseEduTextAnimationStart();
+        void onCloseEduTextAnimationEnd();
     }
 
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
index 6eb719b..d076418 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
@@ -57,7 +57,8 @@
  * A View that represents Pip Menu on TV. It's responsible for displaying the Pip menu actions from
  * the TvPipActionsProvider as well as the buttons for manually moving the PiP.
  */
-public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.Listener {
+public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.Listener,
+        TvPipMenuEduTextDrawer.Listener {
     private static final String TAG = "TvPipMenuView";
 
     private final TvPipMenuView.Listener mListener;
@@ -76,6 +77,7 @@
     private final View mDimLayer;
 
     private final TvPipMenuEduTextDrawer mEduTextDrawer;
+    private final ViewGroup mEduTextContainer;
 
     private final int mPipMenuOuterSpace;
     private final int mPipMenuBorderWidth;
@@ -139,9 +141,9 @@
         mPipMenuBorderWidth = context.getResources()
                 .getDimensionPixelSize(R.dimen.pip_menu_border_width);
 
-        mEduTextDrawer = new TvPipMenuEduTextDrawer(mContext, mainHandler, mListener);
-        ((FrameLayout) findViewById(R.id.tv_pip_menu_edu_text_drawer_placeholder))
-                .addView(mEduTextDrawer);
+        mEduTextDrawer = new TvPipMenuEduTextDrawer(mContext, mainHandler, this);
+        mEduTextContainer = (ViewGroup) findViewById(R.id.tv_pip_menu_edu_text_container);
+        mEduTextContainer.addView(mEduTextDrawer);
     }
 
     void onPipTransitionToTargetBoundsStarted(Rect targetBounds) {
@@ -235,11 +237,13 @@
      * pip menu when it gains focus.
      */
     private void updatePipFrameBounds() {
-        final ViewGroup.LayoutParams pipFrameParams = mPipFrameView.getLayoutParams();
-        if (pipFrameParams != null) {
-            pipFrameParams.width = mCurrentPipBounds.width() + 2 * mPipMenuBorderWidth;
-            pipFrameParams.height = mCurrentPipBounds.height() + 2 * mPipMenuBorderWidth;
-            mPipFrameView.setLayoutParams(pipFrameParams);
+        if (mPipFrameView.getVisibility() == VISIBLE) {
+            final ViewGroup.LayoutParams pipFrameParams = mPipFrameView.getLayoutParams();
+            if (pipFrameParams != null) {
+                pipFrameParams.width = mCurrentPipBounds.width() + 2 * mPipMenuBorderWidth;
+                pipFrameParams.height = mCurrentPipBounds.height() + 2 * mPipMenuBorderWidth;
+                mPipFrameView.setLayoutParams(pipFrameParams);
+            }
         }
 
         final ViewGroup.LayoutParams pipViewParams = mPipView.getLayoutParams();
@@ -262,7 +266,7 @@
     Rect getPipMenuContainerBounds(Rect pipBounds) {
         final Rect menuUiBounds = new Rect(pipBounds);
         menuUiBounds.inset(-mPipMenuOuterSpace, -mPipMenuOuterSpace);
-        menuUiBounds.bottom += mEduTextDrawer.getHeight();
+        menuUiBounds.bottom += mEduTextDrawer.getEduTextDrawerHeight();
         return menuUiBounds;
     }
 
@@ -406,6 +410,17 @@
     }
 
     @Override
+    public void onCloseEduTextAnimationStart() {
+        mListener.onCloseEduText();
+    }
+
+    @Override
+    public void onCloseEduTextAnimationEnd() {
+        mPipFrameView.setVisibility(GONE);
+        mEduTextContainer.setVisibility(GONE);
+    }
+
+    @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (event.getAction() == ACTION_UP) {
 
@@ -551,7 +566,7 @@
         }
     }
 
-    interface Listener extends TvPipMenuEduTextDrawer.Listener {
+    interface Listener {
 
         void onBackPress();
 
@@ -573,5 +588,11 @@
          * has lost focus.
          */
         void onPipWindowFocusChanged(boolean focused);
+
+        /**
+         *  The edu text closing impacts the size of the Picture-in-Picture window and influences
+         *  how it is positioned on the screen.
+         */
+        void onCloseEduText();
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
index c9b3a1a..c4a0e9c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/ShellProtoLogGroup.java
@@ -32,6 +32,8 @@
             Consts.TAG_WM_SHELL),
     WM_SHELL_TRANSITIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
             Consts.TAG_WM_SHELL),
+    WM_SHELL_RECENTS_TRANSITION(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
+            Consts.TAG_WM_SHELL),
     WM_SHELL_DRAG_AND_DROP(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
             Consts.TAG_WM_SHELL),
     WM_SHELL_STARTING_WINDOW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index a8b209f..b554872 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -47,7 +47,9 @@
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.util.TransitionUtil;
@@ -96,6 +98,8 @@
 
     void startRecentsTransition(PendingIntent intent, Intent fillIn, Bundle options,
             IApplicationThread appThread, IRecentsAnimationRunner listener) {
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                "RecentsTransitionHandler.startRecentsTransition");
         // only care about latest one.
         mAnimApp = appThread;
         WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -116,7 +120,7 @@
             mixer.setRecentsTransition(transition);
         }
         if (transition == null) {
-            controller.cancel();
+            controller.cancel("startRecentsTransition");
             return;
         }
         controller.setTransition(transition);
@@ -127,6 +131,7 @@
     public WindowContainerTransaction handleRequest(IBinder transition,
             TransitionRequestInfo request) {
         // do not directly handle requests. Only entry point should be via startRecentsTransition
+        Slog.e(TAG, "RecentsTransitionHandler.handleRequest: Unexpected transition request");
         return null;
     }
 
@@ -143,11 +148,17 @@
             SurfaceControl.Transaction finishTransaction,
             Transitions.TransitionFinishCallback finishCallback) {
         final int controllerIdx = findController(transition);
-        if (controllerIdx < 0) return false;
+        if (controllerIdx < 0) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                    "RecentsTransitionHandler.startAnimation: no controller found");
+            return false;
+        }
         final RecentsController controller = mControllers.get(controllerIdx);
         Transitions.setRunningRemoteTransitionDelegate(mAnimApp);
         mAnimApp = null;
         if (!controller.start(info, startTransaction, finishTransaction, finishCallback)) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                    "RecentsTransitionHandler.startAnimation: failed to start animation");
             return false;
         }
         return true;
@@ -168,7 +179,7 @@
             SurfaceControl.Transaction finishTransaction) {
         final int idx = findController(transition);
         if (idx < 0) return;
-        mControllers.get(idx).cancel();
+        mControllers.get(idx).cancel("onTransitionConsumed");
     }
 
     /** There is only one of these and it gets reset on finish. */
@@ -213,27 +224,38 @@
 
         RecentsController(IRecentsAnimationRunner listener) {
             mListener = listener;
-            mDeathHandler = () -> finish(mWillFinishToHome, false /* leaveHint */);
+            mDeathHandler = () -> {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "RecentsController.DeathRecipient: binder died");
+                finish(mWillFinishToHome, false /* leaveHint */);
+            };
             try {
                 mListener.asBinder().linkToDeath(mDeathHandler, 0 /* flags */);
             } catch (RemoteException e) {
+                Slog.e(TAG, "RecentsController: failed to link to death", e);
                 mListener = null;
             }
         }
 
         void setTransition(IBinder transition) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                    "RecentsController.setTransition: id=%s", transition);
             mTransition = transition;
         }
 
-        void cancel() {
+        void cancel(String reason) {
             // restoring (to-home = false) involves submitting more WM changes, so by default, use
             // toHome = true when canceling.
-            cancel(true /* toHome */);
+            cancel(true /* toHome */, reason);
         }
 
-        void cancel(boolean toHome) {
+        void cancel(boolean toHome, String reason) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                    "RecentsController.cancel: toHome=%b reason=%s", toHome, reason);
             if (mListener != null) {
                 try {
+                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                            "RecentsController.cancel: calling onAnimationCanceled");
                     mListener.onAnimationCanceled(null, null);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "Error canceling recents animation", e);
@@ -267,6 +289,8 @@
                 }
             }
             try {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "RecentsController.cancel: calling onAnimationCanceled with snapshots");
                 mListener.onAnimationCanceled(taskIds, snapshots);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Error canceling recents animation", e);
@@ -276,6 +300,7 @@
         }
 
         void cleanUp() {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "RecentsController.cleanup");
             if (mListener != null && mDeathHandler != null) {
                 mListener.asBinder().unlinkToDeath(mDeathHandler, 0 /* flags */);
                 mDeathHandler = null;
@@ -299,6 +324,7 @@
 
         boolean start(TransitionInfo info, SurfaceControl.Transaction t,
                 SurfaceControl.Transaction finishT, Transitions.TransitionFinishCallback finishCB) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "RecentsController.start");
             if (mListener == null || mTransition == null) {
                 cleanUp();
                 return false;
@@ -358,6 +384,8 @@
                             info.getChanges().size() - i, info, t, mLeashMap);
                     apps.add(target);
                     if (TransitionUtil.isClosingType(change.getMode())) {
+                        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                                "  adding pausing taskId=%d", taskInfo.taskId);
                         // raise closing (pausing) task to "above" layer so it isn't covered
                         t.setLayer(target.leash, info.getChanges().size() * 3 - i);
                         mPausingTasks.add(new TaskState(change, target.leash));
@@ -372,19 +400,23 @@
                     } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
                         // do nothing
                     } else if (TransitionUtil.isOpeningType(change.getMode())) {
+                        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                                "  adding opening taskId=%d", taskInfo.taskId);
                         mOpeningTasks.add(new TaskState(change, target.leash));
                     }
                 }
             }
             t.apply();
             try {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "RecentsController.start: calling onAnimationStart");
                 mListener.onAnimationStart(this,
                         apps.toArray(new RemoteAnimationTarget[apps.size()]),
                         wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]),
                         new Rect(0, 0, 0, 0), new Rect());
             } catch (RemoteException e) {
                 Slog.e(TAG, "Error starting recents animation", e);
-                cancel();
+                cancel("onAnimationStart() failed");
             }
             return true;
         }
@@ -393,14 +425,19 @@
         void merge(TransitionInfo info, SurfaceControl.Transaction t,
                 Transitions.TransitionFinishCallback finishCallback) {
             if (mFinishCB == null) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "RecentsController.merge: skip, no finish callback");
                 // This was no-op'd (likely a repeated start) and we've already sent finish.
                 return;
             }
             if (info.getType() == TRANSIT_SLEEP) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "RecentsController.merge: transit_sleep");
                 // A sleep event means we need to stop animations immediately, so cancel here.
-                cancel();
+                cancel("transit_sleep");
                 return;
             }
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "RecentsController.merge");
             ArrayList<TransitionInfo.Change> openingTasks = null;
             ArrayList<TransitionInfo.Change> closingTasks = null;
             mOpeningSeparateHome = false;
@@ -417,7 +454,7 @@
                         && taskInfo.configuration.windowConfiguration.isAlwaysOnTop()) {
                     // Tasks that are always on top (e.g. bubbles), will handle their own transition
                     // as they are on top of everything else. So cancel the merge here.
-                    cancel();
+                    cancel("task #" + taskInfo.taskId + " is always_on_top");
                     return;
                 }
                 hasTaskChange = hasTaskChange || taskInfo != null;
@@ -448,7 +485,7 @@
                     // Finish recents animation if the display is changed, so the default
                     // transition handler can play the animation such as rotation effect.
                     if (change.hasFlags(TransitionInfo.FLAG_IS_DISPLAY)) {
-                        cancel(mWillFinishToHome);
+                        cancel(mWillFinishToHome, "display change");
                         return;
                     }
                     // Don't consider order-only changes as changing apps.
@@ -492,7 +529,10 @@
                                 + " something unexpected: " + change.getTaskInfo().taskId);
                         continue;
                     }
-                    mPausingTasks.add(mOpeningTasks.remove(openingIdx));
+                    final TaskState openingTask = mOpeningTasks.remove(openingIdx);
+                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                            "  pausing opening taskId=%d", openingTask.mTaskInfo.taskId);
+                    mPausingTasks.add(openingTask);
                     didMergeThings = true;
                 }
             }
@@ -509,7 +549,10 @@
                         // Something is showing/opening a previously-pausing app.
                         appearedTargets[i] = TransitionUtil.newTarget(
                                 change, layer, mPausingTasks.get(pausingIdx).mLeash);
-                        mOpeningTasks.add(mPausingTasks.remove(pausingIdx));
+                        final TaskState pausingTask = mPausingTasks.remove(pausingIdx);
+                        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                                "  opening pausing taskId=%d", pausingTask.mTaskInfo.taskId);
+                        mOpeningTasks.add(pausingTask);
                         // Setup hides opening tasks initially, so make it visible again (since we
                         // are already showing it).
                         t.show(change.getLeash());
@@ -522,6 +565,8 @@
                         final int rootIdx = TransitionUtil.rootIndexFor(change, mInfo);
                         t.reparent(appearedTargets[i].leash, mInfo.getRoot(rootIdx).getLeash());
                         t.setLayer(appearedTargets[i].leash, layer);
+                        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                                "  opening new taskId=%d", appearedTargets[i].taskId);
                         mOpeningTasks.add(new TaskState(change, appearedTargets[i].leash));
                     }
                 }
@@ -539,7 +584,7 @@
                         + foundRecentsClosing);
                 if (foundRecentsClosing) {
                     mWillFinishToHome = false;
-                    cancel(false /* toHome */);
+                    cancel(false /* toHome */, "didn't merge");
                 }
                 return;
             }
@@ -549,6 +594,8 @@
             info.releaseAnimSurfaces();
             if (appearedTargets == null) return;
             try {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "RecentsController.merge: calling onTasksAppeared");
                 mListener.onTasksAppeared(appearedTargets);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Error sending appeared tasks to recents animation", e);
@@ -572,6 +619,8 @@
         @Override
         public TaskSnapshot screenshotTask(int taskId) {
             try {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                        "RecentsController.screenshotTask: taskId=%d", taskId);
                 return ActivityTaskManager.getService().takeTaskSnapshot(taskId);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Failed to screenshot task", e);
@@ -582,12 +631,19 @@
         @Override
         public void setInputConsumerEnabled(boolean enabled) {
             mExecutor.execute(() -> {
-                if (mFinishCB == null || !enabled) return;
+                if (mFinishCB == null || !enabled) {
+                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                            "RecentsController.setInputConsumerEnabled: skip, cb?=%b enabled?=%b",
+                            mFinishCB != null, enabled);
+                    return;
+                }
                 // transient launches don't receive focus automatically. Since we are taking over
                 // the gesture now, take focus explicitly.
                 // This also moves recents back to top if the user gestured before a switch
                 // animation finished.
                 try {
+                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                            "RecentsController.setInputConsumerEnabled: set focus to recents");
                     ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "Failed to set focused task", e);
@@ -602,6 +658,8 @@
         @Override
         public void setFinishTaskTransaction(int taskId,
                 PictureInPictureSurfaceTransaction finishTransaction, SurfaceControl overlay) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                    "RecentsController.setFinishTaskTransaction: taskId=%d", taskId);
             mExecutor.execute(() -> {
                 if (mFinishCB == null) return;
                 mPipTransaction = finishTransaction;
@@ -619,6 +677,9 @@
                 Slog.e(TAG, "Duplicate call to finish");
                 return;
             }
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                    "RecentsController.finishInner: toHome=%b userLeaveHint=%b willFinishToHome=%b",
+                    toHome, sendUserLeaveHint, mWillFinishToHome);
             final Transitions.TransitionFinishCallback finishCB = mFinishCB;
             mFinishCB = null;
 
@@ -630,6 +691,7 @@
                 else wct.restoreTransientOrder(mRecentsTask);
             }
             if (!toHome && !mWillFinishToHome && mPausingTasks != null && mState == STATE_NORMAL) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "  returning to app");
                 // The gesture is returning to the pausing-task(s) rather than continuing with
                 // recents, so end the transition by moving the app back to the top (and also
                 // re-showing it's task).
@@ -642,6 +704,7 @@
                     wct.restoreTransientOrder(mRecentsTask);
                 }
             } else if (toHome && mOpeningSeparateHome && mPausingTasks != null) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "  3p launching home");
                 // Special situation where 3p launcher was changed during recents (this happens
                 // during tapltests...). Here we get both "return to home" AND "home opening".
                 // This is basically going home, but we have to restore the recents and home order.
@@ -660,6 +723,7 @@
                     wct.restoreTransientOrder(mRecentsTask);
                 }
             } else {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "  normal finish");
                 // The general case: committing to recents, going home, or switching tasks.
                 for (int i = 0; i < mOpeningTasks.size(); ++i) {
                     t.show(mOpeningTasks.get(i).mTaskSurface);
@@ -716,6 +780,8 @@
          */
         @Override
         public void detachNavigationBarFromApp(boolean moveHomeToTop) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+                    "RecentsController.detachNavigationBarFromApp");
             mExecutor.execute(() -> {
                 if (mTransition == null) return;
                 try {
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 bdb7d44..08b0bf7 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
@@ -429,6 +429,7 @@
                         && (change.getFlags() & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) == 0) {
                     t.setAlpha(leash, 0.f);
                 }
+                finishT.show(leash);
             } else if (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK) {
                 finishT.hide(leash);
             }
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 c416ad0..45024f3 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
@@ -223,15 +223,6 @@
                     portraitPosTop,
                     scenario.endRotation
                 )
-                .then()
-                .isInvisible(component)
-                .then()
-                .splitAppLayerBoundsSnapToDivider(
-                    component,
-                    landscapePosLeft,
-                    portraitPosTop,
-                    scenario.endRotation
-                )
         } else {
             splitAppLayerBoundsSnapToDivider(
                     component,
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
index 62936e0..625987a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
@@ -293,7 +293,7 @@
             wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace
                 ?: error("Display not found")
         val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS)
-        dividerBar.drag(Point(displayBounds.width * 1 / 3, displayBounds.height * 2 / 3), 2000)
+        dividerBar.drag(Point(displayBounds.width * 1 / 3, displayBounds.height * 2 / 3), 200)
 
         wmHelper
             .StateSyncBuilder()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index d95c7a4..3d8bd38 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -135,12 +135,15 @@
         mShellExecutor.flushAll();
     }
 
-    private void createNavigationInfo(int backType, boolean enableAnimation) {
+    private void createNavigationInfo(int backType,
+            boolean enableAnimation,
+            boolean isAnimationCallback) {
         BackNavigationInfo.Builder builder = new BackNavigationInfo.Builder()
                 .setType(backType)
                 .setOnBackNavigationDone(new RemoteCallback((bundle) -> {}))
                 .setOnBackInvokedCallback(mAppCallback)
-                .setPrepareRemoteAnimation(enableAnimation);
+                .setPrepareRemoteAnimation(enableAnimation)
+                .setAnimationCallback(isAnimationCallback);
 
         createNavigationInfo(builder);
     }
@@ -218,7 +221,9 @@
     @Test
     public void backToHome_dispatchesEvents() throws RemoteException {
         registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
-        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME, true);
+        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME,
+                /* enableAnimation = */ true,
+                /* isAnimationCallback = */ false);
 
         doMotionEvent(MotionEvent.ACTION_DOWN, 0);
 
@@ -240,6 +245,32 @@
     }
 
     @Test
+    public void backToHomeWithAnimationCallback_dispatchesEvents() throws RemoteException {
+        registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
+        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME,
+                /* enableAnimation = */ true,
+                /* isAnimationCallback = */ true);
+
+        doMotionEvent(MotionEvent.ACTION_DOWN, 0);
+
+        // Check that back start and progress is dispatched when first move.
+        doMotionEvent(MotionEvent.ACTION_MOVE, 100, 3000);
+
+        simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME);
+
+        verify(mAnimatorCallback).onBackStarted(any(BackMotionEvent.class));
+        verify(mBackAnimationRunner).onAnimationStart(anyInt(), any(), any(), any(), any());
+        ArgumentCaptor<BackMotionEvent> backEventCaptor =
+                ArgumentCaptor.forClass(BackMotionEvent.class);
+        verify(mAnimatorCallback, atLeastOnce()).onBackProgressed(backEventCaptor.capture());
+
+        // Check that back invocation is dispatched.
+        mController.setTriggerBack(true);   // Fake trigger back
+        doMotionEvent(MotionEvent.ACTION_UP, 0);
+        verify(mAnimatorCallback).onBackInvoked();
+    }
+
+    @Test
     public void animationDisabledFromSettings() throws RemoteException {
         // Toggle the setting off
         Settings.Global.putString(mContentResolver, Settings.Global.ENABLE_BACK_ANIMATION, "0");
@@ -254,7 +285,9 @@
         ArgumentCaptor<BackMotionEvent> backEventCaptor =
                 ArgumentCaptor.forClass(BackMotionEvent.class);
 
-        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME, false);
+        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME,
+                /* enableAnimation = */ false,
+                /* isAnimationCallback = */ false);
 
         triggerBackGesture();
         releaseBackGesture();
@@ -271,7 +304,9 @@
     @Test
     public void ignoresGesture_transitionInProgress() throws RemoteException {
         registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
-        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME, true);
+        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME,
+                /* enableAnimation = */ true,
+                /* isAnimationCallback = */ false);
 
         triggerBackGesture();
         simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME);
@@ -309,7 +344,9 @@
     @Test
     public void acceptsGesture_transitionTimeout() throws RemoteException {
         registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
-        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME, true);
+        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME,
+                /* enableAnimation = */ true,
+                /* isAnimationCallback = */ false);
 
         // In case it is still running in animation.
         doNothing().when(mAnimatorCallback).onBackInvoked();
@@ -334,7 +371,9 @@
     public void cancelBackInvokeWhenLostFocus() throws RemoteException {
         registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
 
-        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME, true);
+        createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME,
+                /* enableAnimation = */ true,
+                /* isAnimationCallback = */ false);
 
         doMotionEvent(MotionEvent.ACTION_DOWN, 0);
         // Check that back start and progress is dispatched when first move.
@@ -454,7 +493,9 @@
 
         mController.registerAnimation(type, animationRunner);
 
-        createNavigationInfo(type, true);
+        createNavigationInfo(type,
+                /* enableAnimation = */ true,
+                /* isAnimationCallback = */ false);
 
         doMotionEvent(MotionEvent.ACTION_DOWN, 0);
 
@@ -473,11 +514,15 @@
     }
 
     private void doMotionEvent(int actionDown, int coordinate) {
+        doMotionEvent(actionDown, coordinate, 0);
+    }
+
+    private void doMotionEvent(int actionDown, int coordinate, float velocity) {
         mController.onMotionEvent(
                 /* touchX */ coordinate,
                 /* touchY */ coordinate,
-                /* velocityX = */ 0,
-                /* velocityY = */ 0,
+                /* velocityX = */ velocity,
+                /* velocityY = */ velocity,
                 /* keyAction */ actionDown,
                 /* swipeEdge */ BackEvent.EDGE_LEFT);
     }
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index 5f5e214..094a33f 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -25,6 +25,8 @@
 import android.media.AudioSystem;
 import android.os.Build;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
@@ -252,10 +254,10 @@
         if (o == null || getClass() != o.getClass()) return false;
 
         final AudioMix that = (AudioMix) o;
-        return (mRouteFlags == that.mRouteFlags)
-                && (mMixType == that.mMixType)
-                && Objects.equals(mRule, that.mRule)
-                && Objects.equals(mFormat, that.mFormat);
+        return Objects.equals(this.mRouteFlags, that.mRouteFlags)
+            && Objects.equals(this.mRule, that.mRule)
+            && Objects.equals(this.mMixType, that.mMixType)
+            && Objects.equals(this.mFormat, that.mFormat);
     }
 
     /** @hide */
@@ -340,7 +342,8 @@
          * @param address
          * @return the same Builder instance.
          */
-        Builder setDevice(int deviceType, String address) {
+        @VisibleForTesting
+        public Builder setDevice(int deviceType, String address) {
             mDeviceSystemType = deviceType;
             mDeviceAddress = address;
             return this;
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
index 556a05c..d2fd780 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/PermissionListAdapter.java
@@ -121,16 +121,15 @@
         if (viewHolder.mExpandButton.getTag() == null) {
             viewHolder.mExpandButton.setTag(R.drawable.btn_expand_more);
         }
-        // Add expand buttons if the permissions are more than PERMISSION_SIZE in this list.
+        // Add expand buttons if the permissions are more than PERMISSION_SIZE in this list also
+        // make the summary invisible by default.
         if (mPermissions.size() > PERMISSION_SIZE) {
+
+            viewHolder.mPermissionSummary.setVisibility(View.GONE);
+
             view.setOnClickListener(v -> {
                 if ((Integer) viewHolder.mExpandButton.getTag() == R.drawable.btn_expand_more) {
                     viewHolder.mExpandButton.setImageResource(R.drawable.btn_expand_less);
-
-                    if (viewHolder.mSummary != null) {
-                        viewHolder.mPermissionSummary.setText(viewHolder.mSummary);
-                    }
-
                     viewHolder.mPermissionSummary.setVisibility(View.VISIBLE);
                     viewHolder.mExpandButton.setTag(R.drawable.btn_expand_less);
                 } else {
@@ -139,6 +138,11 @@
                     viewHolder.mExpandButton.setTag(R.drawable.btn_expand_more);
                 }
             });
+        } else {
+            // Remove expand buttons if the permissions are less than PERMISSION_SIZE in this list
+            // also show the summary by default.
+            viewHolder.mPermissionSummary.setVisibility(View.VISIBLE);
+            viewHolder.mExpandButton.setVisibility(View.GONE);
         }
 
         return viewHolder;
@@ -150,15 +154,8 @@
         final Spanned title = getHtmlFromResources(mContext, sTitleMap.get(type));
         final Spanned summary = getHtmlFromResources(mContext, sSummaryMap.get(type));
 
-        holder.mSummary = summary;
+        holder.mPermissionSummary.setText(summary);
         holder.mPermissionName.setText(title);
-
-        if (mPermissions.size() <= PERMISSION_SIZE) {
-            holder.mPermissionSummary.setText(summary);
-            holder.mExpandButton.setVisibility(View.GONE);
-        } else {
-            holder.mPermissionSummary.setVisibility(View.GONE);
-        }
     }
 
     @Override
@@ -181,7 +178,6 @@
         private final TextView mPermissionSummary;
         private final ImageView mPermissionIcon;
         private final ImageButton mExpandButton;
-        private Spanned mSummary = null;
         ViewHolder(View itemView) {
             super(itemView);
             mPermissionName = itemView.findViewById(R.id.permission_name);
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
index 4d2bb4c..8b74d76 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -18,6 +18,7 @@
 
 import android.app.Activity
 import android.os.IBinder
+import android.text.TextUtils
 import android.util.Log
 import androidx.activity.compose.ManagedActivityResultLauncher
 import androidx.activity.result.ActivityResult
@@ -67,9 +68,9 @@
 
     var uiMetrics: UIMetrics = UIMetrics()
 
-    init{
+    init {
         uiMetrics.logNormal(LifecycleEvent.CREDMAN_ACTIVITY_INIT,
-                credManRepo.requestInfo?.appPackageName)
+            credManRepo.requestInfo?.appPackageName)
     }
 
     /**************************************************************************/
@@ -100,7 +101,7 @@
         if (this.credManRepo.requestInfo?.token != credManRepo.requestInfo?.token) {
             this.uiMetrics.resetInstanceId()
             this.uiMetrics.logNormal(LifecycleEvent.CREDMAN_ACTIVITY_NEW_REQUEST,
-                    credManRepo.requestInfo?.appPackageName)
+                credManRepo.requestInfo?.appPackageName)
         }
     }
 
@@ -174,7 +175,7 @@
     private fun onInternalError() {
         Log.w(Constants.LOG_TAG, "UI closed due to illegal internal state")
         this.uiMetrics.logNormal(LifecycleEvent.CREDMAN_ACTIVITY_INTERNAL_ERROR,
-                credManRepo.requestInfo?.appPackageName)
+            credManRepo.requestInfo?.appPackageName)
         credManRepo.onParsingFailureCancel()
         uiState = uiState.copy(dialogState = DialogState.COMPLETE)
     }
@@ -314,10 +315,11 @@
         uiState = uiState.copy(
             createCredentialUiState = uiState.createCredentialUiState?.copy(
                 currentScreenState =
-                if (activeEntry.activeProvider.id ==
-                    userConfigRepo.getDefaultProviderId())
+                if (activeEntry.activeProvider.id == userConfigRepo.getDefaultProviderId() ||
+                    !TextUtils.isEmpty(uiState.createCredentialUiState?.requestDisplayInfo
+                        ?.appPreferredDefaultProviderId))
                     CreateScreenState.CREATION_OPTION_SELECTION
-                else CreateScreenState.MORE_OPTIONS_ROW_INTRO,
+                else CreateScreenState.DEFAULT_PROVIDER_CONFIRMATION,
                 activeEntry = activeEntry
             )
         )
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index 96010cc..9d871ed 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -139,12 +139,12 @@
                                 onRemoteEntrySelected = viewModel::createFlowOnEntrySelected,
                                 onLog = { viewModel.logUiEvent(it) },
                         )
-                        CreateScreenState.MORE_OPTIONS_ROW_INTRO -> {
+                        CreateScreenState.DEFAULT_PROVIDER_CONFIRMATION -> {
                             if (createCredentialUiState.activeEntry == null) {
                                 viewModel.onIllegalUiState("Expect active entry to be non-null" +
                                         " upon default provider dialog.")
                             } else {
-                                MoreOptionsRowIntroCard(
+                                DefaultProviderConfirmationCard(
                                         selectedEntry = createCredentialUiState.activeEntry,
                                         onIllegalScreenState = viewModel::onIllegalUiState,
                                         onChangeDefaultSelected =
@@ -420,7 +420,7 @@
 }
 
 @Composable
-fun MoreOptionsRowIntroCard(
+fun DefaultProviderConfirmationCard(
         selectedEntry: ActiveEntry,
         onIllegalScreenState: (String) -> Unit,
         onChangeDefaultSelected: () -> Unit,
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
index 12bb629..225dbf2 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
@@ -126,6 +126,6 @@
   PROVIDER_SELECTION,
   CREATION_OPTION_SELECTION,
   MORE_OPTIONS_SELECTION,
-  MORE_OPTIONS_ROW_INTRO,
+  DEFAULT_PROVIDER_CONFIRMATION,
   EXTERNAL_ONLY_SELECTION,
 }
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
index 96ea5b4..27aade5 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
@@ -19,6 +19,7 @@
 import android.Manifest;
 import android.accessibilityservice.AccessibilityButtonController;
 import android.accessibilityservice.AccessibilityService;
+import android.app.KeyguardManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -82,6 +83,9 @@
 
     // TODO(b/136716947): Support multi-display once a11y framework side is ready.
     private DisplayManager mDisplayManager;
+
+    private KeyguardManager mKeyguardManager;
+
     private final DisplayManager.DisplayListener mDisplayListener =
             new DisplayManager.DisplayListener() {
         int mRotation;
@@ -114,7 +118,7 @@
     private final BroadcastReceiver mToggleMenuReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            mA11yMenuLayout.toggleVisibility();
+            toggleVisibility();
         }
     };
 
@@ -159,10 +163,7 @@
                      */
                     @Override
                     public void onClicked(AccessibilityButtonController controller) {
-                        if (SystemClock.uptimeMillis() - mLastTimeTouchedOutside
-                                > BUTTON_CLICK_TIMEOUT) {
-                            mA11yMenuLayout.toggleVisibility();
-                        }
+                        toggleVisibility();
                     }
 
                     /**
@@ -209,6 +210,7 @@
         mDisplayManager = getSystemService(DisplayManager.class);
         mDisplayManager.registerDisplayListener(mDisplayListener, null);
         mAudioManager = getSystemService(AudioManager.class);
+        mKeyguardManager = getSystemService(KeyguardManager.class);
 
         sInitialized = true;
     }
@@ -379,4 +381,12 @@
         }
         return false;
     }
+
+    private void toggleVisibility() {
+        boolean locked = mKeyguardManager != null && mKeyguardManager.isKeyguardLocked();
+        if (!locked && SystemClock.uptimeMillis() - mLastTimeTouchedOutside
+                        > BUTTON_CLICK_TIMEOUT) {
+            mA11yMenuLayout.toggleVisibility();
+        }
+    }
 }
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
index 7277392..9d1af0e 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
@@ -33,6 +33,7 @@
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.Instrumentation;
+import android.app.KeyguardManager;
 import android.app.UiAutomation;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -44,6 +45,7 @@
 import android.os.PowerManager;
 import android.provider.Settings;
 import android.util.Log;
+import android.view.Display;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 
@@ -69,15 +71,19 @@
     private static final int CLICK_ID = AccessibilityNodeInfo.ACTION_CLICK;
 
     private static final int TIMEOUT_SERVICE_STATUS_CHANGE_S = 5;
-    private static final int TIMEOUT_UI_CHANGE_S = 10;
+    private static final int TIMEOUT_UI_CHANGE_S = 5;
     private static final int NO_GLOBAL_ACTION = -1;
     private static final String INPUT_KEYEVENT_KEYCODE_BACK = "input keyevent KEYCODE_BACK";
+    private static final String TEST_PIN = "1234";
 
     private static Instrumentation sInstrumentation;
     private static UiAutomation sUiAutomation;
     private static AtomicInteger sLastGlobalAction;
 
     private static AccessibilityManager sAccessibilityManager;
+    private static PowerManager sPowerManager;
+    private static KeyguardManager sKeyguardManager;
+    private static DisplayManager sDisplayManager;
 
     @BeforeClass
     public static void classSetup() throws Throwable {
@@ -85,8 +91,14 @@
         sInstrumentation = InstrumentationRegistry.getInstrumentation();
         sUiAutomation = sInstrumentation.getUiAutomation(
                 UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
+        sUiAutomation.adoptShellPermissionIdentity(
+                UiAutomation.ALL_PERMISSIONS.toArray(new String[0]));
+
         final Context context = sInstrumentation.getTargetContext();
         sAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+        sPowerManager = context.getSystemService(PowerManager.class);
+        sKeyguardManager = context.getSystemService(KeyguardManager.class);
+        sDisplayManager = context.getSystemService(DisplayManager.class);
 
         // Disable all a11yServices if any are active.
         if (!sAccessibilityManager.getEnabledAccessibilityServiceList(
@@ -123,12 +135,16 @@
 
     @AfterClass
     public static void classTeardown() throws Throwable {
+        clearPin();
         Settings.Secure.putString(sInstrumentation.getTargetContext().getContentResolver(),
                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
     }
 
     @Before
     public void setup() throws Throwable {
+        clearPin();
+        wakeUpScreen();
+        sUiAutomation.executeShellCommand("input keyevent KEYCODE_MENU");
         openMenu();
     }
 
@@ -138,11 +154,43 @@
         sLastGlobalAction.set(NO_GLOBAL_ACTION);
     }
 
+    private static void clearPin() throws Throwable {
+        sUiAutomation.executeShellCommand("locksettings clear --old " + TEST_PIN);
+        TestUtils.waitUntil("Device did not register as unlocked & insecure.",
+                TIMEOUT_SERVICE_STATUS_CHANGE_S,
+                () -> !sKeyguardManager.isDeviceSecure());
+    }
+
+    private static void setPin() throws Throwable {
+        sUiAutomation.executeShellCommand("locksettings set-pin " + TEST_PIN);
+        TestUtils.waitUntil("Device did not recognize as locked & secure.",
+                TIMEOUT_SERVICE_STATUS_CHANGE_S,
+                () -> sKeyguardManager.isDeviceSecure());
+    }
+
     private static boolean isMenuVisible() {
         AccessibilityNodeInfo root = sUiAutomation.getRootInActiveWindow();
         return root != null && root.getPackageName().toString().equals(PACKAGE_NAME);
     }
 
+    private static void wakeUpScreen() throws Throwable {
+        sUiAutomation.executeShellCommand("input keyevent KEYCODE_WAKEUP");
+        TestUtils.waitUntil("Screen did not wake up.",
+                TIMEOUT_UI_CHANGE_S,
+                () -> sPowerManager.isInteractive());
+    }
+
+    private static void closeScreen() throws Throwable {
+        Display display = sDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
+        setPin();
+        sUiAutomation.performGlobalAction(GLOBAL_ACTION_LOCK_SCREEN);
+        TestUtils.waitUntil("Screen did not close.",
+                TIMEOUT_UI_CHANGE_S,
+                () -> !sPowerManager.isInteractive()
+                        && display.getState() == Display.STATE_OFF
+        );
+    }
+
     private static void openMenu() throws Throwable {
         Intent intent = new Intent(PACKAGE_NAME + INTENT_TOGGLE_MENU);
         sInstrumentation.getContext().sendBroadcast(intent);
@@ -381,23 +429,24 @@
 
     @Test
     public void testOnScreenLock_closesMenu() throws Throwable {
-        openMenu();
-        Context context = sInstrumentation.getTargetContext();
-        PowerManager powerManager = context.getSystemService(PowerManager.class);
-
-        assertThat(powerManager).isNotNull();
-        assertThat(powerManager.isInteractive()).isTrue();
-
-        sUiAutomation.performGlobalAction(GLOBAL_ACTION_LOCK_SCREEN);
-        TestUtils.waitUntil("Screen did not become locked",
-                TIMEOUT_UI_CHANGE_S,
-                () -> !powerManager.isInteractive());
-
-        sUiAutomation.executeShellCommand("input keyevent KEYCODE_WAKEUP");
-        TestUtils.waitUntil("Screen did not wake up",
-                TIMEOUT_UI_CHANGE_S,
-                () -> powerManager.isInteractive());
+        closeScreen();
+        wakeUpScreen();
 
         assertThat(isMenuVisible()).isFalse();
     }
+
+    @Test
+    public void testOnScreenLock_cannotOpenMenu() throws Throwable {
+        closeScreen();
+        wakeUpScreen();
+
+        boolean timedOut = false;
+        try {
+            openMenu();
+        } catch (AssertionError e) {
+            // Expected
+            timedOut = true;
+        }
+        assertThat(timedOut).isTrue();
+    }
 }
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
index 204bac8..450c616 100644
--- a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
@@ -316,9 +316,9 @@
     ),
     CLOCK_VIBRANT(
         CoreSpec(
-            a1 = TonalSpec(HueSource(), ChromaBound(ChromaSource(), 30.0, Chroma.MAX_VALUE)),
-            a2 = TonalSpec(HueAdd(20.0), ChromaBound(ChromaSource(), 30.0, Chroma.MAX_VALUE)),
-            a3 = TonalSpec(HueAdd(60.0), ChromaBound(ChromaSource(), 30.0, Chroma.MAX_VALUE)),
+            a1 = TonalSpec(HueSource(), ChromaBound(ChromaSource(), 70.0, Chroma.MAX_VALUE)),
+            a2 = TonalSpec(HueAdd(20.0), ChromaBound(ChromaSource(), 70.0, Chroma.MAX_VALUE)),
+            a3 = TonalSpec(HueAdd(60.0), ChromaBound(ChromaSource(), 70.0, Chroma.MAX_VALUE)),
 
             // Not Used
             n1 = TonalSpec(HueSource(), ChromaConstant(0.0)),
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
index 5b0e290..461d390 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
@@ -41,10 +41,10 @@
     var listeningForFaceAssistant: Boolean = false,
     var occludingAppRequestingFaceAuth: Boolean = false,
     var postureAllowsListening: Boolean = false,
-    var primaryUser: Boolean = false,
     var secureCameraLaunched: Boolean = false,
     var supportsDetect: Boolean = false,
     var switchingUser: Boolean = false,
+    var systemUser: Boolean = false,
     var udfpsFingerDown: Boolean = false,
     var userNotTrustedOrDetectionIsNeeded: Boolean = false,
 ) : KeyguardListenModel() {
@@ -69,11 +69,11 @@
             keyguardGoingAway.toString(),
             listeningForFaceAssistant.toString(),
             occludingAppRequestingFaceAuth.toString(),
-            primaryUser.toString(),
             postureAllowsListening.toString(),
             secureCameraLaunched.toString(),
             supportsDetect.toString(),
             switchingUser.toString(),
+            systemUser.toString(),
             alternateBouncerShowing.toString(),
             udfpsFingerDown.toString(),
             userNotTrustedOrDetectionIsNeeded.toString(),
@@ -109,12 +109,11 @@
                 keyguardGoingAway = model.keyguardGoingAway
                 listeningForFaceAssistant = model.listeningForFaceAssistant
                 occludingAppRequestingFaceAuth = model.occludingAppRequestingFaceAuth
-                primaryUser = model.primaryUser
                 postureAllowsListening = model.postureAllowsListening
                 secureCameraLaunched = model.secureCameraLaunched
                 supportsDetect = model.supportsDetect
                 switchingUser = model.switchingUser
-                switchingUser = model.switchingUser
+                systemUser = model.systemUser
                 udfpsFingerDown = model.udfpsFingerDown
                 userNotTrustedOrDetectionIsNeeded = model.userNotTrustedOrDetectionIsNeeded
             }
@@ -153,11 +152,11 @@
                 "keyguardGoingAway",
                 "listeningForFaceAssistant",
                 "occludingAppRequestingFaceAuth",
-                "primaryUser",
                 "postureAllowsListening",
                 "secureCameraLaunched",
                 "supportsDetect",
                 "switchingUser",
+                "systemUser",
                 "udfpsBouncerShowing",
                 "udfpsFingerDown",
                 "userNotTrustedOrDetectionIsNeeded",
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
index b8c0ccb..f2685c5 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
@@ -41,11 +41,11 @@
     var keyguardIsVisible: Boolean = false,
     var keyguardOccluded: Boolean = false,
     var occludingAppRequestingFp: Boolean = false,
-    var primaryUser: Boolean = false,
     var shouldListenSfpsState: Boolean = false,
     var shouldListenForFingerprintAssistant: Boolean = false,
     var strongerAuthRequired: Boolean = false,
     var switchingUser: Boolean = false,
+    var systemUser: Boolean = false,
     var udfps: Boolean = false,
     var userDoesNotHaveTrust: Boolean = false,
 ) : KeyguardListenModel() {
@@ -72,11 +72,11 @@
             keyguardIsVisible.toString(),
             keyguardOccluded.toString(),
             occludingAppRequestingFp.toString(),
-            primaryUser.toString(),
             shouldListenSfpsState.toString(),
             shouldListenForFingerprintAssistant.toString(),
             strongerAuthRequired.toString(),
             switchingUser.toString(),
+            systemUser.toString(),
             udfps.toString(),
             userDoesNotHaveTrust.toString(),
         )
@@ -112,11 +112,11 @@
                 keyguardIsVisible = model.keyguardIsVisible
                 keyguardOccluded = model.keyguardOccluded
                 occludingAppRequestingFp = model.occludingAppRequestingFp
-                primaryUser = model.primaryUser
                 shouldListenSfpsState = model.shouldListenSfpsState
                 shouldListenForFingerprintAssistant = model.shouldListenForFingerprintAssistant
                 strongerAuthRequired = model.strongerAuthRequired
                 switchingUser = model.switchingUser
+                systemUser = model.systemUser
                 udfps = model.udfps
                 userDoesNotHaveTrust = model.userDoesNotHaveTrust
             }
@@ -158,11 +158,11 @@
                 "keyguardIsVisible",
                 "keyguardOccluded",
                 "occludingAppRequestingFp",
-                "primaryUser",
                 "shouldListenSidFingerprintState",
                 "shouldListenForFingerprintAssistant",
                 "strongAuthRequired",
                 "switchingUser",
+                "systemUser",
                 "underDisplayFingerprint",
                 "userDoesNotHaveTrust",
             )
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 76e051e..693268d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -178,6 +178,7 @@
 
         @Override
         public void onUserInput() {
+            mKeyguardFaceAuthInteractor.onPrimaryBouncerUserInput();
             mUpdateMonitor.cancelFaceAuth();
         }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index ea04376..10c08bc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -297,7 +297,7 @@
     private final Context mContext;
     private final UserTracker mUserTracker;
     private final KeyguardUpdateMonitorLogger mLogger;
-    private final boolean mIsPrimaryUser;
+    private final boolean mIsSystemUser;
     private final AuthController mAuthController;
     private final UiEventLogger mUiEventLogger;
     private final Set<Integer> mFaceAcquiredInfoIgnoreList;
@@ -2522,7 +2522,7 @@
         updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_ON_KEYGUARD_INIT);
 
         TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
-        mIsPrimaryUser = mUserManager.isPrimaryUser();
+        mIsSystemUser = mUserManager.isSystemUser();
         int user = mUserTracker.getUserId();
         mUserIsUnlocked.put(user, mUserManager.isUserUnlocked(user));
         mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
@@ -2968,7 +2968,7 @@
                         || (mKeyguardOccluded && userDoesNotHaveTrust && mKeyguardShowing
                             && (mOccludingAppRequestingFp || isUdfps || mAlternateBouncerShowing));
 
-        // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
+        // Only listen if this KeyguardUpdateMonitor belongs to the system user. There is an
         // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
         final boolean biometricEnabledForUser = mBiometricEnabledForUser.get(user);
         final boolean userCanSkipBouncer = getUserCanSkipBouncer(user);
@@ -2977,7 +2977,7 @@
                 !mSwitchingUser
                         && !fingerprintDisabledForUser
                         && (!mKeyguardGoingAway || !mDeviceInteractive)
-                        && mIsPrimaryUser
+                        && mIsSystemUser
                         && biometricEnabledForUser
                         && !isUserInLockdown(user);
         final boolean strongerAuthRequired = !isUnlockingWithFingerprintAllowed();
@@ -3021,11 +3021,11 @@
                     isKeyguardVisible(),
                     mKeyguardOccluded,
                     mOccludingAppRequestingFp,
-                    mIsPrimaryUser,
                     shouldListenSideFpsState,
                     shouldListenForFingerprintAssistant,
                     strongerAuthRequired,
                     mSwitchingUser,
+                    mIsSystemUser,
                     isUdfps,
                     userDoesNotHaveTrust));
 
@@ -3070,7 +3070,7 @@
         final boolean shouldListenForFaceAssistant = shouldListenForFaceAssistant();
         final boolean isUdfpsFingerDown = mAuthController.isUdfpsFingerDown();
         final boolean isPostureAllowedForFaceAuth = doesPostureAllowFaceAuth(mPostureState);
-        // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
+        // Only listen if this KeyguardUpdateMonitor belongs to the system user. There is an
         // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
         final boolean shouldListen =
                 (mPrimaryBouncerFullyShown
@@ -3082,7 +3082,7 @@
                         || mAlternateBouncerShowing)
                 && !mSwitchingUser && !faceDisabledForUser && userNotTrustedOrDetectionIsNeeded
                 && !mKeyguardGoingAway && biometricEnabledForUser
-                && faceAuthAllowedOrDetectionIsNeeded && mIsPrimaryUser
+                && faceAuthAllowedOrDetectionIsNeeded && mIsSystemUser
                 && (!mSecureCameraLaunched || mAlternateBouncerShowing)
                 && faceAndFpNotAuthenticated
                 && !mGoingToSleep
@@ -3108,10 +3108,10 @@
                     shouldListenForFaceAssistant,
                     mOccludingAppRequestingFace,
                     isPostureAllowedForFaceAuth,
-                    mIsPrimaryUser,
                     mSecureCameraLaunched,
                     supportsDetect,
                     mSwitchingUser,
+                    mIsSystemUser,
                     isUdfpsFingerDown,
                     userNotTrustedOrDetectionIsNeeded));
 
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 29c63bb..41d6ec8 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -577,16 +577,6 @@
     // TODO(b/254512507): Tracking Bug
     val CHOOSER_UNBUNDLED = releasedFlag(1500, "chooser_unbundled")
 
-    // TODO(b/266982749) Tracking Bug
-    val SHARESHEET_RESELECTION_ACTION = releasedFlag(1502, "sharesheet_reselection_action")
-
-    // TODO(b/266983474) Tracking Bug
-    val SHARESHEET_IMAGE_AND_TEXT_PREVIEW = releasedFlag(1503, "sharesheet_image_text_preview")
-
-    // TODO(b/267355521) Tracking Bug
-    val SHARESHEET_SCROLLABLE_IMAGE_PREVIEW =
-        releasedFlag(1504, "sharesheet_scrollable_image_preview")
-
     // 1700 - clipboard
     @JvmField val CLIPBOARD_REMOTE_BEHAVIOR = releasedFlag(1701, "clipboard_remote_behavior")
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index e0af5ce..7a2013e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1957,11 +1957,12 @@
         if (mShowing && mKeyguardStateController.isShowing()) {
             if (mPM.isInteractive() && !mHiding) {
                 // It's already showing, and we're not trying to show it while the screen is off.
-                // We can simply reset all of the views.
+                // We can simply reset all of the views, but don't hide the bouncer in case the user
+                // is currently interacting with it.
                 if (DEBUG) Log.d(TAG, "doKeyguard: not showing (instead, resetting) because it is "
                         + "already showing, we're interactive, and we were not previously hiding. "
                         + "It should be safe to short-circuit here.");
-                resetStateLocked();
+                resetStateLocked(/* hideBouncer= */ false);
                 return;
             } else {
                 // We are trying to show the keyguard while the screen is off or while we were in
@@ -2035,8 +2036,12 @@
      * @see #handleReset
      */
     private void resetStateLocked() {
+        resetStateLocked(/* hideBouncer= */ true);
+    }
+
+    private void resetStateLocked(boolean hideBouncer) {
         if (DEBUG) Log.e(TAG, "resetStateLocked");
-        Message msg = mHandler.obtainMessage(RESET);
+        Message msg = mHandler.obtainMessage(RESET, hideBouncer ? 1 : 0, 0);
         mHandler.sendMessage(msg);
     }
 
@@ -2226,7 +2231,7 @@
                     handleHide();
                     break;
                 case RESET:
-                    handleReset();
+                    handleReset(msg.arg1 != 0);
                     break;
                 case VERIFY_UNLOCK:
                     Trace.beginSection("KeyguardViewMediator#handleMessage VERIFY_UNLOCK");
@@ -3008,10 +3013,10 @@
      * Handle message sent by {@link #resetStateLocked}
      * @see #RESET
      */
-    private void handleReset() {
+    private void handleReset(boolean hideBouncer) {
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleReset");
-            mKeyguardViewControllerLazy.get().reset(true /* hideBouncerWhenShowing */);
+            mKeyguardViewControllerLazy.get().reset(hideBouncer);
         }
 
         scheduleNonStrongBiometricIdleTimeout();
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
index 05ab01b..5f2178df 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -225,10 +225,17 @@
     }
 
     private fun observeFaceAuthResettingConditions() {
-        // Clear auth status when keyguard is going away or when the user is switching.
-        merge(keyguardRepository.isKeyguardGoingAway, userRepository.userSwitchingInProgress)
-            .onEach { goingAwayOrUserSwitchingInProgress ->
-                if (goingAwayOrUserSwitchingInProgress) {
+        // Clear auth status when keyguard is going away or when the user is switching or device
+        // starts going to sleep.
+        merge(
+                keyguardRepository.wakefulness.map {
+                    WakefulnessModel.isSleepingOrStartingToSleep(it)
+                },
+                keyguardRepository.isKeyguardGoingAway,
+                userRepository.userSwitchingInProgress
+            )
+            .onEach { anyOfThemIsTrue ->
+                if (anyOfThemIsTrue) {
                     _isAuthenticated.value = false
                     retryCount = 0
                     halErrorRetryJob?.cancel()
@@ -248,8 +255,8 @@
                     "nonStrongBiometricIsNotAllowed",
                     faceDetectLog
                 ),
-                // We don't want to run face detect if it's not possible to authenticate with FP
-                // from the bouncer. UDFPS is the only fp sensor type that won't support this.
+                // We don't want to run face detect if fingerprint can be used to unlock the device
+                // but it's not possible to authenticate with FP from the bouncer (UDFPS)
                 logAndObserve(
                     and(isUdfps(), deviceEntryFingerprintAuthRepository.isRunning).isFalse(),
                     "udfpsAuthIsNotPossibleAnymore",
@@ -306,7 +313,7 @@
                 logAndObserve(
                     combine(
                         keyguardInteractor.isSecureCameraActive,
-                        alternateBouncerInteractor.isVisible,
+                        alternateBouncerInteractor.isVisible
                     ) { a, b ->
                         !a || b
                     },
@@ -334,12 +341,12 @@
                 logAndObserve(isLockedOut.isFalse(), "isNotInLockOutState", faceAuthLog),
                 logAndObserve(
                     deviceEntryFingerprintAuthRepository.isLockedOut.isFalse(),
-                    "fpLockedOut",
+                    "fpIsNotLockedOut",
                     faceAuthLog
                 ),
                 logAndObserve(
                     trustRepository.isCurrentUserTrusted.isFalse(),
-                    "currentUserTrusted",
+                    "currentUserIsNotTrusted",
                     faceAuthLog
                 ),
                 logAndObserve(
@@ -347,11 +354,6 @@
                     "nonStrongBiometricIsAllowed",
                     faceAuthLog
                 ),
-                logAndObserve(
-                    userRepository.selectedUserInfo.map { it.isPrimary },
-                    "userIsPrimaryUser",
-                    faceAuthLog
-                ),
             )
             .reduce(::and)
             .distinctUntilChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt
index 06ae11fe8..74ef7a5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt
@@ -59,6 +59,7 @@
     fun onQsExpansionStared()
     fun onNotificationPanelClicked()
     fun onSwipeUpOnBouncer()
+    fun onPrimaryBouncerUserInput()
 }
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt
index cad40aa..5005b6c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt
@@ -59,4 +59,5 @@
     override fun onNotificationPanelClicked() {}
 
     override fun onSwipeUpOnBouncer() {}
+    override fun onPrimaryBouncerUserInput() {}
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
index 20ebb71..6b515da 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
@@ -151,6 +151,10 @@
         return featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)
     }
 
+    override fun onPrimaryBouncerUserInput() {
+        repository.cancel()
+    }
+
     /** Provide the status of face authentication */
     override val authenticationStatus = repository.authenticationStatus
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
index 5770f3e..ddce516 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
@@ -47,6 +47,7 @@
             duration = TO_LOCKSCREEN_DURATION,
             onStep = { value -> -translatePx + value * translatePx },
             interpolator = EMPHASIZED_DECELERATE,
+            onCancel = { 0f },
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 7edb378..077ee02 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -136,6 +136,14 @@
         return factory.create("NotifRemoteInputLog", 50 /* maxSize */, false /* systrace */);
     }
 
+    /** Provides a logging buffer for all logs related to unseen notifications. */
+    @Provides
+    @SysUISingleton
+    @UnseenNotificationLog
+    public static LogBuffer provideUnseenNotificationLogBuffer(LogBufferFactory factory) {
+        return factory.create("UnseenNotifLog", 20 /* maxSize */, false /* systrace */);
+    }
+
     /** Provides a logging buffer for all logs related to the data layer of notifications. */
     @Provides
     @SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/UnseenNotificationLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/UnseenNotificationLog.java
new file mode 100644
index 0000000..5c2321b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/UnseenNotificationLog.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.plugins.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/** A {@link LogBuffer} for unseen notification related messages. */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface UnseenNotificationLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 9e204e4..11c8c50 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -2809,6 +2809,7 @@
     @Override
     public void setBouncerShowing(boolean bouncerShowing) {
         mBouncerShowing = bouncerShowing;
+        mNotificationStackScrollLayoutController.updateShowEmptyShadeView();
         updateVisibility();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 1714f48..72ae16e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -71,8 +71,6 @@
 import com.android.systemui.util.Utils;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 
-import dagger.Lazy;
-
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -82,6 +80,8 @@
 import java.util.Optional;
 import java.util.Set;
 
+import dagger.Lazy;
+
 /**
  * Handles tasks and state related to media notifications. For example, there is a 'current' media
  * notification, which this class keeps track of.
@@ -161,49 +161,12 @@
                 Log.v(TAG, "DEBUG_MEDIA: onMetadataChanged: " + metadata);
             }
             mMediaArtworkProcessor.clearCache();
-            mMediaMetadata = cleanMetadata(metadata);
+            mMediaMetadata = metadata;
             dispatchUpdateMediaMetaData(true /* changed */, true /* allowAnimation */);
         }
     };
 
     /**
-     * If this build is not configured for lockscreen artwork, clear artwork references from the
-     * metadata to avoid excess memory usage. Otherwise, return as is.
-     * @param data Original metadata
-     * @return a copy without artwork data, or original
-     */
-    private MediaMetadata cleanMetadata(MediaMetadata data) {
-        if (SHOW_LOCKSCREEN_MEDIA_ARTWORK) {
-            return data;
-        }
-        if (data == null) {
-            return null;
-        }
-        if (DEBUG_MEDIA) {
-            String[] artKeys = new String[] {
-                MediaMetadata.METADATA_KEY_ART,
-                MediaMetadata.METADATA_KEY_ALBUM_ART,
-                MediaMetadata.METADATA_KEY_DISPLAY_ICON,
-                MediaMetadata.METADATA_KEY_ALBUM_ART_URI,
-                MediaMetadata.METADATA_KEY_ART_URI,
-                MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI
-            };
-            Log.v(TAG, "DEBUG_MEDIA: removing artwork from metadata");
-            for (String key: artKeys) {
-                Log.v(TAG, "  " + key + ": " + data.containsKey(key));
-            }
-        }
-        return new MediaMetadata.Builder(data)
-                .putBitmap(MediaMetadata.METADATA_KEY_ART, null)
-                .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, null)
-                .putBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON, null)
-                .putString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, null)
-                .putString(MediaMetadata.METADATA_KEY_ART_URI, null)
-                .putString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, null)
-                .build();
-    }
-
-    /**
      * Injected constructor. See {@link CentralSurfacesModule}.
      */
     public NotificationMediaManager(
@@ -350,7 +313,6 @@
         return mMediaNotificationKey;
     }
 
-    @VisibleForTesting
     public MediaMetadata getMediaMetadata() {
         return mMediaMetadata;
     }
@@ -388,7 +350,7 @@
      * update this manager's internal state.
      * @return whether the current MediaMetadata changed (and needs to be announced to listeners).
      */
-    private boolean findPlayingMediaNotification(
+    boolean findPlayingMediaNotification(
             @NonNull Collection<NotificationEntry> allNotifications) {
         boolean metaDataChanged = false;
         // Promote the media notification with a controller in 'playing' state, if any.
@@ -421,7 +383,7 @@
             clearCurrentMediaNotificationSession();
             mMediaController = controller;
             mMediaController.registerCallback(mMediaListener);
-            mMediaMetadata = cleanMetadata(mMediaController.getMetadata());
+            mMediaMetadata = mMediaController.getMetadata();
             if (DEBUG_MEDIA) {
                 Log.v(TAG, "DEBUG_MEDIA: insert listener, found new controller: "
                         + mMediaController + ", receive metadata: " + mMediaMetadata);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
index 4cbbefe..2fa070c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
@@ -21,8 +21,10 @@
 import android.os.UserHandle
 import android.provider.Settings
 import androidx.annotation.VisibleForTesting
+import com.android.systemui.Dumpable
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -42,8 +44,14 @@
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
 import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.headsUpEvents
+import com.android.systemui.util.asIndenting
+import com.android.systemui.util.indentIfPossible
 import com.android.systemui.util.settings.SecureSettings
 import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
+import java.io.PrintWriter
+import javax.inject.Inject
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -57,13 +65,11 @@
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.transformLatest
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.yield
-import javax.inject.Inject
-import kotlin.time.Duration
-import kotlin.time.Duration.Companion.seconds
 
 /**
  * Filters low priority and privacy-sensitive notifications from the lockscreen, and hides section
@@ -74,17 +80,19 @@
 @Inject
 constructor(
     @Background private val bgDispatcher: CoroutineDispatcher,
+    private val dumpManager: DumpManager,
     private val headsUpManager: HeadsUpManager,
     private val keyguardNotificationVisibilityProvider: KeyguardNotificationVisibilityProvider,
     private val keyguardRepository: KeyguardRepository,
     private val keyguardTransitionRepository: KeyguardTransitionRepository,
+    private val logger: KeyguardCoordinatorLogger,
     private val notifPipelineFlags: NotifPipelineFlags,
     @Application private val scope: CoroutineScope,
     private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
     private val secureSettings: SecureSettings,
     private val seenNotifsProvider: SeenNotificationsProviderImpl,
     private val statusBarStateController: StatusBarStateController,
-) : Coordinator {
+) : Coordinator, Dumpable {
 
     private val unseenNotifications = mutableSetOf<NotificationEntry>()
     private var unseenFilterEnabled = false
@@ -103,6 +111,7 @@
         pipeline.addCollectionListener(collectionListener)
         scope.launch { trackUnseenNotificationsWhileUnlocked() }
         scope.launch { invalidateWhenUnseenSettingChanges() }
+        dumpManager.registerDumpable(this)
     }
 
     private suspend fun trackUnseenNotificationsWhileUnlocked() {
@@ -122,14 +131,16 @@
                         // If the screen is turning off, stop tracking, but if that transition is
                         // cancelled, then start again.
                         emitAll(
-                            keyguardTransitionRepository.transitions
-                                .map { step -> !step.isScreenTurningOff }
+                            keyguardTransitionRepository.transitions.map { step ->
+                                !step.isScreenTurningOff
+                            }
                         )
                     }
                 }
                 // Prevent double emit of `false` caused by transition to AOD, followed by keyguard
                 // showing
                 .distinctUntilChanged()
+                .onEach { trackingUnseen -> logger.logTrackingUnseen(trackingUnseen) }
 
         // Use collectLatest so that trackUnseenNotifications() is cancelled when the keyguard is
         // showing again
@@ -140,9 +151,11 @@
                 // set when unlocked
                 awaitTimeSpentNotDozing(SEEN_TIMEOUT)
                 clearUnseenOnBeginTracking = true
+                logger.logSeenOnLockscreen()
             } else {
                 if (clearUnseenOnBeginTracking) {
                     clearUnseenOnBeginTracking = false
+                    logger.logAllMarkedSeenOnUnlock()
                     unseenNotifications.clear()
                 }
                 unseenNotifFilter.invalidateList("keyguard no longer showing")
@@ -166,6 +179,8 @@
             .first()
     }
 
+    // Track "unseen" notifications, marking them as seen when either shade is expanded or the
+    // notification becomes heads up.
     private suspend fun trackUnseenNotifications() {
         coroutineScope {
             launch { clearUnseenNotificationsWhenShadeIsExpanded() }
@@ -179,6 +194,7 @@
             // keyguard transition and not the user expanding the shade
             yield()
             if (isExpanded) {
+                logger.logShadeExpanded()
                 unseenNotifications.clear()
             }
         }
@@ -190,6 +206,7 @@
             .forEach { unseenNotifications.remove(it) }
         headsUpManager.headsUpEvents.collect { (entry, isHun) ->
             if (isHun) {
+                logger.logUnseenHun(entry.key)
                 unseenNotifications.remove(entry)
             }
         }
@@ -231,6 +248,7 @@
                 if (
                     keyguardRepository.isKeyguardShowing() || !statusBarStateController.isExpanded
                 ) {
+                    logger.logUnseenAdded(entry.key)
                     unseenNotifications.add(entry)
                 }
             }
@@ -239,12 +257,15 @@
                 if (
                     keyguardRepository.isKeyguardShowing() || !statusBarStateController.isExpanded
                 ) {
+                    logger.logUnseenUpdated(entry.key)
                     unseenNotifications.add(entry)
                 }
             }
 
             override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
-                unseenNotifications.remove(entry)
+                if (unseenNotifications.remove(entry)) {
+                    logger.logUnseenRemoved(entry.key)
+                }
             }
         }
 
@@ -272,6 +293,7 @@
                 }.also { hasFiltered -> hasFilteredAnyNotifs = hasFilteredAnyNotifs || hasFiltered }
 
             override fun onCleanup() {
+                logger.logProviderHasFilteredOutSeenNotifs(hasFilteredAnyNotifs)
                 seenNotifsProvider.hasFilteredOutSeenNotifications = hasFilteredAnyNotifs
                 hasFilteredAnyNotifs = false
             }
@@ -306,11 +328,25 @@
         sectionHeaderVisibilityProvider.sectionHeadersVisible = showSections
     }
 
+    override fun dump(pw: PrintWriter, args: Array<out String>) =
+        with(pw.asIndenting()) {
+            println(
+                "seenNotifsProvider.hasFilteredOutSeenNotifications=" +
+                    seenNotifsProvider.hasFilteredOutSeenNotifications
+            )
+            println("unseen notifications:")
+            indentIfPossible {
+                for (notification in unseenNotifications) {
+                    println(notification.key)
+                }
+            }
+        }
+
     companion object {
         private const val TAG = "KeyguardCoordinator"
         private val SEEN_TIMEOUT = 5.seconds
     }
 }
 
-private val TransitionStep.isScreenTurningOff: Boolean get() =
-    transitionState == TransitionState.STARTED && to != KeyguardState.GONE
\ No newline at end of file
+private val TransitionStep.isScreenTurningOff: Boolean
+    get() = transitionState == TransitionState.STARTED && to != KeyguardState.GONE
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorLogger.kt
new file mode 100644
index 0000000..6503a64
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorLogger.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import com.android.systemui.log.dagger.UnseenNotificationLog
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import javax.inject.Inject
+
+private const val TAG = "KeyguardCoordinator"
+
+class KeyguardCoordinatorLogger
+@Inject
+constructor(
+    @UnseenNotificationLog private val buffer: LogBuffer,
+) {
+    fun logSeenOnLockscreen() =
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            "Notifications on lockscreen will be marked as seen when unlocked."
+        )
+
+    fun logTrackingUnseen(trackingUnseen: Boolean) =
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = { bool1 = trackingUnseen },
+            messagePrinter = { "${if (bool1) "Start" else "Stop"} tracking unseen notifications." },
+        )
+
+    fun logAllMarkedSeenOnUnlock() =
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            "Notifications have been marked as seen now that device is unlocked."
+        )
+
+    fun logShadeExpanded() =
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            "Notifications have been marked as seen due to shade expansion."
+        )
+
+    fun logUnseenAdded(key: String) =
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = { str1 = key },
+            messagePrinter = { "Unseen notif added: $str1" },
+        )
+
+    fun logUnseenUpdated(key: String) =
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = { str1 = key },
+            messagePrinter = { "Unseen notif updated: $str1" },
+        )
+
+    fun logUnseenRemoved(key: String) =
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = { str1 = key },
+            messagePrinter = { "Unseen notif removed: $str1" },
+        )
+
+    fun logProviderHasFilteredOutSeenNotifs(hasFilteredAnyNotifs: Boolean) =
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = { bool1 = hasFilteredAnyNotifs },
+            messagePrinter = { "UI showing unseen filter treatment: $bool1" },
+        )
+
+    fun logUnseenHun(key: String) =
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            messageInitializer = { str1 = key },
+            messagePrinter = { "Unseen notif has become heads up: $str1" },
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index e2f93ce..4177263 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -1235,7 +1235,8 @@
                 // Hide empty shade view when in transition to Keyguard.
                 // That avoids "No Notifications" to blink when transitioning to AOD.
                 // For more details, see: b/228790482
-                && !isInTransitionToKeyguard();
+                && !isInTransitionToKeyguard()
+                && !mCentralSurfaces.isBouncerShowing();
 
         mView.updateEmptyShadeView(shouldShow, mZenModeController.areNotificationsHiddenInShade());
 
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 b15d241..f579d30 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -75,7 +75,7 @@
     boolean DEBUG_WAKEUP_DELAY = Compile.IS_DEBUG;
     // additional instrumentation for testing purposes; intended to be left on during development
     boolean CHATTY = DEBUG;
-    boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = false;
+    boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
     String ACTION_FAKE_ARTWORK = "fake_artwork";
     int FADE_KEYGUARD_START_DELAY = 100;
     int FADE_KEYGUARD_DURATION = 300;
diff --git a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
index 39dda8c..6026d2c 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
@@ -50,6 +50,7 @@
                 Pair.create("surface_variant", MDC.surfaceVariant),
                 Pair.create("on_surface_variant", MDC.onSurfaceVariant),
                 Pair.create("outline", MDC.outline),
+                Pair.create("outline_variant", MDC.outlineVariant),
                 Pair.create("error", MDC.error),
                 Pair.create("on_error", MDC.onError),
                 Pair.create("error_container", MDC.errorContainer),
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index ed40eed..2962c14 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -291,7 +291,7 @@
         when(mSessionTracker.getSessionId(SESSION_KEYGUARD)).thenReturn(mKeyguardInstanceId);
 
         when(mUserManager.isUserUnlocked(anyInt())).thenReturn(true);
-        when(mUserManager.isPrimaryUser()).thenReturn(true);
+        currentUserIsSystem();
         when(mStrongAuthTracker.getStub()).thenReturn(mock(IStrongAuthTracker.Stub.class));
         when(mStrongAuthTracker
                 .isUnlockingWithBiometricAllowed(anyBoolean() /* isClass3Biometric */))
@@ -960,7 +960,7 @@
     public void requestFaceAuth_whenFaceAuthWasStarted_returnsTrue() throws RemoteException {
         // This satisfies all the preconditions to run face auth.
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1467,7 +1467,7 @@
 
         // Preconditions for sfps auth to run
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1503,7 +1503,7 @@
 
         // GIVEN Preconditions for sfps auth to run
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1532,7 +1532,7 @@
 
         // GIVEN Preconditions for sfps auth to run
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1684,7 +1684,7 @@
         // Face auth should run when the following is true.
         keyguardNotGoingAway();
         occludingAppRequestsFaceAuth();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         primaryAuthNotRequiredByStrongAuthTracker();
         biometricsEnabledForCurrentUser();
         currentUserDoesNotHaveTrust();
@@ -1705,7 +1705,7 @@
         // Face auth should run when the following is true.
         bouncerFullyVisibleAndNotGoingToSleep();
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         primaryAuthNotRequiredByStrongAuthTracker();
         biometricsEnabledForCurrentUser();
         currentUserDoesNotHaveTrust();
@@ -1728,7 +1728,7 @@
         // Face auth should run when the following is true.
         bouncerFullyVisibleAndNotGoingToSleep();
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         primaryAuthNotRequiredByStrongAuthTracker();
         biometricsEnabledForCurrentUser();
         currentUserDoesNotHaveTrust();
@@ -1749,7 +1749,7 @@
     public void testShouldListenForFace_whenUserIsNotPrimary_returnsFalse() throws RemoteException {
         cleanupKeyguardUpdateMonitor();
         // This disables face auth
-        when(mUserManager.isPrimaryUser()).thenReturn(false);
+        when(mUserManager.isSystemUser()).thenReturn(false);
         mKeyguardUpdateMonitor =
                 new TestableKeyguardUpdateMonitor(mContext);
 
@@ -1773,7 +1773,7 @@
         // Face auth should run when the following is true.
         keyguardNotGoingAway();
         bouncerFullyVisibleAndNotGoingToSleep();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         biometricsEnabledForCurrentUser();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
@@ -1791,7 +1791,7 @@
             throws RemoteException {
         keyguardNotGoingAway();
         bouncerFullyVisibleAndNotGoingToSleep();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1813,7 +1813,7 @@
         // Face auth should run when the following is true.
         keyguardNotGoingAway();
         bouncerFullyVisibleAndNotGoingToSleep();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1833,7 +1833,7 @@
             throws RemoteException {
         keyguardNotGoingAway();
         bouncerFullyVisibleAndNotGoingToSleep();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1854,7 +1854,7 @@
         // Face auth should run when the following is true.
         keyguardNotGoingAway();
         bouncerFullyVisibleAndNotGoingToSleep();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1876,7 +1876,7 @@
             throws RemoteException {
         // Face auth should run when the following is true.
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1896,7 +1896,7 @@
             throws RemoteException {
         // Face auth should run when the following is true.
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1915,7 +1915,7 @@
     public void testShouldListenForFace_whenKeyguardIsAwake_returnsTrue() throws RemoteException {
         // Preconditions for face auth to run
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1940,7 +1940,7 @@
     public void testShouldListenForFace_whenUdfpsFingerDown_returnsTrue() throws RemoteException {
         // Preconditions for face auth to run
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1959,7 +1959,7 @@
             throws RemoteException {
         // Preconditions for face auth to run
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -1977,7 +1977,7 @@
             throws RemoteException {
         // Preconditions for face auth to run
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -2002,7 +2002,7 @@
             throws RemoteException {
         // Preconditions for face auth to run
         keyguardNotGoingAway();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -2324,7 +2324,7 @@
             throws RemoteException {
         keyguardNotGoingAway();
         bouncerFullyVisibleAndNotGoingToSleep();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -2455,7 +2455,7 @@
         mKeyguardUpdateMonitor.mConfigFaceAuthSupportedPosture = DEVICE_POSTURE_CLOSED;
         keyguardNotGoingAway();
         bouncerFullyVisibleAndNotGoingToSleep();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -2479,7 +2479,7 @@
         mKeyguardUpdateMonitor.mConfigFaceAuthSupportedPosture = DEVICE_POSTURE_UNKNOWN;
         keyguardNotGoingAway();
         bouncerFullyVisibleAndNotGoingToSleep();
-        currentUserIsPrimary();
+        currentUserIsSystem();
         currentUserDoesNotHaveTrust();
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
@@ -2877,8 +2877,8 @@
                         new FaceManager.AuthenticationResult(null, null, mCurrentUserId, false));
     }
 
-    private void currentUserIsPrimary() {
-        when(mUserManager.isPrimaryUser()).thenReturn(true);
+    private void currentUserIsSystem() {
+        when(mUserManager.isSystemUser()).thenReturn(true);
     }
 
     private void biometricsNotDisabledThroughDevicePolicyManager() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 0de9608..8f58140 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -502,7 +502,7 @@
         TestableLooper.get(this).processAllMessages();
 
         assertTrue(mViewMediator.isShowingAndNotOccluded());
-        verify(mStatusBarKeyguardViewManager).reset(anyBoolean());
+        verify(mStatusBarKeyguardViewManager).reset(false);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index a76d03b..fa40fc4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -72,7 +72,6 @@
 import java.io.PrintWriter
 import java.io.StringWriter
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -542,14 +541,6 @@
         }
 
     @Test
-    fun authenticateDoesNotRunWhenCurrentUserIsNotPrimary() =
-        testScope.runTest {
-            testGatingCheckForFaceAuth {
-                launch { fakeUserRepository.setSelectedUserInfo(secondaryUser) }
-            }
-        }
-
-    @Test
     fun authenticateDoesNotRunWhenSecureCameraIsActive() =
         testScope.runTest {
             testGatingCheckForFaceAuth {
@@ -653,6 +644,58 @@
         }
 
     @Test
+    fun isAuthenticatedIsResetToFalseWhenDeviceStartsGoingToSleep() =
+        testScope.runTest {
+            initCollectors()
+            allPreconditionsToRunFaceAuthAreTrue()
+
+            triggerFaceAuth(false)
+
+            authenticationCallback.value.onAuthenticationSucceeded(
+                mock(FaceManager.AuthenticationResult::class.java)
+            )
+
+            assertThat(authenticated()).isTrue()
+
+            keyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.STARTING_TO_SLEEP,
+                    isWakingUpOrAwake = false,
+                    lastWakeReason = WakeSleepReason.POWER_BUTTON,
+                    lastSleepReason = WakeSleepReason.POWER_BUTTON
+                )
+            )
+
+            assertThat(authenticated()).isFalse()
+        }
+
+    @Test
+    fun isAuthenticatedIsResetToFalseWhenDeviceGoesToSleep() =
+        testScope.runTest {
+            initCollectors()
+            allPreconditionsToRunFaceAuthAreTrue()
+
+            triggerFaceAuth(false)
+
+            authenticationCallback.value.onAuthenticationSucceeded(
+                mock(FaceManager.AuthenticationResult::class.java)
+            )
+
+            assertThat(authenticated()).isTrue()
+
+            keyguardRepository.setWakefulnessModel(
+                WakefulnessModel(
+                    WakefulnessState.ASLEEP,
+                    isWakingUpOrAwake = false,
+                    lastWakeReason = WakeSleepReason.POWER_BUTTON,
+                    lastSleepReason = WakeSleepReason.POWER_BUTTON
+                )
+            )
+
+            assertThat(authenticated()).isFalse()
+        }
+
+    @Test
     fun isAuthenticatedIsResetToFalseWhenUserIsSwitching() =
         testScope.runTest {
             initCollectors()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
index 3d1d2f4..5da1a84 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
@@ -279,6 +279,23 @@
         }
 
     @Test
+    fun faceAuthIsCancelledWhenUserInputOnPrimaryBouncer() =
+        testScope.runTest {
+            underTest.start()
+
+            underTest.onSwipeUpOnBouncer()
+
+            runCurrent()
+            assertThat(faceAuthRepository.isAuthRunning.value).isTrue()
+
+            underTest.onPrimaryBouncerUserInput()
+
+            runCurrent()
+
+            assertThat(faceAuthRepository.isAuthRunning.value).isFalse()
+        }
+
+    @Test
     fun faceAuthIsRequestedWhenSwipeUpOnBouncer() =
         testScope.runTest {
             underTest.start()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
index 0c4e845..efa5f0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
@@ -92,6 +92,21 @@
             job.cancel()
         }
 
+    @Test
+    fun lockscreenTranslationYResettedAfterJobCancelled() =
+        runTest(UnconfinedTestDispatcher()) {
+            val values = mutableListOf<Float>()
+
+            val pixels = 100
+            val job =
+                underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
+            repository.sendTransitionStep(step(0.5f, TransitionState.CANCELED))
+
+            assertThat(values.last()).isEqualTo(0f)
+
+            job.cancel()
+        }
+
     private fun step(
         value: Float,
         state: TransitionState = TransitionState.RUNNING
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt
index b997f64..9d6ea85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMediaManagerTest.kt
@@ -16,34 +16,11 @@
 
 package com.android.systemui.statusbar
 
-import android.app.Notification
-import android.app.WallpaperManager
-import android.graphics.Bitmap
-import android.media.MediaMetadata
-import android.media.session.MediaSession
-import android.media.session.PlaybackState
 import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper.RunWithLooper
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.colorextraction.SysuiColorExtractor
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.media.controls.pipeline.MediaDataManager
-import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.statusbar.notification.collection.NotifCollection
-import com.android.systemui.statusbar.notification.collection.NotifPipeline
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider
-import com.android.systemui.statusbar.phone.CentralSurfaces
-import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.policy.KeyguardStateController
-import com.android.systemui.util.concurrency.DelayableExecutor
-import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.time.FakeSystemClock
-import com.google.common.truth.Truth.assertThat
-import dagger.Lazy
-import java.util.Optional
+import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -55,121 +32,39 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
+/**
+ * Temporary test for the lock screen live wallpaper project.
+ *
+ * TODO(b/273443374): remove this test
+ */
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
-@RunWithLooper
 class NotificationMediaManagerTest : SysuiTestCase() {
 
-    @Mock private lateinit var centralSurfaces: CentralSurfaces
-    @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
-    @Mock private lateinit var visibilityProvider: NotificationVisibilityProvider
-    @Mock private lateinit var mediaArtworkProcessor: MediaArtworkProcessor
-    @Mock private lateinit var keyguardBypassController: KeyguardBypassController
-    @Mock private lateinit var notifPipeline: NotifPipeline
-    @Mock private lateinit var notifCollection: NotifCollection
-    @Mock private lateinit var mediaDataManager: MediaDataManager
-    @Mock private lateinit var statusBarStateController: StatusBarStateController
-    @Mock private lateinit var colorExtractor: SysuiColorExtractor
-    @Mock private lateinit var keyguardStateController: KeyguardStateController
-    @Mock private lateinit var dumpManager: DumpManager
-    @Mock private lateinit var wallpaperManager: WallpaperManager
+    @Mock private lateinit var notificationMediaManager: NotificationMediaManager
 
-    @Mock private lateinit var notificationEntry: NotificationEntry
-
-    lateinit var manager: NotificationMediaManager
-    val clock = FakeSystemClock()
-    val mainExecutor: DelayableExecutor = FakeExecutor(clock)
-
-    @Mock private lateinit var mockManager: NotificationMediaManager
     @Mock private lateinit var mockBackDropView: BackDropView
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        doCallRealMethod().whenever(mockManager).updateMediaMetaData(anyBoolean(), anyBoolean())
-        doReturn(mockBackDropView).whenever(mockManager).backDropView
-
-        manager =
-            NotificationMediaManager(
-                context,
-                Lazy { Optional.of(centralSurfaces) },
-                Lazy { notificationShadeWindowController },
-                visibilityProvider,
-                mediaArtworkProcessor,
-                keyguardBypassController,
-                notifPipeline,
-                notifCollection,
-                mainExecutor,
-                mediaDataManager,
-                statusBarStateController,
-                colorExtractor,
-                keyguardStateController,
-                dumpManager,
-                wallpaperManager,
-            )
+        doCallRealMethod()
+            .whenever(notificationMediaManager)
+            .updateMediaMetaData(anyBoolean(), anyBoolean())
+        doReturn(mockBackDropView).whenever(notificationMediaManager).backDropView
     }
 
-    /**
-     * Check that updateMediaMetaData is a no-op with mIsLockscreenLiveWallpaperEnabled = true
-     * Temporary test for the lock screen live wallpaper project.
-     *
-     * TODO(b/273443374): remove this test
-     */
+    @After fun tearDown() {}
+
+    /** Check that updateMediaMetaData is a no-op with mIsLockscreenLiveWallpaperEnabled = true */
     @Test
     fun testUpdateMediaMetaDataDisabled() {
-        mockManager.mIsLockscreenLiveWallpaperEnabled = true
+        notificationMediaManager.mIsLockscreenLiveWallpaperEnabled = true
         for (metaDataChanged in listOf(true, false)) {
             for (allowEnterAnimation in listOf(true, false)) {
-                mockManager.updateMediaMetaData(metaDataChanged, allowEnterAnimation)
-                verify(mockManager, never()).mediaMetadata
+                notificationMediaManager.updateMediaMetaData(metaDataChanged, allowEnterAnimation)
+                verify(notificationMediaManager, never()).mediaMetadata
             }
         }
     }
-
-    @Test
-    fun testMetadataUpdated_doesNotRetainArtwork() {
-        val artBmp = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
-        val artUri = "content://example"
-        val inputMetadata =
-            MediaMetadata.Builder()
-                .putBitmap(MediaMetadata.METADATA_KEY_ART, artBmp)
-                .putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, artBmp)
-                .putBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON, artBmp)
-                .putString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, artUri)
-                .putString(MediaMetadata.METADATA_KEY_ART_URI, artUri)
-                .putString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, artUri)
-                .build()
-
-        // Create a playing media notification
-        val state = PlaybackState.Builder().setState(PlaybackState.STATE_PLAYING, 0L, 1f).build()
-        val session = MediaSession(context, "NotificationMediaManagerTest")
-        session.setMetadata(inputMetadata)
-        session.setPlaybackState(state)
-        val sbn =
-            SbnBuilder().run {
-                modifyNotification(context).also {
-                    it.setSmallIcon(android.R.drawable.ic_media_play)
-                    it.setStyle(
-                        Notification.MediaStyle().apply { setMediaSession(session.sessionToken) }
-                    )
-                }
-                build()
-            }
-        whenever(notificationEntry.sbn).thenReturn(sbn)
-        val collection = ArrayList<NotificationEntry>()
-        collection.add(notificationEntry)
-        whenever(notifPipeline.allNotifs).thenReturn(collection)
-
-        // Trigger update in NotificationMediaManager
-        manager.findAndUpdateMediaNotifications()
-
-        // Verify that there is no artwork data retained
-        val metadata = manager.mediaMetadata
-        assertThat(metadata.getBitmap(MediaMetadata.METADATA_KEY_ART)).isNull()
-        assertThat(metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART)).isNull()
-        assertThat(metadata.getBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON)).isNull()
-        assertThat(metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI)).isNull()
-        assertThat(metadata.getString(MediaMetadata.METADATA_KEY_ART_URI)).isNull()
-        assertThat(metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI)).isNull()
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
index 8f07f8d..c3f5123 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
@@ -24,6 +24,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.advanceTimeBy
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -380,10 +381,12 @@
         val keyguardCoordinator =
             KeyguardCoordinator(
                 testDispatcher,
+                mock<DumpManager>(),
                 headsUpManager,
                 keyguardNotifVisibilityProvider,
                 keyguardRepository,
                 keyguardTransitionRepository,
+                mock<KeyguardCoordinatorLogger>(),
                 notifPipelineFlags,
                 testScope.backgroundScope,
                 sectionHeaderVisibilityProvider,
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 0bdb0c8..a3b4a0f 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -194,7 +194,8 @@
         AccessibilityUserState.ServiceInfoChangeListener,
         AccessibilityWindowManager.AccessibilityEventSender,
         AccessibilitySecurityPolicy.AccessibilityUserManager,
-        SystemActionPerformer.SystemActionsChangedListener, ProxyManager.SystemSupport{
+        SystemActionPerformer.SystemActionsChangedListener,
+        SystemActionPerformer.DisplayUpdateCallBack, ProxyManager.SystemSupport {
 
     private static final boolean DEBUG = false;
 
@@ -1219,7 +1220,7 @@
     private SystemActionPerformer getSystemActionPerformer() {
         if (mSystemActionPerformer == null) {
             mSystemActionPerformer =
-                    new SystemActionPerformer(mContext, mWindowManagerService, null, this);
+                    new SystemActionPerformer(mContext, mWindowManagerService, null, this, this);
         }
         return mSystemActionPerformer;
     }
@@ -1443,17 +1444,19 @@
             return;
         }
         if (!mVisibleBgUserIds.get(userId)) {
-            Slogf.wtf(LOG_TAG, "Cannot change current user to %d as it's not visible "
-                    + "(mVisibleUsers=%s)", userId, mVisibleBgUserIds);
+            Slogf.wtf(LOG_TAG, "changeCurrentUserForTestAutomationIfNeededLocked(): cannot change "
+                    + "current user to %d as it's not visible (mVisibleUsers=%s)",
+                    userId, mVisibleBgUserIds);
             return;
         }
         if (mCurrentUserId == userId) {
-            Slogf.w(LOG_TAG, "NOT changing current user for test automation purposes as it is "
-                    + "already %d", mCurrentUserId);
+            Slogf.d(LOG_TAG, "changeCurrentUserForTestAutomationIfNeededLocked(): NOT changing "
+                    + "current user for test automation purposes as it is already %d",
+                    mCurrentUserId);
             return;
         }
-        Slogf.i(LOG_TAG, "Changing current user from %d to %d for test automation purposes",
-                mCurrentUserId, userId);
+        Slogf.i(LOG_TAG, "changeCurrentUserForTestAutomationIfNeededLocked(): changing current user"
+                + " from %d to %d for test automation purposes", mCurrentUserId, userId);
         mRealCurrentUserId = mCurrentUserId;
         switchUser(userId);
     }
@@ -1466,7 +1469,13 @@
                     + "because device doesn't support visible background users");
             return;
         }
-        Slogf.i(LOG_TAG, "Restoring current user to %d after using %d for test automation purposes",
+        if (mRealCurrentUserId == UserHandle.USER_CURRENT) {
+            Slogf.d(LOG_TAG, "restoreCurrentUserForTestAutomationIfNeededLocked(): ignoring "
+                    + "because mRealCurrentUserId is already USER_CURRENT");
+            return;
+        }
+        Slogf.i(LOG_TAG, "restoreCurrentUserForTestAutomationIfNeededLocked(): restoring current "
+                + "user to %d after using %d for test automation purposes",
                 mRealCurrentUserId, mCurrentUserId);
         int currentUserId = mRealCurrentUserId;
         mRealCurrentUserId = UserHandle.USER_CURRENT;
@@ -1611,6 +1620,18 @@
         }
     }
 
+    @Override
+    // TODO(b/276459590): Remove when this is resolved at the virtual device/input level.
+    public void moveNonProxyTopFocusedDisplayToTopIfNeeded() {
+        mA11yWindowManager.moveNonProxyTopFocusedDisplayToTopIfNeeded();
+    }
+
+    @Override
+    // TODO(b/276459590): Remove when this is resolved at the virtual device/input level.
+    public int getLastNonProxyTopFocusedDisplayId() {
+        return mA11yWindowManager.getLastNonProxyTopFocusedDisplayId();
+    }
+
     @VisibleForTesting
     void notifySystemActionsChangedLocked(AccessibilityUserState userState) {
         for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index a8a5365..78f07e4 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -103,6 +103,9 @@
     // The top focused display and window token updated with the callback of window lists change.
     private int mTopFocusedDisplayId;
     private IBinder mTopFocusedWindowToken;
+
+    // The non-proxy display that most recently had top focus.
+    private int mLastNonProxyTopFocusedDisplayId;
     // The display has the accessibility focused window currently.
     private int mAccessibilityFocusedDisplayId = Display.INVALID_DISPLAY;
 
@@ -451,6 +454,9 @@
                 }
                 if (shouldUpdateWindowsLocked(forceSend, windows)) {
                     mTopFocusedDisplayId = topFocusedDisplayId;
+                    if (!isProxyed(topFocusedDisplayId)) {
+                        mLastNonProxyTopFocusedDisplayId = topFocusedDisplayId;
+                    }
                     mTopFocusedWindowToken = topFocusedWindowToken;
                     if (DEBUG) {
                         Slogf.d(LOG_TAG, "onWindowsForAccessibilityChanged(): updating windows for "
@@ -1141,6 +1147,21 @@
         return false;
     }
 
+    private boolean isProxyed(int displayId) {
+        final DisplayWindowsObserver observer = mDisplayWindowsObservers.get(displayId);
+        return (observer != null && observer.mIsProxy);
+    }
+
+    void moveNonProxyTopFocusedDisplayToTopIfNeeded() {
+        if (mHasProxy
+                && (mLastNonProxyTopFocusedDisplayId != mTopFocusedDisplayId)) {
+            mWindowManagerInternal.moveDisplayToTopIfAllowed(mLastNonProxyTopFocusedDisplayId);
+        }
+    }
+    int getLastNonProxyTopFocusedDisplayId() {
+        return mLastNonProxyTopFocusedDisplayId;
+    }
+
     /**
      * Checks if we are tracking windows on specified display.
      *
diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
index c89b9b8..a13df47 100644
--- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
@@ -72,6 +72,13 @@
     }
     private final SystemActionsChangedListener mListener;
 
+    interface DisplayUpdateCallBack {
+        void moveNonProxyTopFocusedDisplayToTopIfNeeded();
+
+        int getLastNonProxyTopFocusedDisplayId();
+    }
+    private final DisplayUpdateCallBack mDisplayUpdateCallBack;
+
     private final Object mSystemActionLock = new Object();
     // Resource id based ActionId -> RemoteAction
     @GuardedBy("mSystemActionLock")
@@ -94,7 +101,7 @@
     public SystemActionPerformer(
             Context context,
             WindowManagerInternal windowManagerInternal) {
-      this(context, windowManagerInternal, null, null);
+      this(context, windowManagerInternal, null, null, null);
     }
 
     // Used to mock ScreenshotHelper
@@ -103,17 +110,19 @@
             Context context,
             WindowManagerInternal windowManagerInternal,
             Supplier<ScreenshotHelper> screenshotHelperSupplier) {
-        this(context, windowManagerInternal, screenshotHelperSupplier, null);
+        this(context, windowManagerInternal, screenshotHelperSupplier, null, null);
     }
 
     public SystemActionPerformer(
             Context context,
             WindowManagerInternal windowManagerInternal,
             Supplier<ScreenshotHelper> screenshotHelperSupplier,
-            SystemActionsChangedListener listener) {
+            SystemActionsChangedListener listener,
+            DisplayUpdateCallBack callback) {
         mContext = context;
         mWindowManagerService = windowManagerInternal;
         mListener = listener;
+        mDisplayUpdateCallBack = callback;
         mScreenshotHelperSupplier = screenshotHelperSupplier;
 
         mLegacyHomeAction = new AccessibilityAction(
@@ -245,6 +254,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             synchronized (mSystemActionLock) {
+                mDisplayUpdateCallBack.moveNonProxyTopFocusedDisplayToTopIfNeeded();
                 // If a system action is registered with the given actionId, call the corresponding
                 // RemoteAction.
                 RemoteAction registeredAction = mRegisteredSystemActions.get(actionId);
@@ -341,7 +351,7 @@
             int source) {
         KeyEvent event = KeyEvent.obtain(downTime, time, action, keyCode, 0, 0,
                 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM,
-                source, null);
+                source, mDisplayUpdateCallBack.getLastNonProxyTopFocusedDisplayId(), null);
         mContext.getSystemService(InputManager.class)
                 .injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
         event.recycle();
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
index eb71885..d9e25ef 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
@@ -199,6 +199,9 @@
             case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
                 mLastTouchedWindowId = event.getWindowId();
                 break;
+            case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
+                mAms.moveNonProxyTopFocusedDisplayToTopIfNeeded();
+                break;
         }
     }
 
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index b042c30..ff72476 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -397,7 +397,7 @@
                             setUpPipes();
                             mAgent = mBackupManagerService.bindToAgentSynchronous(mTargetApp,
                                     FullBackup.KEY_VALUE_DATA_TOKEN.equals(info.domain)
-                                            ? ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL
+                                            ? ApplicationThreadConstants.BACKUP_MODE_RESTORE
                                             : ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL,
                                     mBackupEligibilityRules.getBackupDestination());
                             mAgentPackage = pkg;
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 1656b6f..77990af 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -677,7 +677,7 @@
         // Good to go!  Set up and bind the agent...
         mAgent = backupManagerService.bindToAgentSynchronous(
                 mCurrentPackage.applicationInfo,
-                ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL,
+                ApplicationThreadConstants.BACKUP_MODE_RESTORE,
                 mBackupEligibilityRules.getBackupDestination());
         if (mAgent == null) {
             Slog.w(TAG, "Can't find backup agent for " + packageName);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 9f9642c..578f520 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -3018,7 +3018,7 @@
         final long identityToken = clearCallingIdentity();
         try {
             // Distill the caller's package signatures into a single digest.
-            final byte[] callerPkgSigDigest = calculatePackageSignatureDigest(callerPkg);
+            final byte[] callerPkgSigDigest = calculatePackageSignatureDigest(callerPkg, userId);
 
             // if the caller has permission, do the peek. otherwise go the more expensive
             // route of starting a Session
@@ -3182,12 +3182,12 @@
                 .write();
     }
 
-    private byte[] calculatePackageSignatureDigest(String callerPkg) {
+    private byte[] calculatePackageSignatureDigest(String callerPkg, int userId) {
         MessageDigest digester;
         try {
             digester = MessageDigest.getInstance("SHA-256");
-            PackageInfo pkgInfo = mPackageManager.getPackageInfo(
-                    callerPkg, PackageManager.GET_SIGNATURES);
+            PackageInfo pkgInfo = mPackageManager.getPackageInfoAsUser(
+                    callerPkg, PackageManager.GET_SIGNATURES, userId);
             for (Signature sig : pkgInfo.signatures) {
                 digester.update(sig.toByteArray());
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 81dc346..1f80aec 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4603,8 +4603,7 @@
             boolean isRestrictedBackupMode = false;
             if (backupTarget != null && backupTarget.appInfo.packageName.equals(processName)) {
                 isRestrictedBackupMode = backupTarget.appInfo.uid >= FIRST_APPLICATION_UID
-                        && ((backupTarget.backupMode == BackupRecord.RESTORE)
-                                || (backupTarget.backupMode == BackupRecord.RESTORE_FULL)
+                        && ((backupTarget.backupMode == BackupRecord.RESTORE_FULL)
                                 || (backupTarget.backupMode == BackupRecord.BACKUP_FULL));
             }
 
@@ -13394,7 +13393,8 @@
 
             BackupRecord r = new BackupRecord(app, backupMode, targetUserId, backupDestination);
             ComponentName hostingName =
-                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
+                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL
+                            || backupMode == ApplicationThreadConstants.BACKUP_MODE_RESTORE)
                             ? new ComponentName(app.packageName, app.backupAgentName)
                             : new ComponentName("android", "FullBackupAgent");
 
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index a3163e0..dcfe397 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -2284,8 +2284,8 @@
                 synchronized (VolumeStreamState.class) {
                     mStreamStates[AudioSystem.STREAM_DTMF]
                             .setAllIndexes(mStreamStates[dtmfStreamAlias], caller);
-                    mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].mVolumeIndexSettingName =
-                            System.VOLUME_SETTINGS_INT[a11yStreamAlias];
+                    mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setSettingName(
+                            System.VOLUME_SETTINGS_INT[a11yStreamAlias]);
                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
                             mStreamStates[a11yStreamAlias], caller);
                 }
@@ -7700,7 +7700,7 @@
         private int mPublicStreamType = AudioSystem.STREAM_MUSIC;
         private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes();
         private boolean mIsMuted = false;
-        private final String mSettingName;
+        private String mSettingName;
 
         // No API in AudioSystem to get a device from strategy or from attributes.
         // Need a valid public stream type to use current API getDeviceForStream
@@ -8029,15 +8029,19 @@
         }
 
         private void persistVolumeGroup(int device) {
-            if (mUseFixedVolume) {
+            // No need to persist the index if the volume group is backed up
+            // by a public stream type as this is redundant
+            if (mUseFixedVolume || mHasValidStreamType) {
                 return;
             }
             if (DEBUG_VOL) {
                 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
                         + mAudioVolumeGroup.name()
                         + ", device " + AudioSystem.getOutputDeviceName(device)
-                        + " and User=" + getCurrentUserId());
+                        + " and User=" + getCurrentUserId()
+                        + " mSettingName: " + mSettingName);
             }
+
             boolean success = mSettings.putSystemIntForUser(mContentResolver,
                     getSettingNameForDevice(device),
                     getIndex(device),
@@ -8100,6 +8104,14 @@
             return mSettingName + "_" + AudioSystem.getOutputDeviceName(device);
         }
 
+        void setSettingName(String settingName) {
+            mSettingName = settingName;
+        }
+
+        String getSettingName() {
+            return mSettingName;
+        }
+
         private void dump(PrintWriter pw) {
             pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":");
             pw.print("   Muted: ");
@@ -8242,6 +8254,9 @@
          */
         public void setVolumeGroupState(VolumeGroupState volumeGroupState) {
             mVolumeGroupState = volumeGroupState;
+            if (mVolumeGroupState != null) {
+                mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
+            }
         }
         /**
          * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
@@ -8315,6 +8330,17 @@
             return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty());
         }
 
+        void setSettingName(String settingName) {
+            mVolumeIndexSettingName = settingName;
+            if (mVolumeGroupState != null) {
+                mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
+            }
+        }
+
+        String getSettingName() {
+            return mVolumeIndexSettingName;
+        }
+
         public void readSettings() {
             synchronized (mSettingsLock) {
                 synchronized (VolumeStreamState.class) {
@@ -8989,7 +9015,7 @@
             if (streamState.hasValidSettingsName()) {
                 mSettings.putSystemIntForUser(mContentResolver,
                         streamState.getSettingNameForDevice(device),
-                        (streamState.getIndex(device) + 5)/ 10,
+                        (streamState.getIndex(device) + 5) / 10,
                         UserHandle.USER_CURRENT);
             }
         }
@@ -12452,20 +12478,16 @@
         }
 
         int addMixes(@NonNull ArrayList<AudioMix> mixes) {
-            // TODO optimize to not have to unregister the mixes already in place
             synchronized (mMixes) {
-                mAudioSystem.registerPolicyMixes(mMixes, false);
                 this.add(mixes);
-                return mAudioSystem.registerPolicyMixes(mMixes, true);
+                return mAudioSystem.registerPolicyMixes(mixes, true);
             }
         }
 
         int removeMixes(@NonNull ArrayList<AudioMix> mixes) {
-            // TODO optimize to not have to unregister the mixes already in place
             synchronized (mMixes) {
-                mAudioSystem.registerPolicyMixes(mMixes, false);
                 this.remove(mixes);
-                return mAudioSystem.registerPolicyMixes(mMixes, true);
+                return mAudioSystem.registerPolicyMixes(mixes, false);
             }
         }
 
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 85b4034..5d92c7f 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -119,7 +119,6 @@
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.text.TextUtils;
-import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.IntArray;
@@ -298,11 +297,10 @@
             mDisplayWindowPolicyControllers = new SparseArray<>();
 
     /**
-     *  Map of every internal primary display device {@link HighBrightnessModeMetadata}s indexed by
-     *  {@link DisplayDevice#mUniqueId}.
+     * Provides {@link HighBrightnessModeMetadata}s for {@link DisplayDevice}s.
      */
-    public final ArrayMap<String, HighBrightnessModeMetadata> mHighBrightnessModeMetadataMap =
-            new ArrayMap<>();
+    private final HighBrightnessModeMetadataMapper mHighBrightnessModeMetadataMapper =
+            new HighBrightnessModeMetadataMapper();
 
     // List of all currently registered display adapters.
     private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
@@ -1823,19 +1821,14 @@
 
         DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
         if (dpc != null) {
-            final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
-            if (device == null) {
-                Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: "
-                        + display.getDisplayIdLocked());
-                return;
-            }
-
             final int leadDisplayId = display.getLeadDisplayIdLocked();
             updateDisplayPowerControllerLeaderLocked(dpc, leadDisplayId);
 
-            final String uniqueId = device.getUniqueId();
-            HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
-            dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
+            HighBrightnessModeMetadata hbmMetadata =
+                    mHighBrightnessModeMetadataMapper.getHighBrightnessModeMetadataLocked(display);
+            if (hbmMetadata != null) {
+                dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
+            }
         }
     }
 
@@ -1922,19 +1915,14 @@
         final int displayId = display.getDisplayIdLocked();
         final DisplayPowerControllerInterface dpc = mDisplayPowerControllers.get(displayId);
         if (dpc != null) {
-            final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
-            if (device == null) {
-                Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: "
-                        + display.getDisplayIdLocked());
-                return;
-            }
-
             final int leadDisplayId = display.getLeadDisplayIdLocked();
             updateDisplayPowerControllerLeaderLocked(dpc, leadDisplayId);
 
-            final String uniqueId = device.getUniqueId();
-            HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
-            dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
+            HighBrightnessModeMetadata hbmMetadata =
+                    mHighBrightnessModeMetadataMapper.getHighBrightnessModeMetadataLocked(display);
+            if (hbmMetadata != null) {
+                dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
+            }
         }
     }
 
@@ -3073,26 +3061,6 @@
         mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked);
     }
 
-    private HighBrightnessModeMetadata getHighBrightnessModeMetadata(LogicalDisplay display) {
-        final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
-        if (device == null) {
-            Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: "
-                    + display.getDisplayIdLocked());
-            return null;
-        }
-
-        final String uniqueId = device.getUniqueId();
-
-        if (mHighBrightnessModeMetadataMap.containsKey(uniqueId)) {
-            return mHighBrightnessModeMetadataMap.get(uniqueId);
-        }
-
-        // HBM Time info not present. Create a new one for this physical display.
-        HighBrightnessModeMetadata hbmInfo = new HighBrightnessModeMetadata();
-        mHighBrightnessModeMetadataMap.put(uniqueId, hbmInfo);
-        return hbmInfo;
-    }
-
     @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
     private void addDisplayPowerControllerLocked(LogicalDisplay display) {
         if (mPowerHandler == null) {
@@ -3113,7 +3081,13 @@
         // We also need to pass a mapping of the HighBrightnessModeTimeInfoMap to
         // displayPowerController, so the hbm info can be correctly associated
         // with the corresponding displaydevice.
-        HighBrightnessModeMetadata hbmMetadata = getHighBrightnessModeMetadata(display);
+        HighBrightnessModeMetadata hbmMetadata =
+                mHighBrightnessModeMetadataMapper.getHighBrightnessModeMetadataLocked(display);
+        if (hbmMetadata == null) {
+            Slog.wtf(TAG, "High Brightness Mode Metadata is null in DisplayManagerService for "
+                    + "display: " + display.getDisplayIdLocked());
+            return;
+        }
         if (DeviceConfig.getBoolean("display_manager",
                 "use_newly_structured_display_power_controller", true)) {
             displayPowerController = new DisplayPowerController2(
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeMetadataMapper.java b/services/core/java/com/android/server/display/HighBrightnessModeMetadataMapper.java
new file mode 100644
index 0000000..76702d3
--- /dev/null
+++ b/services/core/java/com/android/server/display/HighBrightnessModeMetadataMapper.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import android.util.ArrayMap;
+import android.util.Slog;
+
+/**
+ * Provides {@link HighBrightnessModeMetadata}s for {@link DisplayDevice}s. This class should only
+ * be accessed from the display thread.
+ */
+class HighBrightnessModeMetadataMapper {
+
+    private static final String TAG = "HighBrightnessModeMetadataMapper";
+
+    /**
+     *  Map of every internal primary display device {@link HighBrightnessModeMetadata}s indexed by
+     *  {@link DisplayDevice#mUniqueId}.
+     */
+    private final ArrayMap<String, HighBrightnessModeMetadata> mHighBrightnessModeMetadataMap =
+            new ArrayMap<>();
+
+    HighBrightnessModeMetadata getHighBrightnessModeMetadataLocked(LogicalDisplay display) {
+        final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
+        if (device == null) {
+            Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: "
+                    + display.getDisplayIdLocked());
+            return null;
+        }
+
+        final String uniqueId = device.getUniqueId();
+
+        if (mHighBrightnessModeMetadataMap.containsKey(uniqueId)) {
+            return mHighBrightnessModeMetadataMap.get(uniqueId);
+        }
+
+        // HBM Time info not present. Create a new one for this physical display.
+        HighBrightnessModeMetadata hbmInfo = new HighBrightnessModeMetadata();
+        mHighBrightnessModeMetadataMap.put(uniqueId, hbmInfo);
+        return hbmInfo;
+    }
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 9eedc4e..f47c4b2 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -682,7 +682,6 @@
     @ServiceThreadOnly
     private void launchDeviceDiscovery() {
         assertRunOnServiceThread();
-        clearDeviceInfoList();
         DeviceDiscoveryAction action = new DeviceDiscoveryAction(this,
                 new DeviceDiscoveryCallback() {
                     @Override
@@ -691,13 +690,6 @@
                             mService.getHdmiCecNetwork().addCecDevice(info);
                         }
 
-                        // Since we removed all devices when it starts and
-                        // device discovery action does not poll local devices,
-                        // we should put device info of local device manually here
-                        for (HdmiCecLocalDevice device : mService.getAllCecLocalDevices()) {
-                            mService.getHdmiCecNetwork().addCecDevice(device.getDeviceInfo());
-                        }
-
                         mSelectRequestBuffer.process();
                         resetSelectRequestBuffer();
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 805ff66..75fe63a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1267,6 +1267,7 @@
         // It's now safe to flush existing local devices from mCecController since they were
         // already moved to 'localDevices'.
         clearCecLocalDevices();
+        mHdmiCecNetwork.clearDeviceList();
         allocateLogicalAddress(localDevices, initiatedBy);
     }
 
@@ -1303,6 +1304,7 @@
                                         HdmiControlManager.POWER_STATUS_ON, getCecVersion());
                                 localDevice.setDeviceInfo(deviceInfo);
                                 mHdmiCecNetwork.addLocalDevice(deviceType, localDevice);
+                                mHdmiCecNetwork.addCecDevice(localDevice.getDeviceInfo());
                                 mCecController.addLogicalAddress(logicalAddress);
                                 allocatedDevices.add(localDevice);
                             }
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
index 0ae1e80..a1b67e1 100644
--- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
+++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
@@ -18,14 +18,19 @@
 
 import static android.view.inputmethod.ImeTracker.DEBUG_IME_VISIBILITY;
 
+import static com.android.internal.inputmethod.SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS;
+import static com.android.internal.inputmethod.SoftInputShowHideReason.SHOW_IME_SCREENSHOT_FROM_IMMS;
 import static com.android.server.EventLogTags.IMF_HIDE_IME;
 import static com.android.server.EventLogTags.IMF_SHOW_IME;
 import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME;
 import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME_EXPLICIT;
 import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME_NOT_ALWAYS;
+import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_REMOVE_IME_SNAPSHOT;
 import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_SHOW_IME;
 import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_SHOW_IME_IMPLICIT;
+import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_SHOW_IME_SNAPSHOT;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.IBinder;
 import android.os.ResultReceiver;
@@ -38,6 +43,7 @@
 import com.android.internal.inputmethod.InputMethodDebug;
 import com.android.internal.inputmethod.SoftInputShowHideReason;
 import com.android.server.LocalServices;
+import com.android.server.wm.ImeTargetVisibilityPolicy;
 import com.android.server.wm.WindowManagerInternal;
 
 import java.util.Objects;
@@ -56,10 +62,14 @@
 
     private final WindowManagerInternal mWindowManagerInternal;
 
+    @NonNull
+    private final ImeTargetVisibilityPolicy mImeTargetVisibilityPolicy;
+
 
     DefaultImeVisibilityApplier(InputMethodManagerService service) {
         mService = service;
         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+        mImeTargetVisibilityPolicy = LocalServices.getService(ImeTargetVisibilityPolicy.class);
     }
 
     @GuardedBy("ImfLock.class")
@@ -162,8 +172,37 @@
                 mService.showCurrentInputLocked(windowToken, statsToken,
                         InputMethodManager.SHOW_IMPLICIT, null, reason);
                 break;
+            case STATE_SHOW_IME_SNAPSHOT:
+                showImeScreenshot(windowToken, mService.getDisplayIdToShowImeLocked(), null);
+                break;
+            case STATE_REMOVE_IME_SNAPSHOT:
+                removeImeScreenshot(mService.getDisplayIdToShowImeLocked());
+                break;
             default:
                 throw new IllegalArgumentException("Invalid IME visibility state: " + state);
         }
     }
+
+    @GuardedBy("ImfLock.class")
+    @Override
+    public boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId,
+            @Nullable ImeTracker.Token statsToken) {
+        if (mImeTargetVisibilityPolicy.showImeScreenshot(imeTarget, displayId)) {
+            mService.onShowHideSoftInputRequested(false /* show */, imeTarget,
+                    SHOW_IME_SCREENSHOT_FROM_IMMS, statsToken);
+            return true;
+        }
+        return false;
+    }
+
+    @GuardedBy("ImfLock.class")
+    @Override
+    public boolean removeImeScreenshot(int displayId) {
+        if (mImeTargetVisibilityPolicy.removeImeScreenshot(displayId)) {
+            mService.onShowHideSoftInputRequested(false /* show */, mService.mCurFocusedWindow,
+                    REMOVE_IME_SCREENSHOT_FROM_IMMS, null);
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java
index f03e985..27f6a89 100644
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java
@@ -16,6 +16,7 @@
 
 package com.android.server.inputmethod;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.IBinder;
 import android.os.ResultReceiver;
@@ -76,4 +77,27 @@
         // TODO: add a method in WindowManagerInternal to call DC#updateImeInputAndControlTarget
         //  here to end up updating IME layering after IMMS#attachNewInputLocked called.
     }
+
+    /**
+     * Shows the IME screenshot and attach it to the given IME target window.
+     *
+     * @param windowToken The token of a window to show the IME screenshot.
+     * @param displayId The unique id to identify the display
+     * @param statsToken  A token that tracks the progress of an IME request.
+     * @return {@code true} if success, {@code false} otherwise.
+     */
+    default boolean showImeScreenshot(@NonNull IBinder windowToken, int displayId,
+            @Nullable ImeTracker.Token statsToken) {
+        return false;
+    }
+
+    /**
+     * Removes the IME screenshot on the given display.
+     *
+     * @param displayId The target display of showing IME screenshot.
+     * @return {@code true} if success, {@code false} otherwise.
+     */
+    default boolean removeImeScreenshot(int displayId) {
+        return false;
+    }
 }
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
index 61fe654..19d6fa0 100644
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
@@ -29,6 +29,8 @@
 import static android.view.WindowManager.LayoutParams.SoftInputModeFlags;
 
 import static com.android.internal.inputmethod.InputMethodDebug.softInputModeToString;
+import static com.android.internal.inputmethod.SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS;
+import static com.android.internal.inputmethod.SoftInputShowHideReason.SHOW_IME_SCREENSHOT_FROM_IMMS;
 import static com.android.server.inputmethod.InputMethodManagerService.computeImeDisplayIdForTarget;
 
 import android.accessibilityservice.AccessibilityService;
@@ -49,6 +51,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.inputmethod.SoftInputShowHideReason;
 import com.android.server.LocalServices;
+import com.android.server.wm.ImeTargetChangeListener;
 import com.android.server.wm.WindowManagerInternal;
 
 import java.io.PrintWriter;
@@ -99,6 +102,18 @@
      */
     private boolean mInputShown;
 
+    /**
+     * Set if we called
+     * {@link com.android.server.wm.ImeTargetVisibilityPolicy#showImeScreenshot(IBinder, int)}.
+     */
+    private boolean mRequestedImeScreenshot;
+
+    /** The window token of the current visible IME layering target overlay. */
+    private IBinder mCurVisibleImeLayeringOverlay;
+
+    /** The window token of the current visible IME input target. */
+    private IBinder mCurVisibleImeInputTarget;
+
     /** Represent the invalid IME visibility state */
     public static final int STATE_INVALID = -1;
 
@@ -122,6 +137,10 @@
     public static final int STATE_HIDE_IME_NOT_ALWAYS = 6;
 
     public static final int STATE_SHOW_IME_IMPLICIT = 7;
+
+    /** State to handle removing an IME preview surface when necessary. */
+    public static final int STATE_REMOVE_IME_SNAPSHOT = 8;
+
     @IntDef({
             STATE_INVALID,
             STATE_HIDE_IME,
@@ -132,6 +151,7 @@
             STATE_HIDE_IME_EXPLICIT,
             STATE_HIDE_IME_NOT_ALWAYS,
             STATE_SHOW_IME_IMPLICIT,
+            STATE_REMOVE_IME_SNAPSHOT,
     })
     @interface VisibilityState {}
 
@@ -172,6 +192,24 @@
         mWindowManagerInternal = wmService;
         mImeDisplayValidator = imeDisplayValidator;
         mPolicy = imePolicy;
+        mWindowManagerInternal.setInputMethodTargetChangeListener(new ImeTargetChangeListener() {
+            @Override
+            public void onImeTargetOverlayVisibilityChanged(IBinder overlayWindowToken,
+                    boolean visible, boolean removed) {
+                mCurVisibleImeLayeringOverlay = (visible && !removed) ? overlayWindowToken : null;
+            }
+
+            @Override
+            public void onImeInputTargetVisibilityChanged(IBinder imeInputTarget,
+                    boolean visibleRequested, boolean removed) {
+                mCurVisibleImeInputTarget = (visibleRequested && !removed) ? imeInputTarget : null;
+                if (mCurVisibleImeInputTarget == null && mCurVisibleImeLayeringOverlay != null) {
+                    mService.onApplyImeVisibilityFromComputer(imeInputTarget,
+                            new ImeVisibilityResult(STATE_HIDE_IME_EXPLICIT,
+                                    SoftInputShowHideReason.HIDE_WHEN_INPUT_TARGET_INVISIBLE));
+                }
+            }
+        });
     }
 
     /**
@@ -453,6 +491,21 @@
         return null;
     }
 
+    @VisibleForTesting
+    ImeVisibilityResult onInteractiveChanged(IBinder windowToken, boolean interactive) {
+        final ImeTargetWindowState state = getWindowStateOrNull(windowToken);
+        if (state != null && state.isRequestedImeVisible() && mInputShown && !interactive) {
+            mRequestedImeScreenshot = true;
+            return new ImeVisibilityResult(STATE_SHOW_IME_SNAPSHOT, SHOW_IME_SCREENSHOT_FROM_IMMS);
+        }
+        if (interactive && mRequestedImeScreenshot) {
+            mRequestedImeScreenshot = false;
+            return new ImeVisibilityResult(STATE_REMOVE_IME_SNAPSHOT,
+                    REMOVE_IME_SCREENSHOT_FROM_IMMS);
+        }
+        return null;
+    }
+
     IBinder getWindowTokenFrom(IBinder requestImeToken) {
         for (IBinder windowToken : mRequestWindowStateMap.keySet()) {
             final ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 2433211..c70d555 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -4847,6 +4847,14 @@
         }
     }
 
+    void onApplyImeVisibilityFromComputer(IBinder windowToken,
+            @NonNull ImeVisibilityResult result) {
+        synchronized (ImfLock.class) {
+            mVisibilityApplier.applyImeVisibility(windowToken, null, result.getState(),
+                    result.getReason());
+        }
+    }
+
     @GuardedBy("ImfLock.class")
     void setEnabledSessionLocked(SessionState session) {
         if (mEnabledSession != session) {
@@ -5083,6 +5091,14 @@
                 return;
             }
             if (mImePlatformCompatUtils.shouldUseSetInteractiveProtocol(getCurMethodUidLocked())) {
+                // Handle IME visibility when interactive changed before finishing the input to
+                // ensure we preserve the last state as possible.
+                final ImeVisibilityResult imeVisRes = mVisibilityStateComputer.onInteractiveChanged(
+                        mCurFocusedWindow, interactive);
+                if (imeVisRes != null) {
+                    mVisibilityApplier.applyImeVisibility(mCurFocusedWindow, null,
+                            imeVisRes.getState(), imeVisRes.getReason());
+                }
                 // Eligible IME processes use new "setInteractive" protocol.
                 mCurClient.mClient.setInteractive(mIsInteractive, mInFullscreenMode);
             } else {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ebcbfed..07891f3 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -10796,7 +10796,8 @@
         static final String FLAG_SEPARATOR = "\\|";
 
         private final ArraySet<ManagedServiceInfo> mLightTrimListeners = new ArraySet<>();
-        ArrayMap<Pair<ComponentName, Integer>, NotificationListenerFilter>
+        @GuardedBy("mRequestedNotificationListeners")
+        private final ArrayMap<Pair<ComponentName, Integer>, NotificationListenerFilter>
                 mRequestedNotificationListeners = new ArrayMap<>();
         private final boolean mIsHeadlessSystemUserMode;
 
@@ -10914,9 +10915,11 @@
         @Override
         public void onUserRemoved(int user) {
             super.onUserRemoved(user);
-            for (int i = mRequestedNotificationListeners.size() - 1; i >= 0; i--) {
-                if (mRequestedNotificationListeners.keyAt(i).second == user) {
-                    mRequestedNotificationListeners.removeAt(i);
+            synchronized (mRequestedNotificationListeners) {
+                for (int i = mRequestedNotificationListeners.size() - 1; i >= 0; i--) {
+                    if (mRequestedNotificationListeners.keyAt(i).second == user) {
+                        mRequestedNotificationListeners.removeAt(i);
+                    }
                 }
             }
         }
@@ -10925,31 +10928,34 @@
         public void onPackagesChanged(boolean removingPackage, String[] pkgList, int[] uidList) {
             super.onPackagesChanged(removingPackage, pkgList, uidList);
 
-            // Since the default behavior is to allow everything, we don't need to explicitly
-            // handle package add or update. they will be added to the xml file on next boot or
-            // when the user tries to change the settings.
-            if (removingPackage) {
-                for (int i = 0; i < pkgList.length; i++) {
-                    String pkg = pkgList[i];
-                    int userId = UserHandle.getUserId(uidList[i]);
-                    for (int j = mRequestedNotificationListeners.size() - 1; j >= 0; j--) {
-                        Pair<ComponentName, Integer> key = mRequestedNotificationListeners.keyAt(j);
-                        if (key.second == userId && key.first.getPackageName().equals(pkg)) {
-                            mRequestedNotificationListeners.removeAt(j);
+            synchronized (mRequestedNotificationListeners) {
+                // Since the default behavior is to allow everything, we don't need to explicitly
+                // handle package add or update. they will be added to the xml file on next boot or
+                // when the user tries to change the settings.
+                if (removingPackage) {
+                    for (int i = 0; i < pkgList.length; i++) {
+                        String pkg = pkgList[i];
+                        int userId = UserHandle.getUserId(uidList[i]);
+                        for (int j = mRequestedNotificationListeners.size() - 1; j >= 0; j--) {
+                            Pair<ComponentName, Integer> key =
+                                    mRequestedNotificationListeners.keyAt(j);
+                            if (key.second == userId && key.first.getPackageName().equals(pkg)) {
+                                mRequestedNotificationListeners.removeAt(j);
+                            }
                         }
                     }
                 }
-            }
 
-            // clean up anything in the disallowed pkgs list
-            for (int i = 0; i < pkgList.length; i++) {
-                String pkg = pkgList[i];
-                int userId = UserHandle.getUserId(uidList[i]);
-                for (int j = mRequestedNotificationListeners.size() - 1; j >= 0; j--) {
-                    NotificationListenerFilter nlf = mRequestedNotificationListeners.valueAt(j);
+                // clean up anything in the disallowed pkgs list
+                for (int i = 0; i < pkgList.length; i++) {
+                    String pkg = pkgList[i];
+                    for (int j = mRequestedNotificationListeners.size() - 1; j >= 0; j--) {
+                        NotificationListenerFilter nlf =
+                                mRequestedNotificationListeners.valueAt(j);
 
-                    VersionedPackage ai = new VersionedPackage(pkg, uidList[i]);
-                    nlf.removePackage(ai);
+                        VersionedPackage ai = new VersionedPackage(pkg, uidList[i]);
+                        nlf.removePackage(ai);
+                    }
                 }
             }
         }
@@ -10997,7 +11003,9 @@
                     }
                     NotificationListenerFilter nlf =
                             new NotificationListenerFilter(approved, disallowedPkgs);
-                    mRequestedNotificationListeners.put(Pair.create(cn, userId), nlf);
+                    synchronized (mRequestedNotificationListeners) {
+                        mRequestedNotificationListeners.put(Pair.create(cn, userId), nlf);
+                    }
                 }
             }
         }
@@ -11005,72 +11013,81 @@
         @Override
         protected void writeExtraXmlTags(TypedXmlSerializer out) throws IOException {
             out.startTag(null, TAG_REQUESTED_LISTENERS);
-            for (Pair<ComponentName, Integer> listener : mRequestedNotificationListeners.keySet()) {
-                NotificationListenerFilter nlf = mRequestedNotificationListeners.get(listener);
-                out.startTag(null, TAG_REQUESTED_LISTENER);
-                XmlUtils.writeStringAttribute(
-                        out, ATT_COMPONENT, listener.first.flattenToString());
-                XmlUtils.writeIntAttribute(out, ATT_USER_ID, listener.second);
+            synchronized (mRequestedNotificationListeners) {
+                for (Pair<ComponentName, Integer> listener :
+                        mRequestedNotificationListeners.keySet()) {
+                    NotificationListenerFilter nlf = mRequestedNotificationListeners.get(listener);
+                    out.startTag(null, TAG_REQUESTED_LISTENER);
+                    XmlUtils.writeStringAttribute(
+                            out, ATT_COMPONENT, listener.first.flattenToString());
+                    XmlUtils.writeIntAttribute(out, ATT_USER_ID, listener.second);
 
-                out.startTag(null, TAG_APPROVED);
-                XmlUtils.writeIntAttribute(out, ATT_TYPES, nlf.getTypes());
-                out.endTag(null, TAG_APPROVED);
+                    out.startTag(null, TAG_APPROVED);
+                    XmlUtils.writeIntAttribute(out, ATT_TYPES, nlf.getTypes());
+                    out.endTag(null, TAG_APPROVED);
 
-                for (VersionedPackage ai : nlf.getDisallowedPackages()) {
-                    if (!TextUtils.isEmpty(ai.getPackageName())) {
-                        out.startTag(null, TAG_DISALLOWED);
-                        XmlUtils.writeStringAttribute(out, ATT_PKG, ai.getPackageName());
-                        XmlUtils.writeIntAttribute(out, ATT_UID, ai.getVersionCode());
-                        out.endTag(null, TAG_DISALLOWED);
+                    for (VersionedPackage ai : nlf.getDisallowedPackages()) {
+                        if (!TextUtils.isEmpty(ai.getPackageName())) {
+                            out.startTag(null, TAG_DISALLOWED);
+                            XmlUtils.writeStringAttribute(out, ATT_PKG, ai.getPackageName());
+                            XmlUtils.writeIntAttribute(out, ATT_UID, ai.getVersionCode());
+                            out.endTag(null, TAG_DISALLOWED);
+                        }
                     }
-                }
 
-                out.endTag(null, TAG_REQUESTED_LISTENER);
+                    out.endTag(null, TAG_REQUESTED_LISTENER);
+                }
             }
 
             out.endTag(null, TAG_REQUESTED_LISTENERS);
         }
 
-        protected @Nullable NotificationListenerFilter getNotificationListenerFilter(
+        @Nullable protected NotificationListenerFilter getNotificationListenerFilter(
                 Pair<ComponentName, Integer> pair) {
-            return mRequestedNotificationListeners.get(pair);
+            synchronized (mRequestedNotificationListeners) {
+                return mRequestedNotificationListeners.get(pair);
+            }
         }
 
         protected void setNotificationListenerFilter(Pair<ComponentName, Integer> pair,
                 NotificationListenerFilter nlf) {
-            mRequestedNotificationListeners.put(pair, nlf);
+            synchronized (mRequestedNotificationListeners) {
+                mRequestedNotificationListeners.put(pair, nlf);
+            }
         }
 
         @Override
         protected void ensureFilters(ServiceInfo si, int userId) {
-            Pair listener = Pair.create(si.getComponentName(), userId);
-            NotificationListenerFilter existingNlf =
-                    mRequestedNotificationListeners.get(listener);
-            if (si.metaData != null) {
-                if (existingNlf  == null) {
-                    // no stored filters for this listener; see if they provided a default
-                    if (si.metaData.containsKey(META_DATA_DEFAULT_FILTER_TYPES)) {
-                        String typeList =
-                                si.metaData.get(META_DATA_DEFAULT_FILTER_TYPES).toString();
-                        if (typeList != null) {
-                            int types = getTypesFromStringList(typeList);
-                            NotificationListenerFilter nlf =
-                                    new NotificationListenerFilter(types, new ArraySet<>());
-                            mRequestedNotificationListeners.put(listener, nlf);
+            Pair<ComponentName, Integer> listener = Pair.create(si.getComponentName(), userId);
+            synchronized (mRequestedNotificationListeners) {
+                NotificationListenerFilter existingNlf =
+                        mRequestedNotificationListeners.get(listener);
+                if (si.metaData != null) {
+                    if (existingNlf == null) {
+                        // no stored filters for this listener; see if they provided a default
+                        if (si.metaData.containsKey(META_DATA_DEFAULT_FILTER_TYPES)) {
+                            String typeList =
+                                    si.metaData.get(META_DATA_DEFAULT_FILTER_TYPES).toString();
+                            if (typeList != null) {
+                                int types = getTypesFromStringList(typeList);
+                                NotificationListenerFilter nlf =
+                                        new NotificationListenerFilter(types, new ArraySet<>());
+                                mRequestedNotificationListeners.put(listener, nlf);
+                            }
                         }
                     }
-                }
 
-                // also check the types they never want bridged
-                if (si.metaData.containsKey(META_DATA_DISABLED_FILTER_TYPES)) {
-                    int neverBridge = getTypesFromStringList(si.metaData.get(
-                            META_DATA_DISABLED_FILTER_TYPES).toString());
-                    if (neverBridge != 0) {
-                        NotificationListenerFilter nlf =
-                                mRequestedNotificationListeners.getOrDefault(
-                                        listener, new NotificationListenerFilter());
-                        nlf.setTypes(nlf.getTypes() & ~neverBridge);
-                        mRequestedNotificationListeners.put(listener, nlf);
+                    // also check the types they never want bridged
+                    if (si.metaData.containsKey(META_DATA_DISABLED_FILTER_TYPES)) {
+                        int neverBridge = getTypesFromStringList(si.metaData.get(
+                                META_DATA_DISABLED_FILTER_TYPES).toString());
+                        if (neverBridge != 0) {
+                            NotificationListenerFilter nlf =
+                                    mRequestedNotificationListeners.getOrDefault(
+                                            listener, new NotificationListenerFilter());
+                            nlf.setTypes(nlf.getTypes() & ~neverBridge);
+                            mRequestedNotificationListeners.put(listener, nlf);
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/pm/VerifyingSession.java b/services/core/java/com/android/server/pm/VerifyingSession.java
index 5015985..7198de2 100644
--- a/services/core/java/com/android/server/pm/VerifyingSession.java
+++ b/services/core/java/com/android/server/pm/VerifyingSession.java
@@ -353,11 +353,10 @@
             PackageInfoLite pkgLite,
             PackageVerificationState verificationState) {
 
-        // TODO: http://b/22976637
-        // Apps installed for "all" users use the device owner to verify the app
+        // Apps installed for "all" users use the current user to verify the app
         UserHandle verifierUser = getUser();
         if (verifierUser == UserHandle.ALL) {
-            verifierUser = UserHandle.SYSTEM;
+            verifierUser = UserHandle.of(mPm.mUserManager.getCurrentUserId());
         }
         final int verifierUserId = verifierUser.getIdentifier();
 
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 984cb19..31348cd 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -42,7 +42,6 @@
 import android.service.textclassifier.TextClassifierService;
 import android.service.textclassifier.TextClassifierService.ConnectionState;
 import android.text.TextUtils;
-import android.util.ArrayMap;
 import android.util.LruCache;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -74,7 +73,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.Objects;
 
 /**
@@ -388,14 +387,13 @@
 
         synchronized (mLock) {
             final StrippedTextClassificationContext textClassificationContext =
-                    mSessionCache.get(sessionId);
+                    mSessionCache.get(sessionId.getToken());
             final int userId = textClassificationContext != null
                     ? textClassificationContext.userId
                     : UserHandle.getCallingUserId();
             final boolean useDefaultTextClassifier =
-                    textClassificationContext != null
-                            ? textClassificationContext.useDefaultTextClassifier
-                            : true;
+                    textClassificationContext == null
+                            || textClassificationContext.useDefaultTextClassifier;
             final SystemTextClassifierMetadata sysTcMetadata = new SystemTextClassifierMetadata(
                     "", userId, useDefaultTextClassifier);
 
@@ -405,7 +403,7 @@
                     /* attemptToBind= */ false,
                     service -> {
                         service.onDestroyTextClassificationSession(sessionId);
-                        mSessionCache.remove(sessionId);
+                        mSessionCache.remove(sessionId.getToken());
                     },
                     "onDestroyTextClassificationSession",
                     NO_OP_CALLBACK);
@@ -676,14 +674,39 @@
 
         @NonNull
         private final Object mLock;
+
+        @NonNull
+        private final DeathRecipient mDeathRecipient = new DeathRecipient() {
+            @Override
+            public void binderDied() {
+                // no-op
+            }
+
+            @Override
+            public void binderDied(IBinder who) {
+                if (DEBUG) {
+                    Slog.d(LOG_TAG, "binderDied for " + who);
+                }
+                remove(who);
+            }
+        };
         @NonNull
         @GuardedBy("mLock")
-        private final LruCache<TextClassificationSessionId, StrippedTextClassificationContext>
-                mCache = new LruCache<>(MAX_CACHE_SIZE);
-        @NonNull
-        @GuardedBy("mLock")
-        private final Map<TextClassificationSessionId, DeathRecipient> mDeathRecipients =
-                new ArrayMap<>();
+        private final LruCache<IBinder, StrippedTextClassificationContext>
+                mCache = new LruCache<>(MAX_CACHE_SIZE) {
+                    @Override
+                    protected void entryRemoved(boolean evicted,
+                            IBinder token,
+                            StrippedTextClassificationContext oldValue,
+                            StrippedTextClassificationContext newValue) {
+                        if (evicted) {
+                            // The remove(K) or put(K, V) should be handled
+                            token.unlinkToDeath(mDeathRecipient, /* flags= */ 0);
+                            // TODO(b/278160706): handle app process and TCS's behavior if the
+                            //  session is removed by system server
+                        }
+                    }
+                };
 
         SessionCache(@NonNull Object lock) {
             mLock = Objects.requireNonNull(lock);
@@ -692,12 +715,10 @@
         void put(@NonNull TextClassificationSessionId sessionId,
                 @NonNull TextClassificationContext textClassificationContext) {
             synchronized (mLock) {
-                mCache.put(sessionId,
+                mCache.put(sessionId.getToken(),
                         new StrippedTextClassificationContext(textClassificationContext));
                 try {
-                    DeathRecipient deathRecipient = () -> remove(sessionId);
-                    sessionId.getToken().linkToDeath(deathRecipient, /* flags= */ 0);
-                    mDeathRecipients.put(sessionId, deathRecipient);
+                    sessionId.getToken().linkToDeath(mDeathRecipient, /* flags= */ 0);
                 } catch (RemoteException e) {
                     Slog.w(LOG_TAG, "SessionCache: Failed to link to death", e);
                 }
@@ -705,22 +726,29 @@
         }
 
         @Nullable
-        StrippedTextClassificationContext get(@NonNull TextClassificationSessionId sessionId) {
-            Objects.requireNonNull(sessionId);
+        StrippedTextClassificationContext get(@NonNull IBinder token) {
+            Objects.requireNonNull(token);
             synchronized (mLock) {
-                return mCache.get(sessionId);
+                return mCache.get(token);
             }
         }
 
-        void remove(@NonNull TextClassificationSessionId sessionId) {
-            Objects.requireNonNull(sessionId);
+        void remove(@NonNull IBinder token) {
+            Objects.requireNonNull(token);
             synchronized (mLock) {
-                DeathRecipient deathRecipient = mDeathRecipients.get(sessionId);
-                if (deathRecipient != null) {
-                    sessionId.getToken().unlinkToDeath(deathRecipient, /* flags= */ 0);
+                if (DEBUG) {
+                    Slog.d(LOG_TAG, "SessionCache: remove for " + token);
                 }
-                mDeathRecipients.remove(sessionId);
-                mCache.remove(sessionId);
+                if (token != null) {
+                    try {
+                        token.unlinkToDeath(mDeathRecipient, /* flags= */ 0);
+                    } catch (NoSuchElementException e) {
+                        if (DEBUG) {
+                            Slog.d(LOG_TAG, "SessionCache: " + token + " was already unlinked.");
+                        }
+                    }
+                }
+                mCache.remove(token);
             }
         }
 
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index 2d3928c..8f41608 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -2237,7 +2237,14 @@
         }
         clearAllResourcesAndClientMapping(getClientProfile(clientId));
         mClientProfiles.remove(clientId);
-        mListeners.remove(clientId);
+
+        // it may be called by unregisterClientProfileInternal under test
+        synchronized (mLock) {
+            ResourcesReclaimListenerRecord record = mListeners.remove(clientId);
+            if (record != null) {
+                record.getListener().asBinder().unlinkToDeath(record, 0);
+            }            
+        }
     }
 
     private void clearFrontendAndClientMapping(ClientProfile profile) {
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index a757d90..f71f3b1 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -397,9 +397,21 @@
 
         /** Returns {@code true} if the incoming activity can belong to this transition. */
         boolean canCoalesce(ActivityRecord r) {
-            return mLastLaunchedActivity.mDisplayContent == r.mDisplayContent
-                    && mLastLaunchedActivity.getTask().getBounds().equals(r.getTask().getBounds())
-                    && mLastLaunchedActivity.getWindowingMode() == r.getWindowingMode();
+            if (mLastLaunchedActivity.mDisplayContent != r.mDisplayContent
+                    || mLastLaunchedActivity.getWindowingMode() != r.getWindowingMode()) {
+                return false;
+            }
+            // The current task should be non-null because it is just launched. While the
+            // last task can be cleared when starting activity with FLAG_ACTIVITY_CLEAR_TASK.
+            final Task lastTask = mLastLaunchedActivity.getTask();
+            final Task currentTask = r.getTask();
+            if (lastTask != null && currentTask != null) {
+                if (lastTask == currentTask) {
+                    return true;
+                }
+                return lastTask.getBounds().equals(currentTask.getBounds());
+            }
+            return mLastLaunchedActivity.isUid(r.launchedFromUid);
         }
 
         /** @return {@code true} if the activity matches a launched activity in this transition. */
diff --git a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
index 5f56af7..1208b6ef 100644
--- a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
+++ b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
@@ -99,13 +99,15 @@
     }
 
     public void forEachConnection(Consumer<T> consumer) {
+        final ArraySet<T> connections;
         synchronized (mActivity) {
             if (mConnections == null || mConnections.isEmpty()) {
                 return;
             }
-            for (int i = mConnections.size() - 1; i >= 0; i--) {
-                consumer.accept(mConnections.valueAt(i));
-            }
+            connections = new ArraySet<>(mConnections);
+        }
+        for (int i = connections.size() - 1; i >= 0; i--) {
+            consumer.accept(connections.valueAt(i));
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index c5e75fa..a27f3e4 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2926,8 +2926,7 @@
         // 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;
+        final Task adjacentTargetTask = mTargetRootTask.getAdjacentTask();
         if (adjacentTargetTask != null && intentActivity.isDescendantOf(adjacentTargetTask)) {
             mTargetRootTask = adjacentTargetTask;
         }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index abf66bc..f93afe8 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2008,7 +2008,8 @@
             return;
         }
 
-        if (r.isState(RESUMED) && r == mRootWindowContainer.getTopResumedActivity()) {
+        if ((touchedActivity == null || r == touchedActivity) && r.isState(RESUMED)
+                && r == mRootWindowContainer.getTopResumedActivity()) {
             setLastResumedActivityUncheckLocked(r, "setFocusedTask-alreadyTop");
             return;
         }
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 597c8bf..805bff2 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -1030,12 +1030,11 @@
                     canPromote = false;
                 }
 
-                // If the current window container is task and it have adjacent task, it means
-                // both tasks will open or close app toghther but we want get their opening or
-                // closing animation target independently so do not promote.
+                // If the current window container is a task with adjacent task set, the both
+                // adjacent tasks will be opened or closed together. To get their opening or
+                // closing animation target independently, skip promoting their animation targets.
                 if (current.asTask() != null
-                        && current.asTask().getAdjacentTaskFragment() != null
-                        && current.asTask().getAdjacentTaskFragment().asTask() != null) {
+                        && current.asTask().getAdjacentTask() != null) {
                     canPromote = false;
                 }
 
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 11d84ff..0c196d7 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -227,6 +227,7 @@
                     backType = BackNavigationInfo.TYPE_CALLBACK;
                 }
                 infoBuilder.setOnBackInvokedCallback(callbackInfo.getCallback());
+                infoBuilder.setAnimationCallback(callbackInfo.isAnimationCallback());
                 mNavigationMonitor.startMonitor(window, navigationObserver);
             }
 
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c2bc459..bad64d3 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -656,6 +656,14 @@
      */
     private InputTarget mLastImeInputTarget;
 
+
+    /**
+     * Tracks the windowToken of the input method input target and the corresponding
+     * {@link WindowContainerListener} for monitoring changes (e.g. the requested visibility
+     * change).
+     */
+    private @Nullable Pair<IBinder, WindowContainerListener> mImeTargetTokenListenerPair;
+
     /**
      * This controls the visibility and animation of the input method window.
      */
@@ -4267,7 +4275,38 @@
 
     @VisibleForTesting
     void setImeInputTarget(InputTarget target) {
+        if (mImeTargetTokenListenerPair != null) {
+            // Unregister the listener before changing to the new IME input target.
+            final WindowToken oldToken = mTokenMap.get(mImeTargetTokenListenerPair.first);
+            if (oldToken != null) {
+                oldToken.unregisterWindowContainerListener(mImeTargetTokenListenerPair.second);
+            }
+            mImeTargetTokenListenerPair = null;
+        }
         mImeInputTarget = target;
+        // Notify listeners about IME input target window visibility by the target change.
+        if (target != null) {
+            // TODO(b/276743705): Let InputTarget register the visibility change of the hierarchy.
+            final WindowState targetWin = target.getWindowState();
+            if (targetWin != null) {
+                mImeTargetTokenListenerPair = new Pair<>(targetWin.mToken.token,
+                        new WindowContainerListener() {
+                            @Override
+                            public void onVisibleRequestedChanged(boolean isVisibleRequested) {
+                                // Notify listeners for IME input target window visibility change
+                                // requested by the parent container.
+                                mWmService.dispatchImeInputTargetVisibilityChanged(
+                                        targetWin.mClient.asBinder(), isVisibleRequested,
+                                        targetWin.mActivityRecord != null
+                                                && targetWin.mActivityRecord.finishing);
+                            }
+                        });
+                targetWin.mToken.registerWindowContainerListener(
+                        mImeTargetTokenListenerPair.second);
+                mWmService.dispatchImeInputTargetVisibilityChanged(targetWin.mClient.asBinder(),
+                        targetWin.isVisible() /* visible */, false /* removed */);
+            }
+        }
         if (refreshImeSecureFlag(getPendingTransaction())) {
             mWmService.requestTraversal();
         }
@@ -4433,6 +4472,10 @@
     }
 
     private void attachImeScreenshotOnTarget(WindowState imeTarget) {
+        attachImeScreenshotOnTarget(imeTarget, false);
+    }
+
+    private void attachImeScreenshotOnTarget(WindowState imeTarget, boolean hideImeWindow) {
         final SurfaceControl.Transaction t = getPendingTransaction();
         // Remove the obsoleted IME snapshot first in case the new snapshot happens to
         // override the current one before the transition finish and the surface never be
@@ -4441,6 +4484,11 @@
         mImeScreenshot = new ImeScreenshot(
                 mWmService.mSurfaceControlFactory.apply(null), imeTarget);
         mImeScreenshot.attachAndShow(t);
+        if (mInputMethodWindow != null && hideImeWindow) {
+            // Hide the IME window when deciding to show IME snapshot on demand.
+            // InsetsController will make IME visible again before animating it.
+            mInputMethodWindow.hide(false, false);
+        }
     }
 
     /**
@@ -4458,7 +4506,7 @@
      */
     @VisibleForTesting
     void showImeScreenshot(WindowState imeTarget) {
-        attachImeScreenshotOnTarget(imeTarget);
+        attachImeScreenshotOnTarget(imeTarget, true /* hideImeWindow */);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 339b6ec..747819e9 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.view.Display.TYPE_INTERNAL;
 import static android.view.InsetsFrameProvider.SOURCE_ARBITRARY_RECTANGLE;
 import static android.view.InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS;
@@ -2208,16 +2207,15 @@
 
     private int updateSystemBarsLw(WindowState win, int disableFlags) {
         final TaskDisplayArea defaultTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
-        final boolean multiWindowTaskVisible =
+        final boolean adjacentTasksVisible =
                 defaultTaskDisplayArea.getRootTask(task -> task.isVisible()
-                        && task.getTopLeafTask().getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW)
+                        && task.getTopLeafTask().getAdjacentTask() != null)
                         != null;
         final boolean freeformRootTaskVisible =
                 defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_FREEFORM);
 
-        // We need to force showing system bars when the multi-window or freeform root task is
-        // visible.
-        mForceShowSystemBars = multiWindowTaskVisible || freeformRootTaskVisible;
+        // We need to force showing system bars when adjacent tasks or freeform roots visible.
+        mForceShowSystemBars = adjacentTasksVisible || freeformRootTaskVisible;
         // We need to force the consumption of the system bars if they are force shown or if they
         // are controlled by a remote insets controller.
         mForceConsumeSystemBars = mForceShowSystemBars
@@ -2238,7 +2236,7 @@
 
         int appearance = APPEARANCE_OPAQUE_NAVIGATION_BARS | APPEARANCE_OPAQUE_STATUS_BARS;
         appearance = configureStatusBarOpacity(appearance);
-        appearance = configureNavBarOpacity(appearance, multiWindowTaskVisible,
+        appearance = configureNavBarOpacity(appearance, adjacentTasksVisible,
                 freeformRootTaskVisible);
 
         // Show immersive mode confirmation if needed.
diff --git a/services/core/java/com/android/server/wm/ImeTargetChangeListener.java b/services/core/java/com/android/server/wm/ImeTargetChangeListener.java
new file mode 100644
index 0000000..8bc445b
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ImeTargetChangeListener.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.annotation.NonNull;
+import android.os.IBinder;
+
+/**
+ * Callback the IME targeting window visibility change state for
+ * {@link com.android.server.inputmethod.InputMethodManagerService} to manage the IME surface
+ * visibility and z-ordering.
+ */
+public interface ImeTargetChangeListener {
+    /**
+     * Called when a non-IME-focusable overlay window being the IME layering target (e.g. a
+     * window with {@link android.view.WindowManager.LayoutParams#FLAG_NOT_FOCUSABLE} and
+     * {@link android.view.WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM} flags)
+     * has changed its window visibility.
+     *
+     * @param overlayWindowToken the window token of the overlay window.
+     * @param visible            the visibility of the overlay window, {@code true} means visible
+     *                           and {@code false} otherwise.
+     * @param removed            Whether the IME target overlay window has being removed.
+     */
+    default void onImeTargetOverlayVisibilityChanged(@NonNull IBinder overlayWindowToken,
+            boolean visible, boolean removed) {
+    }
+
+    /**
+     * Called when the visibility of IME input target window has changed.
+     *
+     * @param imeInputTarget   the window token of the IME input target window.
+     * @param visible          the new window visibility made by {@param imeInputTarget}. visible is
+     *                         {@code true} when switching to the new visible IME input target
+     *                         window and started input, or the same input target relayout to
+     *                         visible from invisible. In contrast, visible is {@code false} when
+     *                         closing the input target, or the same input target relayout to
+     *                         invisible from visible.
+     * @param removed          Whether the IME input target window has being removed.
+     */
+    default void onImeInputTargetVisibilityChanged(@NonNull IBinder imeInputTarget, boolean visible,
+            boolean removed) {
+    }
+}
diff --git a/services/core/java/com/android/server/wm/ImeTargetVisibilityPolicy.java b/services/core/java/com/android/server/wm/ImeTargetVisibilityPolicy.java
index 71dd917..1d9f24c 100644
--- a/services/core/java/com/android/server/wm/ImeTargetVisibilityPolicy.java
+++ b/services/core/java/com/android/server/wm/ImeTargetVisibilityPolicy.java
@@ -19,6 +19,7 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.IBinder;
 import android.view.WindowManager;
@@ -36,16 +37,15 @@
      * @param displayId A unique id to identify the display.
      * @return {@code true} if success, {@code false} otherwise.
      */
-    public abstract boolean showImeScreenShot(IBinder imeTarget, int displayId);
+    public abstract boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId);
 
     /**
-     * Updates the IME parent for target window.
+     * Removes the IME screenshot on the given display.
      *
-     * @param imeTarget The target window to update the IME parent.
-     * @param displayId A unique id to identify the display.
+     * @param displayId The target display of showing IME screenshot.
      * @return {@code true} if success, {@code false} otherwise.
      */
-    public abstract boolean updateImeParent(IBinder imeTarget, int displayId);
+    public abstract boolean removeImeScreenshot(int displayId);
 
     /**
      * Called when {@link DisplayContent#computeImeParent()} to check if it's valid to keep
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 9363eb5..5c33e64 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -2362,6 +2362,22 @@
         return parentTask == null ? null : parentTask.getCreatedByOrganizerTask();
     }
 
+    /** @return the first adjacent task of this task or its parent. */
+    @Nullable
+    Task getAdjacentTask() {
+        final TaskFragment adjacentTaskFragment = getAdjacentTaskFragment();
+        if (adjacentTaskFragment != null && adjacentTaskFragment.asTask() != null) {
+            return adjacentTaskFragment.asTask();
+        }
+
+        final WindowContainer parent = getParent();
+        if (parent == null || parent.asTask() == null) {
+            return null;
+        }
+
+        return parent.asTask().getAdjacentTask();
+    }
+
     // TODO(task-merge): Figure out what's the right thing to do for places that used it.
     boolean isRootTask() {
         return getRootTask() == this;
@@ -2747,7 +2763,7 @@
             Rect outSurfaceInsets) {
         // If this task has its adjacent task, it means they should animate together. Use display
         // bounds for them could move same as full screen task.
-        if (getAdjacentTaskFragment() != null && getAdjacentTaskFragment().asTask() != null) {
+        if (getAdjacentTask() != null) {
             super.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
             return;
         }
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index b0a879e..e80cbb3 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -1081,12 +1081,12 @@
             if (sourceTask != null && sourceTask == candidateTask) {
                 // Do nothing when task that is getting opened is same as the source.
             } else if (sourceTask != null
-                    && mLaunchAdjacentFlagRootTask.getAdjacentTaskFragment() != null
+                    && mLaunchAdjacentFlagRootTask.getAdjacentTask() != null
                     && (sourceTask == mLaunchAdjacentFlagRootTask
                     || sourceTask.isDescendantOf(mLaunchAdjacentFlagRootTask))) {
                 // If the adjacent launch is coming from the same root, launch to
                 // adjacent root instead.
-                return mLaunchAdjacentFlagRootTask.getAdjacentTaskFragment().asTask();
+                return mLaunchAdjacentFlagRootTask.getAdjacentTask();
             } else {
                 return mLaunchAdjacentFlagRootTask;
             }
@@ -1095,10 +1095,8 @@
         for (int i = mLaunchRootTasks.size() - 1; i >= 0; --i) {
             if (mLaunchRootTasks.get(i).contains(windowingMode, activityType)) {
                 final Task launchRootTask = mLaunchRootTasks.get(i).task;
-                final TaskFragment adjacentTaskFragment = launchRootTask != null
-                        ? launchRootTask.getAdjacentTaskFragment() : null;
-                final Task adjacentRootTask =
-                        adjacentTaskFragment != null ? adjacentTaskFragment.asTask() : null;
+                final Task adjacentRootTask = launchRootTask != null
+                        ? launchRootTask.getAdjacentTask() : null;
                 if (sourceTask != null && adjacentRootTask != null
                         && (sourceTask == adjacentRootTask
                         || sourceTask.isDescendantOf(adjacentRootTask))) {
@@ -1116,16 +1114,14 @@
                 // A pinned task relaunching should be handled by its task organizer. Skip fallback
                 // launch target of a pinned task from source task.
                 || candidateTask.getWindowingMode() != WINDOWING_MODE_PINNED)) {
-            Task launchTarget = sourceTask.getCreatedByOrganizerTask();
-            if (launchTarget != null && launchTarget.getAdjacentTaskFragment() != null) {
-                if (candidateTask != null) {
-                    final Task candidateRoot = candidateTask.getCreatedByOrganizerTask();
-                    if (candidateRoot != null && candidateRoot != launchTarget
-                            && launchTarget == candidateRoot.getAdjacentTaskFragment()) {
-                        launchTarget = candidateRoot;
-                    }
+            final Task adjacentTarget = sourceTask.getAdjacentTask();
+            if (adjacentTarget != null) {
+                if (candidateTask != null
+                        && (candidateTask == adjacentTarget
+                        || candidateTask.isDescendantOf(adjacentTarget))) {
+                    return adjacentTarget;
                 }
-                return launchTarget;
+                return sourceTask.getCreatedByOrganizerTask();
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 184293e..5626aa7 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -681,6 +681,7 @@
         final StartingWindowRemovalInfo removalInfo = new StartingWindowRemovalInfo();
         removalInfo.taskId = task.mTaskId;
         removalInfo.playRevealAnimation = prepareAnimation
+                && task.getDisplayContent() != null
                 && task.getDisplayInfo().state == Display.STATE_ON;
         final boolean playShiftUpAnimation = !task.inMultiWindowMode();
         final ActivityRecord topActivity = task.topActivityContainsStartingWindow();
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 969afe5..792ec2e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -444,6 +444,11 @@
     public abstract IBinder getFocusedWindowTokenFromWindowStates();
 
     /**
+     * Moves the given display to the top.
+     */
+    public abstract void moveDisplayToTopIfAllowed(int displayId);
+
+    /**
      * @return Whether the keyguard is engaged.
      */
     public abstract boolean isKeyguardLocked();
@@ -848,6 +853,16 @@
     }
 
     /**
+     * Sets by the {@link com.android.server.inputmethod.InputMethodManagerService} to monitor
+     * the visibility change of the IME targeted windows.
+     *
+     * @see ImeTargetChangeListener#onImeTargetOverlayVisibilityChanged
+     * @see ImeTargetChangeListener#onImeInputTargetVisibilityChanged
+     */
+    public abstract void setInputMethodTargetChangeListener(
+            @NonNull ImeTargetChangeListener listener);
+
+    /**
      * Moves the {@link WindowToken} {@code binder} to the display specified by {@code displayId}.
      */
     public abstract void moveWindowTokenToDisplay(IBinder binder, int displayId);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 99d0ea8..8822193 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -723,6 +723,9 @@
 
     boolean mHardKeyboardAvailable;
     WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
+
+    @Nullable ImeTargetChangeListener mImeTargetChangeListener;
+
     SettingsObserver mSettingsObserver;
     final EmbeddedWindowController mEmbeddedWindowController;
     final AnrController mAnrController;
@@ -1807,6 +1810,10 @@
 
             if (imMayMove) {
                 displayContent.computeImeTarget(true /* updateImeTarget */);
+                if (win.isImeOverlayLayeringTarget()) {
+                    dispatchImeTargetOverlayVisibilityChanged(client.asBinder(),
+                            win.isVisibleRequestedOrAdding(), false /* removed */);
+                }
             }
 
             // Don't do layout here, the window must call
@@ -2328,6 +2335,8 @@
                 winAnimator.mSurfaceController.setSecure(win.isSecureLocked());
             }
 
+            final boolean wasVisible = win.isVisible();
+
             win.mRelayoutCalled = true;
             win.mInRelayout = true;
 
@@ -2336,7 +2345,6 @@
                     "Relayout %s: oldVis=%d newVis=%d. %s", win, oldVisibility,
                             viewVisibility, new RuntimeException().fillInStackTrace());
 
-
             win.setDisplayLayoutNeeded();
             win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
 
@@ -2501,6 +2509,18 @@
             }
             win.mInRelayout = false;
 
+            final boolean winVisibleChanged = win.isVisible() != wasVisible;
+            if (win.isImeOverlayLayeringTarget() && winVisibleChanged) {
+                dispatchImeTargetOverlayVisibilityChanged(client.asBinder(),
+                        win.isVisible(), false /* removed */);
+            }
+            // Notify listeners about IME input target window visibility change.
+            final boolean isImeInputTarget = win.getDisplayContent().getImeInputTarget() == win;
+            if (isImeInputTarget && winVisibleChanged) {
+                dispatchImeInputTargetVisibilityChanged(win.mClient.asBinder(),
+                        win.isVisible() /* visible */, false /* removed */);
+            }
+
             if (outSyncIdBundle != null) {
                 final int maybeSyncSeqId;
                 if (USE_BLAST_SYNC && win.useBLASTSync() && viewVisibility == View.VISIBLE
@@ -3325,6 +3345,30 @@
         });
     }
 
+    void dispatchImeTargetOverlayVisibilityChanged(@NonNull IBinder token, boolean visible,
+            boolean removed) {
+        if (mImeTargetChangeListener != null) {
+            if (DEBUG_INPUT_METHOD) {
+                Slog.d(TAG, "onImeTargetOverlayVisibilityChanged, win=" + mWindowMap.get(token)
+                        + "visible=" + visible + ", removed=" + removed);
+            }
+            mH.post(() -> mImeTargetChangeListener.onImeTargetOverlayVisibilityChanged(token,
+                    visible, removed));
+        }
+    }
+
+    void dispatchImeInputTargetVisibilityChanged(@NonNull IBinder token, boolean visible,
+            boolean removed) {
+        if (mImeTargetChangeListener != null) {
+            if (DEBUG_INPUT_METHOD) {
+                Slog.d(TAG, "onImeInputTargetVisibilityChanged, win=" + mWindowMap.get(token)
+                        + "visible=" + visible + ", removed=" + removed);
+            }
+            mH.post(() -> mImeTargetChangeListener.onImeInputTargetVisibilityChanged(token,
+                    visible, removed));
+        }
+    }
+
     @Override
     public void setSwitchingUser(boolean switching) {
         if (!checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
@@ -7672,6 +7716,11 @@
         }
 
         @Override
+        public void moveDisplayToTopIfAllowed(int displayId) {
+            WindowManagerService.this.moveDisplayToTopIfAllowed(displayId);
+        }
+
+        @Override
         public boolean isKeyguardLocked() {
             return WindowManagerService.this.isKeyguardLocked();
         }
@@ -8262,13 +8311,19 @@
             }
             return null;
         }
+
+        @Override
+        public void setInputMethodTargetChangeListener(@NonNull ImeTargetChangeListener listener) {
+            synchronized (mGlobalLock) {
+                mImeTargetChangeListener = listener;
+            }
+        }
     }
 
     private final class ImeTargetVisibilityPolicyImpl extends ImeTargetVisibilityPolicy {
 
-        // TODO(b/258048231): Track IME visibility change in bugreport when invocations.
         @Override
-        public boolean showImeScreenShot(@NonNull IBinder imeTarget, int displayId) {
+        public boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId) {
             synchronized (mGlobalLock) {
                 final WindowState imeTargetWindow = mWindowMap.get(imeTarget);
                 if (imeTargetWindow == null) {
@@ -8284,24 +8339,18 @@
                 return true;
             }
         }
-
-        // TODO(b/258048231): Track IME visibility change in bugreport when invocations.
         @Override
-        public boolean updateImeParent(@NonNull IBinder imeTarget, int displayId) {
+        public boolean removeImeScreenshot(int displayId) {
             synchronized (mGlobalLock) {
-                final WindowState imeTargetWindow = mWindowMap.get(imeTarget);
-                if (imeTargetWindow == null) {
-                    return false;
-                }
                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
                 if (dc == null) {
-                    Slog.w(TAG, "Invalid displayId:" + displayId + ", fail to update ime parent");
+                    Slog.w(TAG, "Invalid displayId:" + displayId
+                            + ", fail to remove ime screenshot");
                     return false;
                 }
-
-                dc.updateImeParent();
-                return true;
+                dc.removeImeSurfaceImmediately();
             }
+            return true;
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 678d4c8..a299592 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -354,6 +354,7 @@
     // overlay window is hidden because the owning app is suspended
     private boolean mHiddenWhileSuspended;
     private boolean mAppOpVisibility = true;
+
     boolean mPermanentlyHidden; // the window should never be shown again
     // This is a non-system overlay window that is currently force hidden.
     private boolean mForceHideNonSystemOverlayWindow;
@@ -2350,6 +2351,10 @@
         }
         super.removeImmediately();
 
+        if (isImeOverlayLayeringTarget()) {
+            mWmService.dispatchImeTargetOverlayVisibilityChanged(mClient.asBinder(),
+                    false /* visible */, true /* removed */);
+        }
         final DisplayContent dc = getDisplayContent();
         if (isImeLayeringTarget()) {
             // Remove the attached IME screenshot surface.
@@ -2360,6 +2365,8 @@
             dc.computeImeTarget(true /* updateImeTarget */);
         }
         if (dc.getImeInputTarget() == this && !inRelaunchingActivity()) {
+            mWmService.dispatchImeInputTargetVisibilityChanged(mClient.asBinder(),
+                    false /* visible */, true /* removed */);
             dc.updateImeInputAndControlTarget(null);
         }
 
@@ -5499,6 +5506,14 @@
         return getDisplayContent().getImeTarget(IME_TARGET_LAYERING) == this;
     }
 
+    /**
+     * Whether the window is non-focusable IME overlay layering target.
+     */
+    boolean isImeOverlayLayeringTarget() {
+        return isImeLayeringTarget()
+                && (mAttrs.flags & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
+    }
+
     WindowState getImeLayeringTarget() {
         final InsetsControlTarget target = getDisplayContent().getImeTarget(IME_TARGET_LAYERING);
         return target != null ? target.getWindow() : null;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java
index ee73f8a..82f9aad 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java
@@ -17,50 +17,28 @@
 package com.android.server.devicepolicy;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.app.admin.BundlePolicyValue;
 import android.app.admin.PackagePolicyKey;
 import android.app.admin.PolicyKey;
 import android.os.Bundle;
-import android.os.Environment;
 import android.os.Parcelable;
-import android.util.AtomicFile;
-import android.util.Slog;
-import android.util.Xml;
+import android.util.Log;
 
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.XmlUtils;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 
-import libcore.io.IoUtils;
-
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Objects;
 
-// TODO(b/266704763): clean this up and stop creating separate files for each value, the code here
-//  is copied from UserManagerService, however it doesn't currently handle setting different
-//  restrictions for the same package in different users, it also will not remove the files for
-//  outdated restrictions, this will all get fixed when we save it as part of the policies file
-//  rather than in its own files.
 final class BundlePolicySerializer extends PolicySerializer<Bundle> {
 
     private static final String TAG = "BundlePolicySerializer";
 
-    private static final String ATTR_FILE_NAME = "file-name";
-
-    private static final String RESTRICTIONS_FILE_PREFIX = "AppRestrictions_";
-    private static final String XML_SUFFIX = ".xml";
-
-    private static final String TAG_RESTRICTIONS = "restrictions";
     private static final String TAG_ENTRY = "entry";
     private static final String TAG_VALUE = "value";
     private static final String ATTR_KEY = "key";
@@ -83,62 +61,26 @@
             throw new IllegalArgumentException("policyKey is not of type "
                     + "PackagePolicyKey");
         }
-        String packageName = ((PackagePolicyKey) policyKey).getPackageName();
-        String fileName = packageToRestrictionsFileName(packageName, value);
-        writeApplicationRestrictionsLAr(fileName, value);
-        serializer.attribute(/* namespace= */ null, ATTR_FILE_NAME, fileName);
+        writeBundle(value, serializer);
     }
 
-    @Nullable
     @Override
     BundlePolicyValue readFromXml(TypedXmlPullParser parser) {
-        String fileName = parser.getAttributeValue(/* namespace= */ null, ATTR_FILE_NAME);
-
-        return new BundlePolicyValue(readApplicationRestrictions(fileName));
-    }
-
-    private static String packageToRestrictionsFileName(String packageName, Bundle restrictions) {
-        return RESTRICTIONS_FILE_PREFIX + packageName + Objects.hash(restrictions) + XML_SUFFIX;
-    }
-
-    @GuardedBy("mAppRestrictionsLock")
-    private static Bundle readApplicationRestrictions(String fileName) {
-        AtomicFile restrictionsFile =
-                new AtomicFile(new File(Environment.getDataSystemDirectory(), fileName));
-        return readApplicationRestrictions(restrictionsFile);
-    }
-
-    @VisibleForTesting
-    @GuardedBy("mAppRestrictionsLock")
-    static Bundle readApplicationRestrictions(AtomicFile restrictionsFile) {
-        final Bundle restrictions = new Bundle();
-        final ArrayList<String> values = new ArrayList<>();
-        if (!restrictionsFile.getBaseFile().exists()) {
-            return restrictions;
-        }
-
-        FileInputStream fis = null;
+        Bundle bundle = new Bundle();
+        ArrayList<String> values = new ArrayList<>();
         try {
-            fis = restrictionsFile.openRead();
-            final TypedXmlPullParser parser = Xml.resolvePullParser(fis);
-            XmlUtils.nextElement(parser);
-            if (parser.getEventType() != XmlPullParser.START_TAG) {
-                Slog.e(TAG, "Unable to read restrictions file "
-                        + restrictionsFile.getBaseFile());
-                return restrictions;
+            final int outerDepth = parser.getDepth();
+            while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+                readBundle(bundle, values, parser);
             }
-            while (parser.next() != XmlPullParser.END_DOCUMENT) {
-                readEntry(restrictions, values, parser);
-            }
-        } catch (IOException | XmlPullParserException e) {
-            Slog.w(TAG, "Error parsing " + restrictionsFile.getBaseFile(), e);
-        } finally {
-            IoUtils.closeQuietly(fis);
+        } catch (XmlPullParserException | IOException e) {
+            Log.e(TAG, "Error parsing Bundle policy.", e);
+            return null;
         }
-        return restrictions;
+        return new BundlePolicyValue(bundle);
     }
 
-    private static void readEntry(Bundle restrictions, ArrayList<String> values,
+    private static void readBundle(Bundle restrictions, ArrayList<String> values,
             TypedXmlPullParser parser) throws XmlPullParserException, IOException {
         int type = parser.getEventType();
         if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) {
@@ -186,37 +128,11 @@
         Bundle childBundle = new Bundle();
         int outerDepth = parser.getDepth();
         while (XmlUtils.nextElementWithin(parser, outerDepth)) {
-            readEntry(childBundle, values, parser);
+            readBundle(childBundle, values, parser);
         }
         return childBundle;
     }
 
-    private static void writeApplicationRestrictionsLAr(String fileName, Bundle restrictions) {
-        AtomicFile restrictionsFile = new AtomicFile(
-                new File(Environment.getDataSystemDirectory(), fileName));
-        writeApplicationRestrictionsLAr(restrictions, restrictionsFile);
-    }
-
-    static void writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile) {
-        FileOutputStream fos = null;
-        try {
-            fos = restrictionsFile.startWrite();
-            final TypedXmlSerializer serializer = Xml.resolveSerializer(fos);
-            serializer.startDocument(null, true);
-            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-
-            serializer.startTag(null, TAG_RESTRICTIONS);
-            writeBundle(restrictions, serializer);
-            serializer.endTag(null, TAG_RESTRICTIONS);
-
-            serializer.endDocument();
-            restrictionsFile.finishWrite(fos);
-        } catch (Exception e) {
-            restrictionsFile.failWrite(fos);
-            Slog.e(TAG, "Error writing application restrictions list", e);
-        }
-    }
-
     private static void writeBundle(Bundle restrictions, TypedXmlSerializer serializer)
             throws IOException {
         for (String key : restrictions.keySet()) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 18fcafa..7e5d5aa 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11053,7 +11053,6 @@
         }
 
         if (!isPermissionCheckFlagEnabled() && !isPolicyEngineForFinanceFlagEnabled()) {
-            // TODO: Figure out if something like this needs to be restored for policy engine
             final ComponentName profileOwner = getProfileOwnerAsUser(userId);
             if (profileOwner == null) {
                 return false;
@@ -11640,7 +11639,7 @@
                         caller.getUserId());
             }
             setBackwardsCompatibleAppRestrictions(
-                    packageName, restrictions, caller.getUserHandle());
+                    caller, packageName, restrictions, caller.getUserHandle());
         } else {
             Preconditions.checkCallAuthorization((caller.hasAdminComponent()
                     && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
@@ -11661,17 +11660,28 @@
     }
 
     /**
-     * Set app restrictions in user manager to keep backwards compatibility for the old
-     * getApplicationRestrictions API.
+     * Set app restrictions in user manager for DPC callers only to keep backwards compatibility
+     * for the old getApplicationRestrictions API.
      */
     private void setBackwardsCompatibleAppRestrictions(
-            String packageName, Bundle restrictions, UserHandle userHandle) {
-        Bundle restrictionsToApply = restrictions == null || restrictions.isEmpty()
-                ? getAppRestrictionsSetByAnyAdmin(packageName, userHandle)
-                : restrictions;
-        mInjector.binderWithCleanCallingIdentity(() -> {
-            mUserManager.setApplicationRestrictions(packageName, restrictionsToApply, userHandle);
-        });
+            CallerIdentity caller, String packageName, Bundle restrictions, UserHandle userHandle) {
+        if ((caller.hasAdminComponent() && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
+                || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_APP_RESTRICTIONS))) {
+            Bundle restrictionsToApply = restrictions == null || restrictions.isEmpty()
+                    ? getAppRestrictionsSetByAnyAdmin(packageName, userHandle)
+                    : restrictions;
+            mInjector.binderWithCleanCallingIdentity(() -> {
+                mUserManager.setApplicationRestrictions(packageName, restrictionsToApply,
+                        userHandle);
+            });
+        } else {
+            // Notify package of changes via an intent - only sent to explicitly registered
+            // receivers. Sending here because For DPCs, this is being sent in UMS.
+            final Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
+            changeIntent.setPackage(packageName);
+            changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+            mContext.sendBroadcastAsUser(changeIntent, userHandle);
+        }
     }
 
     private Bundle getAppRestrictionsSetByAnyAdmin(String packageName, UserHandle userHandle) {
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
index 7d4f87d..a6ada4d 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
@@ -38,6 +38,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.view.Display;
 import android.view.inputmethod.InputMethodManager;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -144,6 +145,26 @@
         }
     }
 
+    @Test
+    public void testShowImeScreenshot() {
+        synchronized (ImfLock.class) {
+            mVisibilityApplier.showImeScreenshot(mWindowToken, Display.DEFAULT_DISPLAY,
+                    null /* statsToken */);
+        }
+
+        verify(mMockImeTargetVisibilityPolicy).showImeScreenshot(eq(mWindowToken),
+                eq(Display.DEFAULT_DISPLAY));
+    }
+
+    @Test
+    public void testRemoveImeScreenshot() {
+        synchronized (ImfLock.class) {
+            mVisibilityApplier.removeImeScreenshot(Display.DEFAULT_DISPLAY);
+        }
+
+        verify(mMockImeTargetVisibilityPolicy).removeImeScreenshot(eq(Display.DEFAULT_DISPLAY));
+    }
+
     private InputBindResult startInputOrWindowGainedFocus(IBinder windowToken, int softInputMode) {
         return mInputMethodManagerService.startInputOrWindowGainedFocus(
                 StartInputReason.WINDOW_FOCUS_GAIN /* startInputReason */,
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
index 2a256f2..3871e1d 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
@@ -24,7 +24,15 @@
 import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.internal.inputmethod.SoftInputShowHideReason.HIDE_WHEN_INPUT_TARGET_INVISIBLE;
+import static com.android.internal.inputmethod.SoftInputShowHideReason.REMOVE_IME_SCREENSHOT_FROM_IMMS;
+import static com.android.internal.inputmethod.SoftInputShowHideReason.SHOW_IME_SCREENSHOT_FROM_IMMS;
 import static com.android.server.inputmethod.ImeVisibilityStateComputer.ImeTargetWindowState;
+import static com.android.server.inputmethod.ImeVisibilityStateComputer.ImeVisibilityResult;
+import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_HIDE_IME_EXPLICIT;
+import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_REMOVE_IME_SNAPSHOT;
+import static com.android.server.inputmethod.ImeVisibilityStateComputer.STATE_SHOW_IME_SNAPSHOT;
 import static com.android.server.inputmethod.InputMethodManagerService.FALLBACK_DISPLAY_ID;
 import static com.android.server.inputmethod.InputMethodManagerService.ImeDisplayValidator;
 
@@ -37,11 +45,13 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.server.wm.ImeTargetChangeListener;
 import com.android.server.wm.WindowManagerInternal;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 
 /**
  * Test the behavior of {@link ImeVisibilityStateComputer} and {@link ImeVisibilityApplier} when
@@ -53,6 +63,7 @@
 @RunWith(AndroidJUnit4.class)
 public class ImeVisibilityStateComputerTest extends InputMethodManagerServiceTestBase {
     private ImeVisibilityStateComputer mComputer;
+    private ImeTargetChangeListener mListener;
     private int mImeDisplayPolicy = DISPLAY_IME_POLICY_LOCAL;
 
     @Before
@@ -69,7 +80,11 @@
                 return displayId -> mImeDisplayPolicy;
             }
         };
+        ArgumentCaptor<ImeTargetChangeListener> captor = ArgumentCaptor.forClass(
+                ImeTargetChangeListener.class);
+        verify(mMockWindowManagerInternal).setInputMethodTargetChangeListener(captor.capture());
         mComputer = new ImeVisibilityStateComputer(mInputMethodManagerService, injector);
+        mListener = captor.getValue();
     }
 
     @Test
@@ -196,6 +211,53 @@
                 lastState.isRequestedImeVisible());
     }
 
+    @Test
+    public void testOnInteractiveChanged() {
+        mComputer.getOrCreateWindowState(mWindowToken);
+        // Precondition: ensure IME has shown before hiding request.
+        mComputer.requestImeVisibility(mWindowToken, true);
+        mComputer.setInputShown(true);
+
+        // No need any visibility change When initially shows IME on the device was interactive.
+        ImeVisibilityStateComputer.ImeVisibilityResult result = mComputer.onInteractiveChanged(
+                mWindowToken, true /* interactive */);
+        assertThat(result).isNull();
+
+        // Show the IME screenshot to capture the last IME visible state when the device inactive.
+        result = mComputer.onInteractiveChanged(mWindowToken, false /* interactive */);
+        assertThat(result).isNotNull();
+        assertThat(result.getState()).isEqualTo(STATE_SHOW_IME_SNAPSHOT);
+        assertThat(result.getReason()).isEqualTo(SHOW_IME_SCREENSHOT_FROM_IMMS);
+
+        // Remove the IME screenshot when the device became interactive again.
+        result = mComputer.onInteractiveChanged(mWindowToken, true /* interactive */);
+        assertThat(result).isNotNull();
+        assertThat(result.getState()).isEqualTo(STATE_REMOVE_IME_SNAPSHOT);
+        assertThat(result.getReason()).isEqualTo(REMOVE_IME_SCREENSHOT_FROM_IMMS);
+    }
+
+    @Test
+    public void testOnApplyImeVisibilityFromComputer() {
+        final IBinder testImeTargetOverlay = new Binder();
+        final IBinder testImeInputTarget = new Binder();
+
+        // Simulate a test IME layering target overlay fully occluded the IME input target.
+        mListener.onImeTargetOverlayVisibilityChanged(testImeTargetOverlay, true, false);
+        mListener.onImeInputTargetVisibilityChanged(testImeInputTarget, false, false);
+        final ArgumentCaptor<IBinder> targetCaptor = ArgumentCaptor.forClass(IBinder.class);
+        final ArgumentCaptor<ImeVisibilityResult> resultCaptor = ArgumentCaptor.forClass(
+                ImeVisibilityResult.class);
+        verify(mInputMethodManagerService).onApplyImeVisibilityFromComputer(targetCaptor.capture(),
+                resultCaptor.capture());
+        final IBinder imeInputTarget = targetCaptor.getValue();
+        final ImeVisibilityResult result = resultCaptor.getValue();
+
+        // Verify the computer will callback hiding IME state to IMMS.
+        assertThat(imeInputTarget).isEqualTo(testImeInputTarget);
+        assertThat(result.getState()).isEqualTo(STATE_HIDE_IME_EXPLICIT);
+        assertThat(result.getReason()).isEqualTo(HIDE_WHEN_INPUT_TARGET_INVISIBLE);
+    }
+
     private ImeTargetWindowState initImeTargetWindowState(IBinder windowToken) {
         final ImeTargetWindowState state = new ImeTargetWindowState(SOFT_INPUT_STATE_UNCHANGED,
                 0, true, true, true);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
index 90691a7..c80ecbf 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
@@ -62,6 +62,7 @@
 import com.android.server.SystemService;
 import com.android.server.input.InputManagerInternal;
 import com.android.server.pm.UserManagerInternal;
+import com.android.server.wm.ImeTargetVisibilityPolicy;
 import com.android.server.wm.WindowManagerInternal;
 
 import org.junit.After;
@@ -113,6 +114,7 @@
     @Mock protected IInputMethod mMockInputMethod;
     @Mock protected IBinder mMockInputMethodBinder;
     @Mock protected IInputManager mMockIInputManager;
+    @Mock protected ImeTargetVisibilityPolicy mMockImeTargetVisibilityPolicy;
 
     protected Context mContext;
     protected MockitoSession mMockingSession;
@@ -166,6 +168,8 @@
                 .when(() -> LocalServices.getService(DisplayManagerInternal.class));
         doReturn(mMockUserManagerInternal)
                 .when(() -> LocalServices.getService(UserManagerInternal.class));
+        doReturn(mMockImeTargetVisibilityPolicy)
+                .when(() -> LocalServices.getService(ImeTargetVisibilityPolicy.class));
         doReturn(mMockIInputMethodManager)
                 .when(() -> ServiceManager.getServiceOrThrow(Context.INPUT_METHOD_SERVICE));
         doReturn(mMockIPlatformCompat)
@@ -218,6 +222,7 @@
                         false);
         mInputMethodManagerService = new InputMethodManagerService(mContext, mServiceThread,
                 mMockInputMethodBindingController);
+        spyOn(mInputMethodManagerService);
 
         // Start a InputMethodManagerService.Lifecycle to publish and manage the lifecycle of
         // InputMethodManagerService, which is closer to the real situation.
diff --git a/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/res/values/dimens.xml b/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/res/values/dimens.xml
index 1a4959e..5d91bd2 100644
--- a/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/res/values/dimens.xml
+++ b/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/res/values/dimens.xml
@@ -16,9 +16,9 @@
   -->
 
 <resources>
-    <dimen name="text_size_normal">24dp</dimen>
+    <dimen name="text_size_normal">20dp</dimen>
     <dimen name="text_size_symbol">14dp</dimen>
 
-    <dimen name="keyboard_header_height">40dp</dimen>
-    <dimen name="keyboard_row_height">50dp</dimen>
+    <dimen name="keyboard_header_height">30dp</dimen>
+    <dimen name="keyboard_row_height">40dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/HighBrightnessModeMetadataMapperTest.java b/services/tests/mockingservicestests/src/com/android/server/display/HighBrightnessModeMetadataMapperTest.java
new file mode 100644
index 0000000..d9fbba5
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/display/HighBrightnessModeMetadataMapperTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class HighBrightnessModeMetadataMapperTest {
+
+    private HighBrightnessModeMetadataMapper mHighBrightnessModeMetadataMapper;
+
+    @Before
+    public void setUp() {
+        mHighBrightnessModeMetadataMapper = new HighBrightnessModeMetadataMapper();
+    }
+
+    @Test
+    public void testGetHighBrightnessModeMetadata() {
+        // Display device is null
+        final LogicalDisplay display = mock(LogicalDisplay.class);
+        when(display.getPrimaryDisplayDeviceLocked()).thenReturn(null);
+        assertNull(mHighBrightnessModeMetadataMapper.getHighBrightnessModeMetadataLocked(display));
+
+        // No HBM metadata stored for this display yet
+        final DisplayDevice device = mock(DisplayDevice.class);
+        when(display.getPrimaryDisplayDeviceLocked()).thenReturn(device);
+        HighBrightnessModeMetadata hbmMetadata =
+                mHighBrightnessModeMetadataMapper.getHighBrightnessModeMetadataLocked(display);
+        assertTrue(hbmMetadata.getHbmEventQueue().isEmpty());
+        assertTrue(hbmMetadata.getRunningStartTimeMillis() < 0);
+
+        // Modify the metadata
+        long startTimeMillis = 100;
+        long endTimeMillis = 200;
+        long setTime = 300;
+        hbmMetadata.addHbmEvent(new HbmEvent(startTimeMillis, endTimeMillis));
+        hbmMetadata.setRunningStartTimeMillis(setTime);
+        hbmMetadata =
+                mHighBrightnessModeMetadataMapper.getHighBrightnessModeMetadataLocked(display);
+        assertEquals(1, hbmMetadata.getHbmEventQueue().size());
+        assertEquals(startTimeMillis,
+                hbmMetadata.getHbmEventQueue().getFirst().getStartTimeMillis());
+        assertEquals(endTimeMillis, hbmMetadata.getHbmEventQueue().getFirst().getEndTimeMillis());
+        assertEquals(setTime, hbmMetadata.getRunningStartTimeMillis());
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index 8f38f25..9cd22dd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -1132,7 +1132,7 @@
     @Test
     public void testRareJobBatching() {
         spyOn(mService);
-        doNothing().when(mService).evaluateControllerStatesLocked(any());
+        doReturn(false).when(mService).evaluateControllerStatesLocked(any());
         doNothing().when(mService).noteJobsPending(any());
         doReturn(true).when(mService).isReadyToBeExecutedLocked(any(), anyBoolean());
         advanceElapsedClock(24 * HOUR_IN_MILLIS);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
index d9461aa..b62dbcd 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
@@ -108,6 +108,7 @@
     @Mock private StatusBarManager mMockStatusBarManager;
     @Mock private ScreenshotHelper mMockScreenshotHelper;
     @Mock private SystemActionPerformer.SystemActionsChangedListener mMockListener;
+    @Mock private SystemActionPerformer.DisplayUpdateCallBack mMockCallback;
 
     @Before
     public void setup() {
@@ -125,7 +126,7 @@
                 mMockContext,
                 mMockWindowManagerInternal,
                 () -> mMockScreenshotHelper,
-                mMockListener);
+                mMockListener, mMockCallback);
     }
 
     private void setupWithRealContext() {
@@ -133,7 +134,7 @@
                 InstrumentationRegistry.getContext(),
                 mMockWindowManagerInternal,
                 () -> mMockScreenshotHelper,
-                mMockListener);
+                mMockListener, mMockCallback);
     }
 
     // We need below two help functions because AccessbilityAction.equals function only compares
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index aca96ad..aad373f 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -445,14 +445,14 @@
                         + "    <library \n"
                         + "        name=\"foo\"\n"
                         + "        file=\"" + mFooJar + "\"\n"
-                        + "        on-bootclasspath-before=\"Q\"\n"
+                        + "        on-bootclasspath-before=\"A\"\n"
                         + "        on-bootclasspath-since=\"W\"\n"
                         + "     />\n\n"
                         + " </permissions>";
         parseSharedLibraries(contents);
         assertFooIsOnlySharedLibrary();
         SystemConfig.SharedLibraryEntry entry = mSysConfig.getSharedLibraries().get("foo");
-        assertThat(entry.onBootclasspathBefore).isEqualTo("Q");
+        assertThat(entry.onBootclasspathBefore).isEqualTo("A");
         assertThat(entry.onBootclasspathSince).isEqualTo("W");
     }
 
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 90d1488..4406d83 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
@@ -71,10 +71,10 @@
 import android.testing.TestableContext;
 import android.util.ArraySet;
 import android.util.Pair;
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.modules.utils.TypedXmlSerializer;
 import android.util.Xml;
 
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
 import com.android.server.UiServiceTestCase;
 
 import com.google.common.collect.ImmutableList;
@@ -92,6 +92,7 @@
 import java.io.ByteArrayOutputStream;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
 
 public class NotificationListenersTest extends UiServiceTestCase {
 
@@ -626,6 +627,58 @@
                 .onNotificationChannelGroupModification(anyString(), any(), any(), anyInt());
     }
 
+    @Test
+    public void testNotificationListenerFilter_threadSafety() throws Exception {
+        testThreadSafety(() -> {
+            mListeners.setNotificationListenerFilter(
+                    new Pair<>(new ComponentName("pkg1", "cls1"), 0),
+                    new NotificationListenerFilter());
+            mListeners.setNotificationListenerFilter(
+                    new Pair<>(new ComponentName("pkg2", "cls2"), 10),
+                    new NotificationListenerFilter());
+            mListeners.setNotificationListenerFilter(
+                    new Pair<>(new ComponentName("pkg3", "cls3"), 11),
+                    new NotificationListenerFilter());
+
+            mListeners.onUserRemoved(10);
+            mListeners.onPackagesChanged(true, new String[]{"pkg1", "pkg2"}, new int[]{0, 0});
+        }, 20, 50);
+    }
+
+    /**
+     * Helper method to test the thread safety of some operations.
+     *
+     * <p>Runs the supplied {@code operationToTest}, {@code nRunsPerThread} times,
+     * concurrently using {@code nThreads} threads, and waits for all of them to finish.
+     */
+    private static void testThreadSafety(Runnable operationToTest, int nThreads,
+            int nRunsPerThread) throws InterruptedException {
+        final CountDownLatch startLatch = new CountDownLatch(1);
+        final CountDownLatch doneLatch = new CountDownLatch(nThreads);
+
+        for (int i = 0; i < nThreads; i++) {
+            Runnable threadRunnable = () -> {
+                try {
+                    startLatch.await();
+                    for (int j = 0; j < nRunsPerThread; j++) {
+                        operationToTest.run();
+                    }
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                } finally {
+                    doneLatch.countDown();
+                }
+            };
+            new Thread(threadRunnable, "Test Thread #" + i).start();
+        }
+
+        // Ready set go
+        startLatch.countDown();
+
+        // Wait for all test threads to be done.
+        doneLatch.await();
+    }
+
     private ManagedServices.ManagedServiceInfo getParcelingListener(
             final NotificationChannelGroup toParcel)
             throws RemoteException {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 9cfdaa7..dd9f3cb 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -5447,6 +5447,29 @@
     }
 
     @Test
+    public void testVisitUris_callStyle() {
+        Icon personIcon = Icon.createWithContentUri("content://media/person");
+        Icon verificationIcon = Icon.createWithContentUri("content://media/verification");
+        Person callingPerson = new Person.Builder().setName("Someone")
+                .setIcon(personIcon)
+                .build();
+        PendingIntent hangUpIntent = PendingIntent.getActivity(mContext, 0, new Intent(),
+                PendingIntent.FLAG_IMMUTABLE);
+        Notification n = new Notification.Builder(mContext, "a")
+                .setStyle(Notification.CallStyle.forOngoingCall(callingPerson, hangUpIntent)
+                        .setVerificationIcon(verificationIcon))
+                .setContentTitle("Calling...")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+
+        Consumer<Uri> visitor = (Consumer<Uri>) spy(Consumer.class);
+        n.visitUris(visitor);
+
+        verify(visitor, times(1)).accept(eq(personIcon.getUri()));
+        verify(visitor, times(1)).accept(eq(verificationIcon.getUri()));
+    }
+
+    @Test
     public void testVisitUris_audioContentsString() throws Exception {
         final Uri audioContents = Uri.parse("content://com.example/audio");
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 4e001fe..37c4b37 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -28,6 +28,7 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
@@ -501,6 +502,12 @@
         onActivityLaunched(mTrampolineActivity);
         mActivityMetricsLogger.notifyActivityLaunching(mTopActivity.intent,
                 mTrampolineActivity /* caller */, mTrampolineActivity.getUid());
+
+        // Simulate a corner case that the trampoline activity is removed by CLEAR_TASK.
+        // The 2 launch events can still be coalesced to one by matching the uid.
+        mTrampolineActivity.takeFromHistory();
+        assertNull(mTrampolineActivity.getTask());
+
         notifyActivityLaunched(START_SUCCESS, mTopActivity);
         transitToDrawnAndVerifyOnLaunchFinished(mTopActivity);
     }
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 8f2b470..0033e3e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2399,7 +2399,10 @@
         holder.addConnection(connection);
         assertTrue(holder.isActivityVisible());
         final int[] count = new int[1];
-        final Consumer<Object> c = conn -> count[0]++;
+        final Consumer<Object> c = conn -> {
+            count[0]++;
+            assertFalse(Thread.holdsLock(activity));
+        };
         holder.forEachConnection(c);
         assertEquals(1, count[0]);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index 17ae215..6d7f2c1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -232,11 +232,36 @@
 
         IOnBackInvokedCallback callback = createOnBackInvokedCallback();
         window.setOnBackInvokedCallbackInfo(
-                new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_DEFAULT));
+                new OnBackInvokedCallbackInfo(
+                        callback,
+                        OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+                        /* isAnimationCallback = */ false));
 
         BackNavigationInfo backNavigationInfo = startBackNavigation();
         assertWithMessage("BackNavigationInfo").that(backNavigationInfo).isNotNull();
         assertThat(backNavigationInfo.getType()).isEqualTo(BackNavigationInfo.TYPE_CALLBACK);
+        assertThat(backNavigationInfo.isAnimationCallback()).isEqualTo(false);
+        assertThat(backNavigationInfo.getOnBackInvokedCallback()).isEqualTo(callback);
+    }
+
+    @Test
+    public void backInfoWithAnimationCallback() {
+        WindowState window = createWindow(null, WindowManager.LayoutParams.TYPE_WALLPAPER,
+                "Wallpaper");
+        addToWindowMap(window, true);
+        makeWindowVisibleAndDrawn(window);
+
+        IOnBackInvokedCallback callback = createOnBackInvokedCallback();
+        window.setOnBackInvokedCallbackInfo(
+                new OnBackInvokedCallbackInfo(
+                        callback,
+                        OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+                        /* isAnimationCallback = */ true));
+
+        BackNavigationInfo backNavigationInfo = startBackNavigation();
+        assertWithMessage("BackNavigationInfo").that(backNavigationInfo).isNotNull();
+        assertThat(backNavigationInfo.getType()).isEqualTo(BackNavigationInfo.TYPE_CALLBACK);
+        assertThat(backNavigationInfo.isAnimationCallback()).isEqualTo(true);
         assertThat(backNavigationInfo.getOnBackInvokedCallback()).isEqualTo(callback);
     }
 
@@ -364,7 +389,10 @@
 
         IOnBackInvokedCallback callback = createOnBackInvokedCallback();
         window.setOnBackInvokedCallbackInfo(
-                new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_DEFAULT));
+                new OnBackInvokedCallbackInfo(
+                        callback,
+                        OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+                        /* isAnimationCallback = */ false));
 
         BackNavigationInfo backNavigationInfo = startBackNavigation();
         assertThat(backNavigationInfo).isNull();
@@ -450,14 +478,20 @@
     private IOnBackInvokedCallback withSystemCallback(Task task) {
         IOnBackInvokedCallback callback = createOnBackInvokedCallback();
         task.getTopMostActivity().getTopChild().setOnBackInvokedCallbackInfo(
-                new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_SYSTEM));
+                new OnBackInvokedCallbackInfo(
+                        callback,
+                        OnBackInvokedDispatcher.PRIORITY_SYSTEM,
+                        /* isAnimationCallback = */ false));
         return callback;
     }
 
     private IOnBackInvokedCallback withAppCallback(Task task) {
         IOnBackInvokedCallback callback = createOnBackInvokedCallback();
         task.getTopMostActivity().getTopChild().setOnBackInvokedCallbackInfo(
-                new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_DEFAULT));
+                new OnBackInvokedCallbackInfo(
+                        callback,
+                        OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+                        /* isAnimationCallback = */ false));
         return callback;
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index 2065540..a8fc25f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -84,12 +84,14 @@
     }
 
     @Test
-    public void testControlsForDispatch_multiWindowTaskVisible() {
+    public void testControlsForDispatch_adjacentTasksVisible() {
         addStatusBar();
         addNavigationBar();
 
-        final WindowState win = createWindow(null, WINDOWING_MODE_MULTI_WINDOW,
-                ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
+        final Task task1 = createTask(mDisplayContent);
+        final Task task2 = createTask(mDisplayContent);
+        task1.setAdjacentTaskFragment(task2);
+        final WindowState win = createAppWindow(task1, WINDOWING_MODE_MULTI_WINDOW, "app");
         final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win);
 
         // The app must not control any system bars.
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 49d8da1..9d597b1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -586,6 +586,15 @@
         // Making the activity0 be the focused activity and ensure the focused app is updated.
         activity0.moveFocusableActivityToTop("test");
         assertEquals(activity0, mDisplayContent.mFocusedApp);
+
+        // Moving activity1 to top and make both the two activities resumed.
+        activity1.moveFocusableActivityToTop("test");
+        activity0.setState(RESUMED, "test");
+        activity1.setState(RESUMED, "test");
+
+        // Verifies that the focus app can be updated to an Activity in the adjacent TF
+        mAtm.setFocusedTask(task.mTaskId, activity0);
+        assertEquals(activity0, mDisplayContent.mFocusedApp);
     }
 
     @Test
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 766e74c..460a603 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -20,6 +20,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.InsetsSource.ID_IME;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_270;
@@ -85,17 +86,25 @@
 import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.InputConfig;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.util.ArraySet;
+import android.util.MergedConfiguration;
 import android.view.Gravity;
+import android.view.IWindow;
+import android.view.IWindowSessionCallback;
 import android.view.InputWindowHandle;
 import android.view.InsetsSource;
+import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 import android.view.SurfaceControl;
+import android.view.View;
+import android.view.WindowInsets;
 import android.view.WindowManager;
+import android.window.ClientWindowFrames;
 import android.window.ITaskFragmentOrganizer;
 import android.window.TaskFragmentOrganizer;
 
@@ -1280,4 +1289,118 @@
         assertEquals(new ArraySet(Arrays.asList(expectedArea1, expectedArea2)),
                      new ArraySet(unrestrictedKeepClearAreas));
     }
+
+    @Test
+    public void testImeTargetChangeListener_OnImeInputTargetVisibilityChanged() {
+        final TestImeTargetChangeListener listener = new TestImeTargetChangeListener();
+        mWm.mImeTargetChangeListener = listener;
+
+        final WindowState imeTarget = createWindow(null /* parent */, TYPE_BASE_APPLICATION,
+                createActivityRecord(mDisplayContent), "imeTarget");
+
+        imeTarget.mActivityRecord.setVisibleRequested(true);
+        makeWindowVisible(imeTarget);
+        mDisplayContent.setImeInputTarget(imeTarget);
+        waitHandlerIdle(mWm.mH);
+
+        assertThat(listener.mImeTargetToken).isEqualTo(imeTarget.mClient.asBinder());
+        assertThat(listener.mIsRemoved).isFalse();
+        assertThat(listener.mIsVisibleForImeInputTarget).isTrue();
+
+        imeTarget.mActivityRecord.setVisibleRequested(false);
+        waitHandlerIdle(mWm.mH);
+
+        assertThat(listener.mImeTargetToken).isEqualTo(imeTarget.mClient.asBinder());
+        assertThat(listener.mIsRemoved).isFalse();
+        assertThat(listener.mIsVisibleForImeInputTarget).isFalse();
+
+        imeTarget.removeImmediately();
+        assertThat(listener.mImeTargetToken).isEqualTo(imeTarget.mClient.asBinder());
+        assertThat(listener.mIsRemoved).isTrue();
+        assertThat(listener.mIsVisibleForImeInputTarget).isFalse();
+    }
+
+    @SetupWindows(addWindows = {W_INPUT_METHOD})
+    @Test
+    public void testImeTargetChangeListener_OnImeTargetOverlayVisibilityChanged() {
+        final TestImeTargetChangeListener listener = new TestImeTargetChangeListener();
+        mWm.mImeTargetChangeListener = listener;
+
+        // Scenario 1: test addWindow/relayoutWindow to add Ime layering overlay window as visible.
+        final WindowToken windowToken = createTestWindowToken(TYPE_APPLICATION_OVERLAY,
+                mDisplayContent);
+        final IWindow client = new TestIWindow();
+        final Session session = new Session(mWm, new IWindowSessionCallback.Stub() {
+            @Override
+            public void onAnimatorScaleChanged(float v) throws RemoteException {
+
+            }
+        });
+        final ClientWindowFrames outFrames = new ClientWindowFrames();
+        final MergedConfiguration outConfig = new MergedConfiguration();
+        final SurfaceControl outSurfaceControl = new SurfaceControl();
+        final InsetsState outInsetsState = new InsetsState();
+        final InsetsSourceControl.Array outControls = new InsetsSourceControl.Array();
+        final Bundle outBundle = new Bundle();
+        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+                TYPE_APPLICATION_OVERLAY);
+        params.setTitle("imeLayeringTargetOverlay");
+        params.token = windowToken.token;
+        params.flags = FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM;
+
+        mWm.addWindow(session, client, params, View.VISIBLE, DEFAULT_DISPLAY,
+                0 /* userUd */, WindowInsets.Type.defaultVisible(), null, new InsetsState(),
+                new InsetsSourceControl.Array(), new Rect(), new float[1]);
+        mWm.relayoutWindow(session, client, params, 100, 200, View.VISIBLE, 0, 0, 0,
+                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
+        waitHandlerIdle(mWm.mH);
+
+        final WindowState imeLayeringTargetOverlay = mDisplayContent.getWindow(
+                w -> w.mClient.asBinder() == client.asBinder());
+        assertThat(imeLayeringTargetOverlay.isVisible()).isTrue();
+        assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
+        assertThat(listener.mIsRemoved).isFalse();
+        assertThat(listener.mIsVisibleForImeTargetOverlay).isTrue();
+
+        // Scenario 2: test relayoutWindow to let the Ime layering target overlay window invisible.
+        mWm.relayoutWindow(session, client, params, 100, 200, View.GONE, 0, 0, 0,
+                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
+        waitHandlerIdle(mWm.mH);
+
+        assertThat(imeLayeringTargetOverlay.isVisible()).isFalse();
+        assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
+        assertThat(listener.mIsRemoved).isFalse();
+        assertThat(listener.mIsVisibleForImeTargetOverlay).isFalse();
+
+        // Scenario 3: test removeWindow to remove the Ime layering target overlay window.
+        mWm.removeWindow(session, client);
+        waitHandlerIdle(mWm.mH);
+
+        assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
+        assertThat(listener.mIsRemoved).isTrue();
+        assertThat(listener.mIsVisibleForImeTargetOverlay).isFalse();
+    }
+
+    private static class TestImeTargetChangeListener implements ImeTargetChangeListener {
+        private IBinder mImeTargetToken;
+        private boolean mIsRemoved;
+        private boolean mIsVisibleForImeTargetOverlay;
+        private boolean mIsVisibleForImeInputTarget;
+
+        @Override
+        public void onImeTargetOverlayVisibilityChanged(IBinder overlayWindowToken, boolean visible,
+                boolean removed) {
+            mImeTargetToken = overlayWindowToken;
+            mIsVisibleForImeTargetOverlay = visible;
+            mIsRemoved = removed;
+        }
+
+        @Override
+        public void onImeInputTargetVisibilityChanged(IBinder imeInputTarget,
+                boolean visibleRequested, boolean removed) {
+            mImeTargetToken = imeInputTarget;
+            mIsVisibleForImeInputTarget = visibleRequested;
+            mIsRemoved = removed;
+        }
+    }
 }
diff --git a/tests/ActivityManagerPerfTests/utils/Android.bp b/tests/ActivityManagerPerfTests/utils/Android.bp
index 99c43c8..5902c1c 100644
--- a/tests/ActivityManagerPerfTests/utils/Android.bp
+++ b/tests/ActivityManagerPerfTests/utils/Android.bp
@@ -32,6 +32,6 @@
     static_libs: [
         "androidx.test.rules",
         "junit",
-        "ub-uiautomator",
+        "androidx.test.uiautomator_uiautomator",
     ],
 }
diff --git a/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java b/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java
index fc787ba..9bd94f2 100644
--- a/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java
+++ b/tests/ActivityManagerPerfTests/utils/src/com/android/frameworks/perftests/am/util/Utils.java
@@ -19,10 +19,10 @@
 import android.content.Intent;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
-import android.support.test.uiautomator.UiDevice;
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.uiautomator.UiDevice;
 
 import java.io.IOException;
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt
index 18e49fe..ae9ca80 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt
@@ -102,7 +102,7 @@
 
     @Postsubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()
 
-    @Postsubmit
+    @Ignore("Not applicable to this CUJ. App is full screen at the end")
     @Test
     override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
 
@@ -127,11 +127,11 @@
     @Test
     override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
 
-    @Postsubmit
+    @Ignore("Not applicable to this CUJ. App is full screen at the end")
     @Test
     override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
 
-    @Postsubmit
+    @Ignore("Not applicable to this CUJ. App is full screen at the end")
     @Test
     override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
 
@@ -145,7 +145,7 @@
     override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
         super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 
-    @Postsubmit
+    @Ignore("Not applicable to this CUJ. App is full screen at the end")
     @Test
     override fun navBarWindowIsVisibleAtStartAndEnd() {
         super.navBarWindowIsVisibleAtStartAndEnd()
diff --git a/tests/InputMethodStressTest/Android.bp b/tests/InputMethodStressTest/Android.bp
index 0ad3876..27640a5 100644
--- a/tests/InputMethodStressTest/Android.bp
+++ b/tests/InputMethodStressTest/Android.bp
@@ -32,5 +32,8 @@
         "general-tests",
         "vts",
     ],
-    sdk_version: "31",
+    data: [
+        ":SimpleTestIme",
+    ],
+    sdk_version: "current",
 }
diff --git a/tests/InputMethodStressTest/AndroidManifest.xml b/tests/InputMethodStressTest/AndroidManifest.xml
index 2d183bc..62eee02 100644
--- a/tests/InputMethodStressTest/AndroidManifest.xml
+++ b/tests/InputMethodStressTest/AndroidManifest.xml
@@ -17,7 +17,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.inputmethod.stresstest">
-
+    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
     <application>
         <activity android:name=".ImeStressTestUtil$TestActivity"
                   android:configChanges="orientation|screenSize"/>
diff --git a/tests/InputMethodStressTest/AndroidTest.xml b/tests/InputMethodStressTest/AndroidTest.xml
index 9ac4135..bedf099 100644
--- a/tests/InputMethodStressTest/AndroidTest.xml
+++ b/tests/InputMethodStressTest/AndroidTest.xml
@@ -25,6 +25,7 @@
 
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="SimpleTestIme.apk" />
         <option name="test-file-name" value="InputMethodStressTest.apk" />
     </target_preparer>
 
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
index 9c70e6e..3d257b2 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
@@ -61,14 +61,10 @@
 @RunWith(Parameterized.class)
 public final class AutoShowTest {
 
-    @Rule(order = 0) public DisableLockScreenRule mDisableLockScreenRule =
-            new DisableLockScreenRule();
-    @Rule(order = 1) public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
-    @Rule(order = 2) public ScreenOrientationRule mScreenOrientationRule =
-            new ScreenOrientationRule(true /* isPortrait */);
-    @Rule(order = 3) public PressHomeBeforeTestRule mPressHomeBeforeTestRule =
-            new PressHomeBeforeTestRule();
-    @Rule(order = 4) public ScreenCaptureRule mScreenCaptureRule =
+    @Rule(order = 0) public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
+    @Rule(order = 1) public ImeStressTestRule mImeStressTestRule =
+        new ImeStressTestRule(true /* useSimpleTestIme */);
+    @Rule(order = 2) public ScreenCaptureRule mScreenCaptureRule =
             new ScreenCaptureRule("/sdcard/InputMethodStressTest");
     @Parameterized.Parameters(
             name = "windowFocusFlags={0}, softInputVisibility={1}, softInputAdjustment={2}")
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/DisableLockScreenRule.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/DisableLockScreenRule.java
deleted file mode 100644
index d95decf..0000000
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/DisableLockScreenRule.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.stresstest;
-
-import android.support.test.uiautomator.UiDevice;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-
-import java.io.IOException;
-
-/** Disable lock screen during the test. */
-public class DisableLockScreenRule extends TestWatcher {
-    private static final String LOCK_SCREEN_OFF_COMMAND = "locksettings set-disabled true";
-    private static final String LOCK_SCREEN_ON_COMMAND = "locksettings set-disabled false";
-
-    private final UiDevice mUiDevice =
-            UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-    @Override
-    protected void starting(Description description) {
-        try {
-            mUiDevice.executeShellCommand(LOCK_SCREEN_OFF_COMMAND);
-        } catch (IOException e) {
-            throw new RuntimeException("Could not disable lock screen.", e);
-        }
-    }
-
-    @Override
-    protected void finished(Description description) {
-        try {
-            mUiDevice.executeShellCommand(LOCK_SCREEN_ON_COMMAND);
-        } catch (IOException e) {
-            throw new RuntimeException("Could not enable lock screen.", e);
-        }
-    }
-}
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
index 9d4aefb..7632ab0 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
@@ -68,14 +68,10 @@
     private static final String TAG = "ImeOpenCloseStressTest";
     private static final int NUM_TEST_ITERATIONS = 10;
 
-    @Rule(order = 0) public DisableLockScreenRule mDisableLockScreenRule =
-            new DisableLockScreenRule();
-    @Rule(order = 1) public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
-    @Rule(order = 2) public ScreenOrientationRule mScreenOrientationRule =
-            new ScreenOrientationRule(true /* isPortrait */);
-    @Rule(order = 3) public PressHomeBeforeTestRule mPressHomeBeforeTestRule =
-            new PressHomeBeforeTestRule();
-    @Rule(order = 4) public ScreenCaptureRule mScreenCaptureRule =
+    @Rule(order = 0) public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
+    @Rule(order = 1) public ImeStressTestRule mImeStressTestRule =
+            new ImeStressTestRule(true /* useSimpleTestIme */);
+    @Rule(order = 2) public ScreenCaptureRule mScreenCaptureRule =
             new ScreenCaptureRule("/sdcard/InputMethodStressTest");
 
     private final Instrumentation mInstrumentation;
@@ -499,8 +495,6 @@
 
     @Test
     public void testRotateScreenWithKeyboardOn() throws Exception {
-        // TODO(b/256739702): Keyboard disappears after rotating screen to landscape mode if
-        // android:configChanges="orientation|screenSize" is not set
         Intent intent =
                 createIntent(
                         mWindowFocusFlags,
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestRule.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestRule.java
new file mode 100644
index 0000000..12104b2
--- /dev/null
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestRule.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.stresstest;
+
+import android.app.Instrumentation;
+import android.os.RemoteException;
+import android.support.test.uiautomator.UiDevice;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+import java.io.IOException;
+
+/**
+ * Do setup and cleanup for Ime stress tests, including disabling lock and auto-rotate screen,
+ * pressing home and enabling a simple test Ime during the tests.
+ */
+public class ImeStressTestRule extends TestWatcher {
+    private static final String LOCK_SCREEN_OFF_COMMAND = "locksettings set-disabled true";
+    private static final String LOCK_SCREEN_ON_COMMAND = "locksettings set-disabled false";
+    private static final String SET_PORTRAIT_MODE_COMMAND = "settings put system user_rotation 0";
+    private static final String SET_LANDSCAPE_MODE_COMMAND = "settings put system user_rotation 1";
+    private static final String SIMPLE_IME_ID =
+            "com.android.apps.inputmethod.simpleime/.SimpleInputMethodService";
+    private static final String ENABLE_IME_COMMAND = "ime enable " + SIMPLE_IME_ID;
+    private static final String SET_IME_COMMAND = "ime set " + SIMPLE_IME_ID;
+    private static final String DISABLE_IME_COMMAND = "ime disable " + SIMPLE_IME_ID;
+    private static final String RESET_IME_COMMAND = "ime reset";
+
+    @NonNull private final Instrumentation mInstrumentation;
+    @NonNull private final UiDevice mUiDevice;
+    // Whether the screen orientation is set to portrait.
+    private boolean mIsPortrait;
+    // Whether to use a simple test Ime or system default Ime for test.
+    private final boolean mUseSimpleTestIme;
+
+    public ImeStressTestRule(boolean useSimpleTestIme) {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mUiDevice = UiDevice.getInstance(mInstrumentation);
+        // Default is portrait mode
+        mIsPortrait = true;
+        mUseSimpleTestIme = useSimpleTestIme;
+    }
+
+    public void setIsPortrait(boolean isPortrait) {
+        mIsPortrait = isPortrait;
+    }
+
+    @Override
+    protected void starting(Description description) {
+        disableLockScreen();
+        setOrientation();
+        mUiDevice.pressHome();
+        if (mUseSimpleTestIme) {
+            enableSimpleIme();
+        } else {
+            resetImeToDefault();
+        }
+
+        mInstrumentation.waitForIdleSync();
+    }
+
+    @Override
+    protected void finished(Description description) {
+        if (mUseSimpleTestIme) {
+            disableSimpleIme();
+        }
+        unfreezeRotation();
+        restoreLockScreen();
+    }
+
+    private void disableLockScreen() {
+        try {
+            executeShellCommand(LOCK_SCREEN_OFF_COMMAND);
+        } catch (IOException e) {
+            throw new RuntimeException("Could not disable lock screen.", e);
+        }
+    }
+
+    private void restoreLockScreen() {
+        try {
+            executeShellCommand(LOCK_SCREEN_ON_COMMAND);
+        } catch (IOException e) {
+            throw new RuntimeException("Could not enable lock screen.", e);
+        }
+    }
+
+    private void setOrientation() {
+        try {
+            mUiDevice.freezeRotation();
+            executeShellCommand(
+                    mIsPortrait ? SET_PORTRAIT_MODE_COMMAND : SET_LANDSCAPE_MODE_COMMAND);
+        } catch (IOException e) {
+            throw new RuntimeException("Could not set screen orientation.", e);
+        } catch (RemoteException e) {
+            throw new RuntimeException("Could not freeze rotation.", e);
+        }
+    }
+
+    private void unfreezeRotation() {
+        try {
+            mUiDevice.unfreezeRotation();
+        } catch (RemoteException e) {
+            throw new RuntimeException("Could not unfreeze screen rotation.", e);
+        }
+    }
+
+    private void enableSimpleIme() {
+        try {
+            executeShellCommand(ENABLE_IME_COMMAND);
+            executeShellCommand(SET_IME_COMMAND);
+        } catch (IOException e) {
+            throw new RuntimeException("Could not enable SimpleTestIme.", e);
+        }
+    }
+
+    private void disableSimpleIme() {
+        try {
+            executeShellCommand(DISABLE_IME_COMMAND);
+        } catch (IOException e) {
+            throw new RuntimeException("Could not disable SimpleTestIme.", e);
+        }
+    }
+
+    private void resetImeToDefault() {
+        try {
+            executeShellCommand(RESET_IME_COMMAND);
+        } catch (IOException e) {
+            throw new RuntimeException("Could not reset Ime to default.", e);
+        }
+    }
+
+    private @NonNull String executeShellCommand(@NonNull String cmd) throws IOException {
+        return mUiDevice.executeShellCommand(cmd);
+    }
+}
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
index d2708ad..f4a04a1 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/NotificationTest.java
@@ -77,11 +77,10 @@
     private static final BySelector REPLY_SEND_BUTTON_SELECTOR =
             By.res("com.android.systemui", "remote_input_send").enabled(true);
 
-    @Rule
-    public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
-
-    @Rule
-    public ScreenCaptureRule mScreenCaptureRule =
+    @Rule(order = 0) public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
+    @Rule(order = 1) public ImeStressTestRule mImeStressTestRule =
+            new ImeStressTestRule(true /* useSimpleTestIme */);
+    @Rule(order = 2) public ScreenCaptureRule mScreenCaptureRule =
             new ScreenCaptureRule("/sdcard/InputMethodStressTest");
 
     private Context mContext;
@@ -141,7 +140,8 @@
 
         // Post inline reply notification.
         PendingIntent pendingIntent = PendingIntent.getBroadcast(
-                mContext, REPLY_REQUEST_CODE, new Intent().setAction(ACTION_REPLY),
+                mContext, REPLY_REQUEST_CODE,
+                new Intent().setAction(ACTION_REPLY).setClass(mContext, NotificationTest.class),
                 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
         RemoteInput remoteInput = new RemoteInput.Builder(REPLY_INPUT_KEY)
                 .setLabel(REPLY_INPUT_LABEL)
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/PressHomeBeforeTestRule.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/PressHomeBeforeTestRule.java
deleted file mode 100644
index 6586f63..0000000
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/PressHomeBeforeTestRule.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.inputmethod.stresstest;
-
-import android.support.test.uiautomator.UiDevice;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-
-/** This rule will press home before a test case. */
-public class PressHomeBeforeTestRule extends TestWatcher {
-    private final UiDevice mUiDevice =
-            UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-    @Override
-    protected void starting(Description description) {
-        mUiDevice.pressHome();
-    }
-}
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ScreenOrientationRule.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ScreenOrientationRule.java
deleted file mode 100644
index bc3b1ef..0000000
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ScreenOrientationRule.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.stresstest;
-
-import android.os.RemoteException;
-import android.support.test.uiautomator.UiDevice;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-
-import java.io.IOException;
-
-/**
- * Disable auto-rotate during the test and set the screen orientation to portrait or landscape
- * before the test starts.
- */
-public class ScreenOrientationRule extends TestWatcher {
-    private static final String SET_PORTRAIT_MODE_CMD = "settings put system user_rotation 0";
-    private static final String SET_LANDSCAPE_MODE_CMD = "settings put system user_rotation 1";
-
-    private final boolean mIsPortrait;
-    private final UiDevice mUiDevice =
-            UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-    ScreenOrientationRule(boolean isPortrait) {
-        mIsPortrait = isPortrait;
-    }
-
-    @Override
-    protected void starting(Description description) {
-        try {
-            mUiDevice.freezeRotation();
-            mUiDevice.executeShellCommand(mIsPortrait ? SET_PORTRAIT_MODE_CMD :
-                    SET_LANDSCAPE_MODE_CMD);
-        } catch (IOException e) {
-            throw new RuntimeException("Could not set screen orientation.", e);
-        } catch (RemoteException e) {
-            throw new RuntimeException("Could not freeze rotation.", e);
-        }
-    }
-
-    @Override
-    protected void finished(Description description) {
-        try {
-            mUiDevice.unfreezeRotation();
-        } catch (RemoteException e) {
-            throw new RuntimeException("Could not unfreeze screen rotation.", e);
-        }
-    }
-}
diff --git a/tools/validatekeymaps/Android.bp b/tools/validatekeymaps/Android.bp
index 25373f9..554f64e 100644
--- a/tools/validatekeymaps/Android.bp
+++ b/tools/validatekeymaps/Android.bp
@@ -15,7 +15,7 @@
 
 cc_binary_host {
     name: "validatekeymaps",
-
+    cpp_std: "c++20",
     srcs: ["Main.cpp"],
 
     cflags: [