Merge "Fix race condition using notification pipeline" into main
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 5adcd93..7eb9d0f 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -1335,7 +1335,8 @@
                 if (path.string() == animation.parts[j].path.c_str()) {
                     uint16_t method;
                     // supports only stored png files
-                    if (zip->getEntryInfo(entry, &method, nullptr, nullptr, nullptr, nullptr, nullptr)) {
+                    if (zip->getEntryInfo(entry, &method, nullptr, nullptr, nullptr, nullptr,
+                            nullptr, nullptr)) {
                         if (method == ZipFileRO::kCompressStored) {
                             FileMap* map = zip->createEntryFileMap(entry);
                             if (map) {
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 8e99e46b..9785252 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -1101,19 +1101,9 @@
     public abstract ArraySet<String> getClientPackages(String servicePackageName);
 
     /**
-     * Retrieve an IUnsafeIntentStrictModeCallback matching the given callingUid.
-     * Returns null no match is found.
-     * @param callingPid The PID mapped with the callback.
-     * @return The callback, if it exists.
+     * Trigger an unsafe intent usage strict mode violation.
      */
-    public abstract IUnsafeIntentStrictModeCallback getRegisteredStrictModeCallback(
-            int callingPid);
-
-    /**
-     * Unregisters an IUnsafeIntentStrictModeCallback matching the given callingUid.
-     * @param callingPid The PID mapped with the callback.
-     */
-    public abstract void unregisterStrictModeCallback(int callingPid);
+    public abstract void triggerUnsafeIntentStrictMode(int callingPid, int type, Intent intent);
 
     /**
      * Start a foreground service delegate.
diff --git a/core/java/android/app/IUnsafeIntentStrictModeCallback.aidl b/core/java/android/app/IUnsafeIntentStrictModeCallback.aidl
index e2b3bb1..69e99a3 100644
--- a/core/java/android/app/IUnsafeIntentStrictModeCallback.aidl
+++ b/core/java/android/app/IUnsafeIntentStrictModeCallback.aidl
@@ -24,5 +24,5 @@
  */
 oneway interface IUnsafeIntentStrictModeCallback
 {
-    void onImplicitIntentMatchedInternalComponent(in Intent intent);
+    void onUnsafeIntent(int type, in Intent intent);
 }
diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java
index 48081bb..9a04ded 100644
--- a/core/java/android/app/servertransaction/ClientTransaction.java
+++ b/core/java/android/app/servertransaction/ClientTransaction.java
@@ -249,6 +249,9 @@
 
     @Override
     public void recycle() {
+        if (Flags.disableObjectPool()) {
+            return;
+        }
         if (mTransactionItems != null) {
             int size = mTransactionItems.size();
             for (int i = 0; i < size; i++) {
diff --git a/core/java/android/app/servertransaction/ObjectPool.java b/core/java/android/app/servertransaction/ObjectPool.java
index 2fec30a..598bd8a 100644
--- a/core/java/android/app/servertransaction/ObjectPool.java
+++ b/core/java/android/app/servertransaction/ObjectPool.java
@@ -16,6 +16,8 @@
 
 package android.app.servertransaction;
 
+import com.android.window.flags.Flags;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
@@ -38,6 +40,9 @@
      * @return An instance or null if there is none.
      */
     public static <T extends ObjectPoolItem> T obtain(Class<T> itemClass) {
+        if (Flags.disableObjectPool()) {
+            return null;
+        }
         synchronized (sPoolSync) {
             @SuppressWarnings("unchecked")
             final ArrayList<T> itemPool = (ArrayList<T>) sPoolMap.get(itemClass);
@@ -54,6 +59,9 @@
      * @see ObjectPoolItem#recycle()
      */
     public static <T extends ObjectPoolItem> void recycle(T item) {
+        if (Flags.disableObjectPool()) {
+            return;
+        }
         synchronized (sPoolSync) {
             @SuppressWarnings("unchecked")
             ArrayList<T> itemPool = (ArrayList<T>) sPoolMap.get(item.getClass());
diff --git a/core/java/android/app/wearable/WearableSensingManager.java b/core/java/android/app/wearable/WearableSensingManager.java
index 4b77c74..b2b14ce 100644
--- a/core/java/android/app/wearable/WearableSensingManager.java
+++ b/core/java/android/app/wearable/WearableSensingManager.java
@@ -436,18 +436,18 @@
     /**
      * Requests the wearable to start hotword recognition.
      *
-     * <p>When this method is called, the system will attempt to provide a {@link
-     * android.service.wearable.WearableHotwordAudioConsumer} to {@link WearableSensingService}.
-     * After first-stage hotword is detected on a wearable, {@link WearableSensingService} should
-     * send the hotword audio to the {@link android.service.wearable.WearableHotwordAudioConsumer},
-     * which will forward the data to the {@link android.service.voice.HotwordDetectionService} for
+     * <p>When this method is called, the system will attempt to provide a {@code
+     * Consumer<android.service.voice.HotwordAudioStream>} to {@link WearableSensingService}. After
+     * first-stage hotword is detected on a wearable, {@link WearableSensingService} should send the
+     * hotword audio to the {@code Consumer<android.service.voice.HotwordAudioStream>}, which will
+     * forward the data to the {@link android.service.voice.HotwordDetectionService} for
      * second-stage hotword validation. If hotword is detected there, the audio data will be
      * forwarded to the {@link android.service.voice.VoiceInteractionService}.
      *
      * <p>If the {@code targetVisComponentName} provided here is not null, when {@link
-     * WearableSensingService} sends hotword audio to the {@link
-     * android.service.wearable.WearableHotwordAudioConsumer}, the system will check whether the
-     * {@link android.service.voice.VoiceInteractionService} at that time is {@code
+     * WearableSensingService} sends hotword audio to the {@code
+     * Consumer<android.service.voice.HotwordAudioStream>}, the system will check whether the {@link
+     * android.service.voice.VoiceInteractionService} at that time is {@code
      * targetVisComponentName}. If not, the system will call {@link
      * WearableSensingService#onActiveHotwordAudioStopRequested()} and will not forward the audio
      * data to the current {@link android.service.voice.HotwordDetectionService} nor {@link
@@ -457,8 +457,8 @@
      * android.service.voice.VoiceInteractionService} is the same as {@code targetVisComponentName}.
      * The check here is just a protection against race conditions.
      *
-     * <p>Calling this method again will send a new {@link
-     * android.service.wearable.WearableHotwordAudioConsumer} to {@link WearableSensingService}. For
+     * <p>Calling this method again will send a new {@code
+     * Consumer<android.service.voice.HotwordAudioStream>} to {@link WearableSensingService}. For
      * audio data sent to the new consumer, the system will perform the above check using the newly
      * provided {@code targetVisComponentName}. The {@link WearableSensingService} should not
      * continue to use the previous consumers after receiving a new one.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 1f6730b..4b579e7 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2628,15 +2628,6 @@
             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
@@ -2708,15 +2699,6 @@
             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 c7403c0..153dd9a 100644
--- a/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java
@@ -316,15 +316,6 @@
             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,
@@ -377,27 +368,19 @@
             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) {
-            return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, "Bad package SDK");
+            // 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);
         }
 
         // Otherwise, we're looking at an incompatible pre-release SDK.
diff --git a/core/java/android/credentials/CredentialManager.java b/core/java/android/credentials/CredentialManager.java
index 481ff2e..f0f691d 100644
--- a/core/java/android/credentials/CredentialManager.java
+++ b/core/java/android/credentials/CredentialManager.java
@@ -470,8 +470,8 @@
      * Returns {@code true} if the calling application provides a CredentialProviderService that is
      * enabled for the current user, or {@code false} otherwise. CredentialProviderServices are
      * enabled on a per-service basis so the individual component name of the service should be
-     * passed in here. <strong>Usage of this API is discouraged as it is not fully functional, and
-     * may throw a NullPointerException on certain devices and/or API versions.</strong>
+     * passed in here. <strong>Usage of this API is encouraged in API level 35 and above. It
+     * may throw a NullPointerException on certain devices running other API versions.</strong>
      *
      * @throws IllegalArgumentException if the componentName package does not match the calling
      * package name this call will throw an exception
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 8aa2c35..30d2dec 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1238,6 +1238,18 @@
         public static final int VANILLA_ICE_CREAM = 35;
     }
 
+    /**
+     * The vendor API for 2024 Q2
+     *
+     * <p>For Android 14-QPR3 and later, the vendor API level is completely decoupled from the SDK
+     * API level and the format has switched to YYYYMM (year and month)
+     *
+     * @see <a href="https://preview.source.android.com/docs/core/architecture/api-flags">Vendor API
+     *     level</a>
+     * @hide
+     */
+    public static final int VENDOR_API_2024_Q2 = 202404;
+
     /** The type of build, like "user" or "eng". */
     public static final String TYPE = getString("ro.build.type");
 
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 222c69c..292e6bd 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -17,6 +17,10 @@
 
 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
 
+import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH;
+import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH;
+import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH;
+
 import android.animation.ValueAnimator;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -2135,27 +2139,26 @@
         }
     }
 
-    private static void registerIntentMatchingRestrictionCallback() {
-        try {
-            ActivityManager.getService().registerStrictModeCallback(
-                    new UnsafeIntentStrictModeCallback());
-        } catch (RemoteException e) {
-            /*
-            If exception is DeadObjectException it means system process is dead, so we can ignore
-             */
-            if (!(e instanceof DeadObjectException)) {
-                Log.e(TAG, "RemoteException handling StrictMode violation", e);
+    private static final class UnsafeIntentStrictModeCallback
+            extends IUnsafeIntentStrictModeCallback.Stub {
+        @Override
+        public void onUnsafeIntent(int type, Intent intent) {
+            if (StrictMode.vmUnsafeIntentLaunchEnabled()) {
+                StrictMode.onUnsafeIntentLaunch(type, intent);
             }
         }
     }
 
-    private static final class UnsafeIntentStrictModeCallback
-            extends IUnsafeIntentStrictModeCallback.Stub {
-        @Override
-        public void onImplicitIntentMatchedInternalComponent(Intent intent) {
-            if (StrictMode.vmUnsafeIntentLaunchEnabled()) {
-                StrictMode.onUnsafeIntentLaunch(intent,
-                        "Launch of unsafe implicit intent: " + intent);
+    /** Each process should only have one singleton callback */
+    private static volatile UnsafeIntentStrictModeCallback sUnsafeIntentCallback;
+
+    private static void registerIntentMatchingRestrictionCallback() {
+        if (sUnsafeIntentCallback == null) {
+            sUnsafeIntentCallback = new UnsafeIntentStrictModeCallback();
+            try {
+                ActivityManager.getService().registerStrictModeCallback(sUnsafeIntentCallback);
+            } catch (RemoteException e) {
+                // system_server should not throw
             }
         }
     }
@@ -2383,9 +2386,22 @@
         onVmPolicyViolation(new UnsafeIntentLaunchViolation(intent));
     }
 
-    /** @hide */
-    public static void onUnsafeIntentLaunch(Intent intent, String message) {
-        onVmPolicyViolation(new UnsafeIntentLaunchViolation(intent, message));
+    private static void onUnsafeIntentLaunch(int type, Intent intent) {
+        String msg;
+        switch (type) {
+            case UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH:
+                msg = "Launch of intent with null action: ";
+                break;
+            case UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH:
+                msg = "Implicit intent matching internal non-exported component: ";
+                break;
+            case UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH:
+                msg = "Intent mismatch target component intent filter: ";
+                break;
+            default:
+                return;
+        }
+        onVmPolicyViolation(new UnsafeIntentLaunchViolation(intent, msg + intent));
     }
 
     /** Assume locked until we hear otherwise */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7933212..53a30b2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1736,6 +1736,24 @@
             "android.settings.NETWORK_OPERATOR_SETTINGS";
 
     /**
+     * Activity Action: Show settings for selecting the network provider.
+     * <p>
+     * In some cases, a matching Activity may not be provided, so ensure you
+     * safeguard against this.
+     * <p>
+     * Access to this preference can be customized via Settings' app.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_NETWORK_PROVIDER_SETTINGS =
+            "android.settings.NETWORK_PROVIDER_SETTINGS";
+
+    /**
      * Activity Action: Show settings for selection of 2G/3G.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 1626924..8d884f2 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -713,11 +713,13 @@
             new InsetsState.OnTraverseCallbacks() {
 
                 private @InsetsType int mTypes;
+                private InsetsState mFromState;
                 private InsetsState mToState;
 
                 @Override
                 public void onStart(InsetsState state1, InsetsState state2) {
                     mTypes = 0;
+                    mFromState = null;
                     mToState = null;
                 }
 
@@ -734,9 +736,13 @@
                         return;
                     }
                     mTypes |= source1.getType();
+                    if (mFromState == null) {
+                        mFromState = new InsetsState();
+                    }
                     if (mToState == null) {
                         mToState = new InsetsState();
                     }
+                    mFromState.addSource(new InsetsSource(source1));
                     mToState.addSource(new InsetsSource(source2));
                 }
 
@@ -747,7 +753,7 @@
                     }
                     cancelExistingControllers(mTypes);
                     final InsetsAnimationControlRunner runner = new InsetsResizeAnimationRunner(
-                            mFrame, state1, mToState, RESIZE_INTERPOLATOR,
+                            mFrame, mFromState, mToState, RESIZE_INTERPOLATOR,
                             ANIMATION_DURATION_RESIZE, mTypes, InsetsController.this);
                     if (mRunningAnimations.isEmpty()) {
                         mHost.notifyAnimationRunningStateChanged(true);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 088d551..e0f9fcc 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -12809,8 +12809,13 @@
                                 + mFrameRateCompatibility);
                 }
                 if (sToolkitFrameRateFunctionEnablingReadOnlyFlagValue) {
-                    mFrameRateTransaction.setFrameRate(mSurfaceControl, preferredFrameRate,
-                            mFrameRateCompatibility).applyAsyncUnsafe();
+                    if (preferredFrameRate > 0) {
+                        mFrameRateTransaction.setFrameRate(mSurfaceControl, preferredFrameRate,
+                                mFrameRateCompatibility);
+                    } else {
+                        mFrameRateTransaction.clearFrameRate(mSurfaceControl);
+                    }
+                    mFrameRateTransaction.applyAsyncUnsafe();
                 }
                 mLastPreferredFrameRate = preferredFrameRate;
             }
diff --git a/core/java/android/window/TaskFragmentAnimationParams.java b/core/java/android/window/TaskFragmentAnimationParams.java
index c8f6327..85e96c9 100644
--- a/core/java/android/window/TaskFragmentAnimationParams.java
+++ b/core/java/android/window/TaskFragmentAnimationParams.java
@@ -16,17 +16,21 @@
 
 package android.window;
 
+import static android.window.TransitionInfo.AnimationOptions.DEFAULT_ANIMATION_RESOURCES_ID;
+
+import android.annotation.AnimRes;
 import android.annotation.ColorInt;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.Objects;
+
 /**
  * Data object for animation related override of TaskFragment.
  * @hide
  */
-// TODO(b/206557124): Add more animation customization options.
 public final class TaskFragmentAnimationParams implements Parcelable {
 
     /** The default {@link TaskFragmentAnimationParams} to use when there is no app override. */
@@ -43,8 +47,22 @@
     @ColorInt
     private final int mAnimationBackgroundColor;
 
-    private TaskFragmentAnimationParams(@ColorInt int animationBackgroundColor) {
+    @AnimRes
+    private final int mOpenAnimationResId;
+
+    @AnimRes
+    private final int mChangeAnimationResId;
+
+    @AnimRes
+    private final int mCloseAnimationResId;
+
+    private TaskFragmentAnimationParams(@ColorInt int animationBackgroundColor,
+            @AnimRes int openAnimationResId, @AnimRes int changeAnimationResId,
+            @AnimRes int closeAnimationResId) {
         mAnimationBackgroundColor = animationBackgroundColor;
+        mOpenAnimationResId = openAnimationResId;
+        mChangeAnimationResId = changeAnimationResId;
+        mCloseAnimationResId = closeAnimationResId;
     }
 
     /**
@@ -58,13 +76,52 @@
         return mAnimationBackgroundColor;
     }
 
+    /**
+     * Returns the resources ID of open animation that applies to this TaskFragment.
+     * <p>
+     * The default value is {@link DEFAULT_ANIMATION_RESOURCES_ID}, which is to use the system
+     * default animation.
+     */
+    @AnimRes
+    public int getOpenAnimationResId() {
+        return mOpenAnimationResId;
+    }
+
+    /**
+     * Returns the resources ID of change animation that applies to this TaskFragment.
+     * <p>
+     * The default value is {@link DEFAULT_ANIMATION_RESOURCES_ID}, which is to use the system
+     * default animation.
+     */
+    @AnimRes
+    public int getChangeAnimationResId() {
+        return mChangeAnimationResId;
+    }
+
+    /**
+     * Returns the resources ID of close animation that applies to this TaskFragment.
+     * <p>
+     * The default value is {@link DEFAULT_ANIMATION_RESOURCES_ID}, which is to use the system
+     * default animation.
+     */
+    @AnimRes
+    public int getCloseAnimationResId() {
+        return mCloseAnimationResId;
+    }
+
     private TaskFragmentAnimationParams(Parcel in) {
         mAnimationBackgroundColor = in.readInt();
+        mOpenAnimationResId = in.readInt();
+        mChangeAnimationResId = in.readInt();
+        mCloseAnimationResId = in.readInt();
     }
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(mAnimationBackgroundColor);
+        dest.writeInt(mOpenAnimationResId);
+        dest.writeInt(mChangeAnimationResId);
+        dest.writeInt(mCloseAnimationResId);
     }
 
     @NonNull
@@ -85,21 +142,37 @@
     public String toString() {
         return "TaskFragmentAnimationParams{"
                 + " animationBgColor=" + Integer.toHexString(mAnimationBackgroundColor)
+                + " openAnimResId=" + mOpenAnimationResId
+                + " changeAnimResId=" + mChangeAnimationResId
+                + " closeAnimResId=" + mCloseAnimationResId
                 + "}";
     }
 
     @Override
     public int hashCode() {
-        return mAnimationBackgroundColor;
+        return Objects.hash(mAnimationBackgroundColor, mOpenAnimationResId, mChangeAnimationResId,
+                mCloseAnimationResId);
     }
 
     @Override
     public boolean equals(@Nullable Object obj) {
-        if (!(obj instanceof TaskFragmentAnimationParams)) {
+        if (!(obj instanceof TaskFragmentAnimationParams other)) {
             return false;
         }
-        final TaskFragmentAnimationParams other = (TaskFragmentAnimationParams) obj;
-        return mAnimationBackgroundColor == other.mAnimationBackgroundColor;
+        return mAnimationBackgroundColor == other.mAnimationBackgroundColor
+                && mOpenAnimationResId == other.mOpenAnimationResId
+                && mChangeAnimationResId == other.mChangeAnimationResId
+                && mCloseAnimationResId == other.mCloseAnimationResId;
+    }
+
+    /**
+     * Returns {@code true} if one of {@link #getOpenAnimationResId()},
+     * {@link #getChangeAnimationResId()} or {@link #getCloseAnimationResId()} is specified.
+     */
+    public boolean hasOverrideAnimation() {
+        return mOpenAnimationResId != DEFAULT_ANIMATION_RESOURCES_ID
+                || mChangeAnimationResId != DEFAULT_ANIMATION_BACKGROUND_COLOR
+                || mCloseAnimationResId != DEFAULT_ANIMATION_RESOURCES_ID;
     }
 
     @Override
@@ -113,6 +186,15 @@
         @ColorInt
         private int mAnimationBackgroundColor = DEFAULT_ANIMATION_BACKGROUND_COLOR;
 
+        @AnimRes
+        private int mOpenAnimationResId = DEFAULT_ANIMATION_RESOURCES_ID;
+
+        @AnimRes
+        private int mChangeAnimationResId = DEFAULT_ANIMATION_RESOURCES_ID;
+
+        @AnimRes
+        private int mCloseAnimationResId = DEFAULT_ANIMATION_RESOURCES_ID;
+
         /**
          * Sets the {@link ColorInt} to use for the background during the animation with this
          * TaskFragment if the animation requires a background. The default value is
@@ -128,10 +210,50 @@
             return this;
         }
 
+        /**
+         * Sets the open animation resources ID this TaskFragment. The default value is
+         * {@link DEFAULT_ANIMATION_RESOURCES_ID}, which is to use the system default animation.
+         *
+         * @param resId the open animation resources ID.
+         * @return this {@link Builder}.
+         */
+        @NonNull
+        public Builder setOpenAnimationResId(@AnimRes int resId) {
+            mOpenAnimationResId = resId;
+            return this;
+        }
+
+        /**
+         * Sets the change animation resources ID this TaskFragment. The default value is
+         * {@link DEFAULT_ANIMATION_RESOURCES_ID}, which is to use the system default animation.
+         *
+         * @param resId the change animation resources ID.
+         * @return this {@link Builder}.
+         */
+        @NonNull
+        public Builder setChangeAnimationResId(@AnimRes int resId) {
+            mChangeAnimationResId = resId;
+            return this;
+        }
+
+        /**
+         * Sets the close animation resources ID this TaskFragment. The default value is
+         * {@link DEFAULT_ANIMATION_RESOURCES_ID}, which is to use the system default animation.
+         *
+         * @param resId the close animation resources ID.
+         * @return this {@link Builder}.
+         */
+        @NonNull
+        public Builder setCloseAnimationResId(@AnimRes int resId) {
+            mCloseAnimationResId = resId;
+            return this;
+        }
+
         /** Constructs the {@link TaskFragmentAnimationParams}. */
         @NonNull
         public TaskFragmentAnimationParams build() {
-            return new TaskFragmentAnimationParams(mAnimationBackgroundColor);
+            return new TaskFragmentAnimationParams(mAnimationBackgroundColor,
+                    mOpenAnimationResId, mChangeAnimationResId, mCloseAnimationResId);
         }
     }
 }
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 8a79754..1d42c93 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -1107,6 +1107,7 @@
 
         private int mType;
         private @AnimRes int mEnterResId = DEFAULT_ANIMATION_RESOURCES_ID;
+        private @AnimRes int mChangeResId = DEFAULT_ANIMATION_RESOURCES_ID;
         private @AnimRes int mExitResId = DEFAULT_ANIMATION_RESOURCES_ID;
         private boolean mOverrideTaskTransition;
         private String mPackageName;
@@ -1126,6 +1127,7 @@
         private AnimationOptions(Parcel in) {
             mType = in.readInt();
             mEnterResId = in.readInt();
+            mChangeResId = in.readInt();
             mExitResId = in.readInt();
             mBackgroundColor = in.readInt();
             mOverrideTaskTransition = in.readBoolean();
@@ -1189,9 +1191,27 @@
         public static AnimationOptions makeCustomAnimOptions(@NonNull String packageName,
                 @AnimRes int enterResId, @AnimRes int exitResId, @ColorInt int backgroundColor,
                 boolean overrideTaskTransition) {
+            return makeCustomAnimOptions(packageName, enterResId, DEFAULT_ANIMATION_RESOURCES_ID,
+                    exitResId, backgroundColor, overrideTaskTransition);
+        }
+
+        /**
+         * Creates a {@link android.app.ActivityOptions#ANIM_CUSTOM} {@link AnimationOptions}.
+         *
+         * @param packageName the package name that includes the animation resources.
+         * @param enterResId the resources ID of open animation.
+         * @param changeResId the resources ID of change animation.
+         * @param exitResId the resources ID of close animation.
+         * @param overrideTaskTransition indicates whether to override task transition.
+         */
+        @NonNull
+        public static AnimationOptions makeCustomAnimOptions(@NonNull String packageName,
+                @AnimRes int enterResId, @AnimRes int changeResId, @AnimRes int exitResId,
+                @ColorInt int backgroundColor, boolean overrideTaskTransition) {
             AnimationOptions options = new AnimationOptions(ANIM_CUSTOM);
             options.mPackageName = packageName;
             options.mEnterResId = enterResId;
+            options.mChangeResId = changeResId;
             options.mExitResId = exitResId;
             options.mBackgroundColor = backgroundColor;
             options.mOverrideTaskTransition = overrideTaskTransition;
@@ -1251,6 +1271,11 @@
         }
 
         @AnimRes
+        public int getChangeResId() {
+            return mChangeResId;
+        }
+
+        @AnimRes
         public int getExitResId() {
             return mExitResId;
         }
@@ -1292,6 +1317,7 @@
         public void writeToParcel(@NonNull Parcel dest, int flags) {
             dest.writeInt(mType);
             dest.writeInt(mEnterResId);
+            dest.writeInt(mChangeResId);
             dest.writeInt(mExitResId);
             dest.writeInt(mBackgroundColor);
             dest.writeBoolean(mOverrideTaskTransition);
@@ -1352,6 +1378,9 @@
             if (mEnterResId != DEFAULT_ANIMATION_RESOURCES_ID) {
                 sb.append(" enterResId=").append(mEnterResId);
             }
+            if (mChangeResId != DEFAULT_ANIMATION_RESOURCES_ID) {
+                sb.append(" changeResId=").append(mChangeResId);
+            }
             if (mExitResId != DEFAULT_ANIMATION_RESOURCES_ID) {
                 sb.append(" exitResId=").append(mExitResId);
             }
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 5e88d97c..f4f6c8a 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -375,7 +375,23 @@
      */
     @NonNull
     public WindowContainerTransaction reorder(@NonNull WindowContainerToken child, boolean onTop) {
-        mHierarchyOps.add(HierarchyOp.createForReorder(child.asBinder(), onTop));
+        return reorder(child, onTop, false /* includingParents */);
+    }
+
+    /**
+     * Reorders a container within its parent with an option to reorder all the parents in the
+     * hierarchy above among their respective siblings.
+     *
+     * @param onTop When {@code true}, the child goes to the top of parent; otherwise it goes to
+     *              the bottom.
+     * @param includingParents When {@code true}, all the parents in the hierarchy above are also
+     *                         reordered among their respective siblings.
+     * @hide
+     */
+    @NonNull
+    public WindowContainerTransaction reorder(@NonNull WindowContainerToken child, boolean onTop,
+            boolean includingParents) {
+        mHierarchyOps.add(HierarchyOp.createForReorder(child.asBinder(), onTop, includingParents));
         return this;
     }
 
@@ -1451,6 +1467,8 @@
         @Nullable
         private Rect mBounds;
 
+        private boolean mIncludingParents;
+
         private boolean mAlwaysOnTop;
 
         private boolean mReparentLeafTaskIfRelaunch;
@@ -1464,11 +1482,22 @@
                     .build();
         }
 
-        public static HierarchyOp createForReorder(@NonNull IBinder container, boolean toTop) {
+        /**
+         * Creates the {@link HierarchyOp} for the reorder operation.
+         *
+         * @param container which needs to be reordered
+         * @param toTop if true, the container reorders
+         * @param includingParents if true, all the parents in the hierarchy above are also
+         *                         reoredered among their respective siblings
+         * @return
+         */
+        public static HierarchyOp createForReorder(@NonNull IBinder container, boolean toTop,
+                boolean includingParents) {
             return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REORDER)
                     .setContainer(container)
                     .setReparentContainer(container)
                     .setToTop(toTop)
+                    .setIncludingParents(includingParents)
                     .build();
         }
 
@@ -1555,6 +1584,7 @@
             mType = copy.mType;
             mContainer = copy.mContainer;
             mBounds = copy.mBounds;
+            mIncludingParents = copy.mIncludingParents;
             mReparent = copy.mReparent;
             mInsetsFrameProvider = copy.mInsetsFrameProvider;
             mInsetsFrameOwner = copy.mInsetsFrameOwner;
@@ -1575,6 +1605,7 @@
             mType = in.readInt();
             mContainer = in.readStrongBinder();
             mBounds = in.readTypedObject(Rect.CREATOR);
+            mIncludingParents = in.readBoolean();
             mReparent = in.readStrongBinder();
             mInsetsFrameProvider = in.readTypedObject(InsetsFrameProvider.CREATOR);
             mInsetsFrameOwner = in.readStrongBinder();
@@ -1678,6 +1709,12 @@
             return mBounds;
         }
 
+        /** Denotes whether the parents should also be included in the op. */
+        @NonNull
+        public boolean includingParents() {
+            return mIncludingParents;
+        }
+
         /** Gets a string representation of a hierarchy-op type. */
         public static String hopToString(int type) {
             switch (type) {
@@ -1789,6 +1826,7 @@
             dest.writeInt(mType);
             dest.writeStrongBinder(mContainer);
             dest.writeTypedObject(mBounds, flags);
+            dest.writeBoolean(mIncludingParents);
             dest.writeStrongBinder(mReparent);
             dest.writeTypedObject(mInsetsFrameProvider, flags);
             dest.writeStrongBinder(mInsetsFrameOwner);
@@ -1866,6 +1904,8 @@
             @Nullable
             private Rect mBounds;
 
+            private boolean mIncludingParents;
+
             private boolean mAlwaysOnTop;
 
             private boolean mReparentLeafTaskIfRelaunch;
@@ -1955,6 +1995,11 @@
                 return this;
             }
 
+            Builder setIncludingParents(boolean value) {
+                mIncludingParents = value;
+                return this;
+            }
+
             HierarchyOp build() {
                 final HierarchyOp hierarchyOp = new HierarchyOp(mType);
                 hierarchyOp.mContainer = mContainer;
@@ -1976,6 +2021,7 @@
                 hierarchyOp.mTaskFragmentOperation = mTaskFragmentOperation;
                 hierarchyOp.mShortcutInfo = mShortcutInfo;
                 hierarchyOp.mBounds = mBounds;
+                hierarchyOp.mIncludingParents = mIncludingParents;
                 hierarchyOp.mReparentLeafTaskIfRelaunch = mReparentLeafTaskIfRelaunch;
 
                 return hierarchyOp;
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 0590c40..1742fe3 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -92,3 +92,10 @@
     description: "Makes the App Header style adapt to the system's and app's light/dark theme"
     bug: "328668781"
 }
+
+flag {
+    name: "enable_camera_compat_for_desktop_windowing"
+    namespace: "lse_desktop_experience"
+    description: "Whether to apply Camera Compat treatment to fixed-orientation apps in desktop windowing mode"
+    bug: "314952133"
+}
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index 9e69f89..87ede4a 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -169,3 +169,14 @@
          purpose: PURPOSE_BUGFIX
      }
 }
+
+flag {
+    namespace: "windowing_sdk"
+    name: "disable_object_pool"
+    description: "Whether to disable object pool and let the GC handle lifecycle items"
+    bug: "311089192"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 71bbccb..b8f7a3d 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -69,7 +69,7 @@
 
     private static final long LAUNCH_TIME = 5000L;
 
-    private static final String U_EGG_UNLOCK_SETTING = "egg_mode_u";
+    private static final String EGG_UNLOCK_SETTING = "egg_mode_v";
 
     private static final float MIN_WARP = 1f;
     private static final float MAX_WARP = 10f; // after all these years
@@ -309,13 +309,12 @@
 
     private void launchNextStage(boolean locked) {
         final ContentResolver cr = getContentResolver();
-
         try {
             if (shouldWriteSettings()) {
                 Log.v(TAG, "Saving egg locked=" + locked);
                 syncTouchPressure();
                 Settings.System.putLong(cr,
-                        U_EGG_UNLOCK_SETTING,
+                        EGG_UNLOCK_SETTING,
                         locked ? 0 : System.currentTimeMillis());
             }
         } catch (RuntimeException e) {
@@ -499,4 +498,4 @@
             mDt = dt;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/com/android/internal/protolog/ProtoLogGroup.java b/core/java/com/android/internal/protolog/ProtoLogGroup.java
index f2783c4..bb3507c 100644
--- a/core/java/com/android/internal/protolog/ProtoLogGroup.java
+++ b/core/java/com/android/internal/protolog/ProtoLogGroup.java
@@ -18,6 +18,8 @@
 
 import com.android.internal.protolog.common.IProtoLogGroup;
 
+import java.util.UUID;
+
 /**
  * Defines logging groups for ProtoLog.
  *
@@ -153,10 +155,18 @@
         this.mLogToLogcat = logToLogcat;
     }
 
+    @Override
+    public int getId() {
+        return Consts.START_ID + this.ordinal();
+    }
+
     private static class Consts {
         private static final String TAG_WM = "WindowManager";
 
         private static final boolean ENABLE_DEBUG = true;
         private static final boolean ENABLE_LOG_TO_PROTO_DEBUG = true;
+        private static final int START_ID = (int) (
+                UUID.nameUUIDFromBytes(ProtoLogGroup.class.getName().getBytes())
+                        .getMostSignificantBits() % Integer.MAX_VALUE);
     }
 }
diff --git a/core/java/com/android/internal/protolog/common/IProtoLogGroup.java b/core/java/com/android/internal/protolog/common/IProtoLogGroup.java
index 149aa7a..91b24fd 100644
--- a/core/java/com/android/internal/protolog/common/IProtoLogGroup.java
+++ b/core/java/com/android/internal/protolog/common/IProtoLogGroup.java
@@ -64,4 +64,9 @@
      * returns name of the logging group.
      */
     String name();
+
+    /**
+     * returns the id of the logging group (unique for each group).
+     */
+    int getId();
 }
diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java
index eef3368..606e038 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -93,8 +93,7 @@
         if (bg != null) {
             bg.setCallback(this);
             if (mActionBarView != null) {
-                mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(),
-                        mActionBarView.getRight(), mActionBarView.getBottom());
+                bg.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
             }
         }
         setWillNotDraw(mIsSplit ? mSplitBackground == null :
@@ -293,6 +292,7 @@
         if (mActionBarView == null) return;
 
         if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
+            final int verticalPadding = getPaddingTop() + getPaddingBottom();
             int nonTabMaxHeight = 0;
             final int childCount = getChildCount();
             for (int i = 0; i < childCount; i++) {
@@ -307,7 +307,9 @@
             final int maxHeight = mode == MeasureSpec.AT_MOST ?
                     MeasureSpec.getSize(heightMeasureSpec) : Integer.MAX_VALUE;
             setMeasuredDimension(getMeasuredWidth(),
-                    Math.min(nonTabMaxHeight + getMeasuredHeightWithMargins(mTabContainer),
+                    Math.min(
+                            verticalPadding + nonTabMaxHeight
+                                    + getMeasuredHeightWithMargins(mTabContainer),
                             maxHeight));
         }
     }
@@ -335,13 +337,9 @@
             }
         } else {
             if (mBackground != null) {
-                if (mActionBarView.getVisibility() == View.VISIBLE) {
-                    mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(),
-                            mActionBarView.getRight(), mActionBarView.getBottom());
-                } else if (mActionContextView != null &&
-                        mActionContextView.getVisibility() == View.VISIBLE) {
-                    mBackground.setBounds(mActionContextView.getLeft(), mActionContextView.getTop(),
-                            mActionContextView.getRight(), mActionContextView.getBottom());
+                if ((mActionBarView.getVisibility() == View.VISIBLE) || (mActionContextView != null
+                        && mActionContextView.getVisibility() == View.VISIBLE)) {
+                    mBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
                 } else {
                     mBackground.setBounds(0, 0, 0, 0);
                 }
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 0992db9..707f109 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -24,6 +24,7 @@
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.Insets;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
@@ -77,10 +78,13 @@
     private final Rect mBaseContentInsets = new Rect();
     private final Rect mLastBaseContentInsets = new Rect();
     private final Rect mContentInsets = new Rect();
+    private final Rect mSystemInsets = new Rect();
     private WindowInsets mBaseInnerInsets = WindowInsets.CONSUMED;
     private WindowInsets mLastBaseInnerInsets = WindowInsets.CONSUMED;
     private WindowInsets mInnerInsets = WindowInsets.CONSUMED;
     private WindowInsets mLastInnerInsets = WindowInsets.CONSUMED;
+    private boolean mDecorFitsSystemWindows = true;
+    private boolean mActionBarExtendsIntoSystemInsets = false;
 
     private ActionBarVisibilityCallback mActionBarVisibilityCallback;
 
@@ -268,7 +272,8 @@
             // We want the bar to be visible if it is not being hidden,
             // or the app has not turned on a stable UI mode (meaning they
             // are performing explicit layout around the action bar).
-            mActionBarVisibilityCallback.enableContentAnimations(!stable);
+            mActionBarVisibilityCallback.enableContentAnimations(
+                    !stable && !mActionBarExtendsIntoSystemInsets);
             if (barVisible || !stable) mActionBarVisibilityCallback.showForSystem();
             else mActionBarVisibilityCallback.hideForSystem();
         }
@@ -288,25 +293,56 @@
         }
     }
 
-    private boolean applyInsets(View view, Rect insets, boolean left, boolean top,
-            boolean bottom, boolean right) {
+    private boolean applyInsets(View view, Rect insets, boolean toPadding,
+            boolean left, boolean top, boolean bottom, boolean right) {
+        boolean changed;
+        if (toPadding) {
+            changed = setMargin(view, left, top, bottom, right, 0, 0, 0, 0);
+            changed |= setPadding(view, left, top, bottom, right,
+                    insets.left, insets.top, insets.right, insets.bottom);
+        } else {
+            changed = setPadding(view, left, top, bottom, right, 0, 0, 0, 0);
+            changed |= setMargin(view, left, top, bottom, right,
+                    insets.left, insets.top, insets.right, insets.bottom);
+        }
+        return changed;
+    }
+
+    private boolean setPadding(View view, boolean left, boolean top, boolean bottom, boolean right,
+            int l, int t, int r, int b) {
+        if ((left && view.getPaddingLeft() != l)
+                || (top && view.getPaddingTop() != t)
+                || (right && view.getPaddingRight() != r)
+                || (bottom && view.getPaddingBottom() != b)) {
+            view.setPadding(
+                    left ? l : view.getPaddingLeft(),
+                    top ? t : view.getPaddingTop(),
+                    right ? r : view.getPaddingRight(),
+                    bottom ? b : view.getPaddingBottom());
+            return true;
+        }
+        return false;
+    }
+
+    private boolean setMargin(View view, boolean left, boolean top, boolean bottom, boolean right,
+            int l, int t, int r, int b) {
+        LayoutParams lp = (LayoutParams) view.getLayoutParams();
         boolean changed = false;
-        LayoutParams lp = (LayoutParams)view.getLayoutParams();
-        if (left && lp.leftMargin != insets.left) {
+        if (left && lp.leftMargin != l) {
             changed = true;
-            lp.leftMargin = insets.left;
+            lp.leftMargin = l;
         }
-        if (top && lp.topMargin != insets.top) {
+        if (top && lp.topMargin != t) {
             changed = true;
-            lp.topMargin = insets.top;
+            lp.topMargin = t;
         }
-        if (right && lp.rightMargin != insets.right) {
+        if (right && lp.rightMargin != r) {
             changed = true;
-            lp.rightMargin = insets.right;
+            lp.rightMargin = r;
         }
-        if (bottom && lp.bottomMargin != insets.bottom) {
+        if (bottom && lp.bottomMargin != b) {
             changed = true;
-            lp.bottomMargin = insets.bottom;
+            lp.bottomMargin = b;
         }
         return changed;
     }
@@ -316,12 +352,28 @@
         pullChildren();
 
         final int vis = getWindowSystemUiVisibility();
-        final Rect systemInsets = insets.getSystemWindowInsetsAsRect();
+        final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0;
+        final boolean layoutIntoSystemInsets = (vis & SYSTEM_UI_LAYOUT_FLAGS) != 0;
+        mDecorFitsSystemWindows = hasContentOnApplyWindowInsetsListener();
+
+        // Only extend action bar into system insets area if the app doesn't fit system insets.
+        mActionBarExtendsIntoSystemInsets =
+                !mDecorFitsSystemWindows || (stable && layoutIntoSystemInsets);
+
+        if (mActionBarVisibilityCallback != null) {
+            mActionBarVisibilityCallback.enableContentAnimations(
+                    !stable && !mActionBarExtendsIntoSystemInsets);
+        }
+
+        final Insets sysInsets = insets.getSystemWindowInsets();
+        mSystemInsets.set(sysInsets.left, sysInsets.top, sysInsets.right, sysInsets.bottom);
 
         // The top and bottom action bars are always within the content area.
-        boolean changed = applyInsets(mActionBarTop, systemInsets, true, true, false, true);
+        boolean changed = applyInsets(mActionBarTop, mSystemInsets,
+                mActionBarExtendsIntoSystemInsets, true, true, false, true);
         if (mActionBarBottom != null) {
-            changed |= applyInsets(mActionBarBottom, systemInsets, true, false, true, true);
+            changed |= applyInsets(mActionBarBottom, mSystemInsets,
+                    mActionBarExtendsIntoSystemInsets, true, false, true, true);
         }
 
         // Cannot use the result of computeSystemWindowInsets, because that consumes the
@@ -406,6 +458,9 @@
             // This is the standard space needed for the action bar.  For stable measurement,
             // we can't depend on the size currently reported by it -- this must remain constant.
             topInset = mActionBarHeight;
+            if (mActionBarExtendsIntoSystemInsets) {
+                topInset += mSystemInsets.top;
+            }
             if (mHasNonEmbeddedTabs) {
                 final View tabs = mActionBarTop.getTabContainer();
                 if (tabs != null) {
@@ -424,6 +479,9 @@
             if (mActionBarBottom != null) {
                 if (stable) {
                     bottomInset = mActionBarHeight;
+                    if (mActionBarExtendsIntoSystemInsets) {
+                        bottomInset += mSystemInsets.bottom;
+                    }
                 } else {
                     bottomInset = mActionBarBottom.getMeasuredHeight();
                 }
@@ -436,21 +494,35 @@
         // overlay.
         mContentInsets.set(mBaseContentInsets);
         mInnerInsets = mBaseInnerInsets;
-        if (!mOverlayMode && !stable && hasContentOnApplyWindowInsetsListener()) {
-            mContentInsets.top += topInset;
-            mContentInsets.bottom += bottomInset;
+        if (!mOverlayMode && !stable && mDecorFitsSystemWindows) {
+            if (mActionBarExtendsIntoSystemInsets) {
+                mContentInsets.top = Math.max(mContentInsets.top, topInset);
+                mContentInsets.bottom = Math.max(mContentInsets.bottom, bottomInset);
+            } else {
+                mContentInsets.top += topInset;
+                mContentInsets.bottom += bottomInset;
+            }
             // Content view has been shrunk, shrink all insets to match.
             mInnerInsets = mInnerInsets.inset(0 /* left */, topInset, 0 /* right */, bottomInset);
         } else {
             // Add ActionBar to system window inset, but leave other insets untouched.
-            mInnerInsets = mInnerInsets.replaceSystemWindowInsets(
-                    mInnerInsets.getSystemWindowInsetLeft(),
-                    mInnerInsets.getSystemWindowInsetTop() + topInset,
-                    mInnerInsets.getSystemWindowInsetRight(),
-                    mInnerInsets.getSystemWindowInsetBottom() + bottomInset
-            );
+            if (mActionBarExtendsIntoSystemInsets) {
+                mInnerInsets = mInnerInsets.replaceSystemWindowInsets(
+                        mInnerInsets.getSystemWindowInsetLeft(),
+                        Math.max(mInnerInsets.getSystemWindowInsetTop(), topInset),
+                        mInnerInsets.getSystemWindowInsetRight(),
+                        Math.max(mInnerInsets.getSystemWindowInsetBottom(), bottomInset)
+                );
+            } else {
+                mInnerInsets = mInnerInsets.replaceSystemWindowInsets(
+                        mInnerInsets.getSystemWindowInsetLeft(),
+                        mInnerInsets.getSystemWindowInsetTop() + topInset,
+                        mInnerInsets.getSystemWindowInsetRight(),
+                        mInnerInsets.getSystemWindowInsetBottom() + bottomInset
+                );
+            }
         }
-        applyInsets(mContent, mContentInsets, true, true, true, true);
+        applyInsets(mContent, mContentInsets, false /* toPadding */, true, true, true, true);
 
         if (!mLastInnerInsets.equals(mInnerInsets)) {
             // If the inner insets have changed, we need to dispatch this down to
diff --git a/core/jni/android_database_SQLiteRawStatement.cpp b/core/jni/android_database_SQLiteRawStatement.cpp
index 8fc13a8..9614864 100644
--- a/core/jni/android_database_SQLiteRawStatement.cpp
+++ b/core/jni/android_database_SQLiteRawStatement.cpp
@@ -83,6 +83,16 @@
     }
 }
 
+// If the last operation failed, throw an exception and return true.  Otherwise return false.
+static bool throwIfError(JNIEnv *env, jlong stmtPtr) {
+    switch (sqlite3_errcode(db(stmtPtr))) {
+        case SQLITE_OK:
+        case SQLITE_DONE:
+        case SQLITE_ROW: return false;
+    }
+    throw_sqlite3_exception(env, db(stmtPtr), nullptr);
+    return true;
+}
 
 static jint bindParameterCount(JNIEnv* env, jclass, jlong stmtPtr) {
     return sqlite3_bind_parameter_count(stmt(stmtPtr));
@@ -223,17 +233,24 @@
 
 static jint columnBytes(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
     throwIfInvalidColumn(env, stmtPtr, col);
-    return sqlite3_column_bytes16(stmt(stmtPtr), col);
+    int r = sqlite3_column_bytes16(stmt(stmtPtr), col);
+    throwIfError(env, stmtPtr);
+    return r;
 }
 
-
 static jbyteArray columnBlob(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
     throwIfInvalidColumn(env, stmtPtr, col);
     const void* blob = sqlite3_column_blob(stmt(stmtPtr), col);
     if (blob == nullptr) {
+        if (throwIfError(env, stmtPtr)) {
+            return NULL;
+        }
         return (sqlite3_column_type(stmt(stmtPtr), col) == SQLITE_NULL) ? NULL : emptyArray;
     }
     size_t size = sqlite3_column_bytes(stmt(stmtPtr), col);
+    if (throwIfError(env, stmtPtr)) {
+        return NULL;
+    }
     jbyteArray result = env->NewByteArray(size);
     if (result == nullptr) {
         // An OutOfMemory exception will have been thrown.
@@ -248,9 +265,13 @@
     throwIfInvalidColumn(env, stmtPtr, col);
     const void* blob = sqlite3_column_blob(stmt(stmtPtr), col);
     if (blob == nullptr) {
+        throwIfError(env, stmtPtr);
         return 0;
     }
     jsize bsize = sqlite3_column_bytes(stmt(stmtPtr), col);
+    if (throwIfError(env, stmtPtr)) {
+        return 0;
+    }
     if (bsize == 0 || bsize <= srcOffset) {
         return 0;
     }
@@ -278,9 +299,13 @@
     throwIfInvalidColumn(env, stmtPtr, col);
     const jchar* text = static_cast<const jchar*>(sqlite3_column_text16(stmt(stmtPtr), col));
     if (text == nullptr) {
+        throwIfError(env, stmtPtr);
         return NULL;
     }
     size_t length = sqlite3_column_bytes16(stmt(stmtPtr), col) / sizeof(jchar);
+    if (throwIfError(env, stmtPtr)) {
+        return NULL;
+    }
     return env->NewString(text, length);
 }
 
diff --git a/core/jni/android_tracing_PerfettoDataSource.cpp b/core/jni/android_tracing_PerfettoDataSource.cpp
index 17129d8..fec28987 100644
--- a/core/jni/android_tracing_PerfettoDataSource.cpp
+++ b/core/jni/android_tracing_PerfettoDataSource.cpp
@@ -245,7 +245,6 @@
 }
 
 void nativeWritePackets(JNIEnv* env, jclass clazz, jlong ds_ptr, jobjectArray packets) {
-    ALOG(LOG_DEBUG, LOG_TAG, "nativeWritePackets(%p)", (void*)ds_ptr);
     sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(ds_ptr);
     datasource->WritePackets(env, packets);
 }
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 9b8dab7..fba0d81 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -115,7 +115,8 @@
     size_t* total = (size_t*) arg;
     uint32_t uncompLen;
 
-    if (!zipFile->getEntryInfo(zipEntry, nullptr, &uncompLen, nullptr, nullptr, nullptr, nullptr)) {
+    if (!zipFile->getEntryInfo(zipEntry, nullptr, &uncompLen, nullptr, nullptr, nullptr, nullptr,
+                               nullptr)) {
         return INSTALL_FAILED_INVALID_APK;
     }
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0706b32..4dfe000 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -7030,6 +7030,13 @@
     <!-- Name of the starting activity for DisplayCompat host. specific to automotive.-->
     <string name="config_defaultDisplayCompatHostActivity" translatable="false"></string>
 
+    <!-- Name of the starting activity for launch on private display. specific to automotive.-->
+    <string name="config_defaultLaunchOnPrivateDisplayRouterActivity" translatable="false"></string>
+
+    <!-- Allowlisted activities for launch on a private display. specific to automotive.-->
+    <!--TODO(b/343733988): Remove this allowlisting when GMS is ready with the allowlisting mechanism.-->
+    <string-array name="config_defaultAllowlistLaunchOnPrivateDisplayPackages"></string-array>
+
     <!-- Whether to use file hashes cache in watchlist-->
     <bool name="config_watchlistUseFileHashesCache">false</bool>
 
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 0e855af1..41696df 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -85,6 +85,7 @@
         "kotlin-test",
         "mockito-target-minus-junit4",
         "androidx.test.uiautomator_uiautomator",
+        "platform-parametric-runner-lib",
         "platform-test-annotations",
         "platform-compat-test-rules",
         "truth",
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index 30ec940..b64eeca 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -703,10 +703,10 @@
                 hugeIcon).build();
 
         Bitmap smallNotificationIcon = notification.getSmallIcon().getBitmap();
-        assertThat(smallNotificationIcon.getWidth()).isEqualTo(
+        assertThat((float) smallNotificationIcon.getWidth()).isWithin(3f).of(
                 mContext.getResources().getDimensionPixelSize(
                         R.dimen.notification_small_icon_size));
-        assertThat(smallNotificationIcon.getHeight()).isEqualTo(
+        assertThat((float) smallNotificationIcon.getHeight()).isWithin(3f).of(
                 mContext.getResources().getDimensionPixelSize(
                         R.dimen.notification_small_icon_size));
     }
@@ -730,23 +730,23 @@
         Notification notification = new Notification.Builder(mContext, "Channel").setStyle(
                 style).build();
 
-        int targetSize = mContext.getResources().getDimensionPixelSize(
+        float targetSize = mContext.getResources().getDimensionPixelSize(
                 ActivityManager.isLowRamDeviceStatic()
                         ? R.dimen.notification_person_icon_max_size_low_ram
                         : R.dimen.notification_person_icon_max_size);
 
         Bitmap personIcon = style.getUser().getIcon().getBitmap();
-        assertThat(personIcon.getWidth()).isEqualTo(targetSize);
-        assertThat(personIcon.getHeight()).isEqualTo(targetSize);
+        assertThat((float) personIcon.getWidth()).isWithin(3f).of(targetSize);
+        assertThat((float) personIcon.getHeight()).isWithin(3f).of(targetSize);
 
         Bitmap avatarIcon = style.getMessages().get(0).getSenderPerson().getIcon().getBitmap();
-        assertThat(avatarIcon.getWidth()).isEqualTo(targetSize);
-        assertThat(avatarIcon.getHeight()).isEqualTo(targetSize);
+        assertThat((float) avatarIcon.getWidth()).isWithin(3f).of(targetSize);
+        assertThat((float) avatarIcon.getHeight()).isWithin(3f).of(targetSize);
 
         Bitmap historicAvatarIcon = style.getHistoricMessages().get(
                 0).getSenderPerson().getIcon().getBitmap();
-        assertThat(historicAvatarIcon.getWidth()).isEqualTo(targetSize);
-        assertThat(historicAvatarIcon.getHeight()).isEqualTo(targetSize);
+        assertThat((float) historicAvatarIcon.getWidth()).isWithin(3f).of(targetSize);
+        assertThat((float) historicAvatarIcon.getHeight()).isWithin(3f).of(targetSize);
     }
 
     @Test
@@ -760,10 +760,10 @@
                 style).build();
         Bitmap shortcutIcon = style.getShortcutIcon().getBitmap();
 
-        assertThat(shortcutIcon.getWidth()).isEqualTo(
+        assertThat((float) shortcutIcon.getWidth()).isWithin(3f).of(
                 mContext.getResources().getDimensionPixelSize(
                         R.dimen.notification_small_icon_size));
-        assertThat(shortcutIcon.getHeight()).isEqualTo(
+        assertThat((float) shortcutIcon.getHeight()).isWithin(3f).of(
                 mContext.getResources().getDimensionPixelSize(
                         R.dimen.notification_small_icon_size));
     }
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index 584fe16..32e611c 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -21,6 +21,8 @@
 import static android.app.servertransaction.TestUtils.referrerIntentList;
 import static android.app.servertransaction.TestUtils.resultInfoList;
 
+import static com.android.window.flags.Flags.FLAG_DISABLE_OBJECT_POOL;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotSame;
@@ -39,19 +41,27 @@
 import android.os.IBinder;
 import android.os.PersistableBundle;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.FlagsParameterization;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.window.ActivityWindowInfo;
 
 import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.window.flags.Flags;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.List;
 import java.util.function.Supplier;
 
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
 /**
  * Tests for {@link ObjectPool}.
  *
@@ -61,16 +71,28 @@
  * <p>This test class is a part of Window Manager Service tests and specified in
  * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
  */
-@RunWith(AndroidJUnit4.class)
+@RunWith(ParameterizedAndroidJunit4.class)
 @SmallTest
 @Presubmit
 public class ObjectPoolTests {
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return FlagsParameterization.allCombinationsOf(FLAG_DISABLE_OBJECT_POOL);
+    }
+
+    @Rule
+    public SetFlagsRule mSetFlagsRule;
+
     @Mock
     private IApplicationThread mApplicationThread;
     @Mock
     private IBinder mActivityToken;
 
+    public ObjectPoolTests(FlagsParameterization flags) {
+        mSetFlagsRule = new SetFlagsRule(flags);
+    }
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
@@ -199,12 +221,20 @@
         item.recycle();
         final ObjectPoolItem item2 = obtain.get();
 
-        assertSame(item, item2);
+        if (Flags.disableObjectPool()) {
+            assertNotSame(item, item2);  // Different instance.
+        } else {
+            assertSame(item, item2);
+        }
 
         // Create new object when the pool is empty.
         final ObjectPoolItem item3 = obtain.get();
 
         assertNotSame(item, item3);
+        if (Flags.disableObjectPool()) {
+            // Skip recycle if flag enabled, compare unnecessary.
+            return;
+        }
         assertEquals(item, item3);
 
         // Reset fields after recycle.
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index f05390d..ae7f465 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -32,6 +32,7 @@
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowInsets.Type.systemBars;
+import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
@@ -52,6 +53,9 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import android.annotation.NonNull;
 import android.content.Context;
 import android.graphics.Insets;
 import android.graphics.Point;
@@ -80,6 +84,8 @@
 import org.mockito.InOrder;
 import org.mockito.Mockito;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
 /**
@@ -668,30 +674,58 @@
     }
 
     @Test
-    public void testResizeAnimation_withFlagAnimateResizing() {
+    public void testResizeAnimation_withFlagAnimateResizing() throws InterruptedException {
+        final int id = ID_NAVIGATION_BAR;
+        final @InsetsType int type = navigationBars();
+        final int fromInsetsHeight = 50;
+        final int toInsetsHeight = 60;
+        final ArrayList<WindowInsets> progressList = new ArrayList<>();
+        final CountDownLatch animationEndLatch = new CountDownLatch(1);
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            final int id = ID_NAVIGATION_BAR;
-            final @InsetsType int type = navigationBars();
             final InsetsState state1 = new InsetsState();
             state1.getOrCreateSource(id, type)
                     .setVisible(true)
-                    .setFrame(0, 0, 500, 50)
+                    .setFrame(0, 0, 500, fromInsetsHeight)
                     .setFlags(FLAG_ANIMATE_RESIZING, FLAG_ANIMATE_RESIZING);
             final InsetsState state2 = new InsetsState(state1, true /* copySources */);
-            state2.peekSource(id).setFrame(0, 0, 500, 60);
+            state2.peekSource(id).setFrame(0, 0, 500, toInsetsHeight);
 
             // New insets source won't cause the resize animation.
             mController.onStateChanged(state1);
             assertEquals("There must not be resize animation.", ANIMATION_TYPE_NONE,
                     mController.getAnimationType(type));
 
+            mViewRoot.getView().setWindowInsetsAnimationCallback(
+                    new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
+                        @Override
+                        public WindowInsets onProgress(
+                                @NonNull WindowInsets insets,
+                                @NonNull List<WindowInsetsAnimation> runningAnimations) {
+                            progressList.add(insets);
+                            return insets;
+                        }
+
+                        @Override
+                        public void onEnd(@NonNull WindowInsetsAnimation animation) {
+                            animationEndLatch.countDown();
+                        }
+                    });
+
             // Changing frame of the source with FLAG_ANIMATE_RESIZING will cause the resize
             // animation.
             mController.onStateChanged(state2);
             assertEquals("There must be resize animation.", ANIMATION_TYPE_RESIZE,
                     mController.getAnimationType(type));
+
+            mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+        assertTrue("Animation must be ended.", animationEndLatch.await(3, SECONDS));
+        assertEquals("The first insets height must be the same as `fromInsetsHeight`",
+                fromInsetsHeight, progressList.get(0).getInsets(type).top);
+        assertEquals("The last insets height must be the same as `toInsetsHeight`",
+                toInsetsHeight, progressList.get(progressList.size() - 1).getInsets(type).top);
     }
 
     @Test
diff --git a/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java b/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
index 1dbb775..2b8adcb 100644
--- a/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
@@ -20,6 +20,7 @@
 import static android.view.View.MeasureSpec.EXACTLY;
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.Matchers.is;
@@ -69,6 +70,7 @@
 
     private ViewGroup mContent;
     private ViewGroup mActionBarTop;
+    private ViewGroup mActionBarView;
     private Toolbar mToolbar;
     private FakeOnApplyWindowListener mContentInsetsListener;
 
@@ -86,15 +88,22 @@
         mContentInsetsListener = new FakeOnApplyWindowListener();
         mContent.setOnApplyWindowInsetsListener(mContentInsetsListener);
 
-        mActionBarTop = new ActionBarContainer(mContext);
-        mActionBarTop.setId(com.android.internal.R.id.action_bar_container);
-        mActionBarTop.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, 20));
-        mLayout.addView(mActionBarTop);
-        mLayout.setActionBarHeight(20);
+        // mActionBarView and mToolbar are supposed to be the same view. Here makes mToolbar a child
+        // of mActionBarView is to control the height of mActionBarView. In this way, the child
+        // views of mToolbar won't affect the measurement of mActionBarView or mActionBarTop.
+        mActionBarView = new FrameLayout(mContext);
+        mActionBarView.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, 20));
 
         mToolbar = new Toolbar(mContext);
         mToolbar.setId(com.android.internal.R.id.action_bar);
-        mActionBarTop.addView(mToolbar);
+        mActionBarView.addView(mToolbar);
+
+        mActionBarTop = new ActionBarContainer(mContext);
+        mActionBarTop.setId(com.android.internal.R.id.action_bar_container);
+        mActionBarTop.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
+        mActionBarTop.addView(mActionBarView);
+        mLayout.addView(mActionBarTop);
+        mLayout.setActionBarHeight(20);
     }
 
     @Test
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 1410950..050f9b5 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -200,13 +200,3 @@
     src: "com.android.systemui.xml",
     filename_from_src: true,
 }
-
-filegroup {
-    name: "services.core.protolog.json",
-    srcs: ["services.core.protolog.json"],
-}
-
-filegroup {
-    name: "file-core.protolog.pb",
-    srcs: ["core.protolog.pb"],
-}
diff --git a/data/etc/core.protolog.pb b/data/etc/core.protolog.pb
deleted file mode 100644
index a105ba7..0000000
--- a/data/etc/core.protolog.pb
+++ /dev/null
Binary files differ
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
deleted file mode 100644
index db68f95..0000000
--- a/data/etc/services.core.protolog.json
+++ /dev/null
@@ -1,4870 +0,0 @@
-{
-  "version": "2.0.0",
-  "messages": {
-    "7286191062634870297": {
-      "message": "Binding proc %s with config %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/am\/ActivityManagerService.java"
-    },
-    "-4921282642721622589": {
-      "message": "Report configuration: %s %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityClientController.java"
-    },
-    "-1597980207704427048": {
-      "message": "Frontmost changed immersion: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IMMERSIVE",
-      "at": "com\/android\/server\/wm\/ActivityClientController.java"
-    },
-    "-6509265758887333864": {
-      "message": "Can't report activity moved to display - client not running, activityRecord=%s, displayId=%d",
-      "level": "WARN",
-      "group": "WM_DEBUG_SWITCH",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-4183059578873561863": {
-      "message": "Reporting activity moved to display, activityRecord=%s, displayId=%d, config=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SWITCH",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "7435279034964784633": {
-      "message": "Can't report activity configuration update - client not running, activityRecord=%s",
-      "level": "WARN",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-7418876140361338495": {
-      "message": "Sending new config to %s, config: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-4284934398288119962": {
-      "message": "Can't report activity position update - client not running, activityRecord=%s",
-      "level": "WARN",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "7244227111034368231": {
-      "message": "Sending position change to %s, onTop: %b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "338586566486930495": {
-      "message": "Checking theme of starting window: 0x%x",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-2561793317091789573": {
-      "message": "Translucent=%s Floating=%s ShowWallpaper=%s Disable=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "7269690012594027154": {
-      "message": "Creating SplashScreenStartingData",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-3432060893368468911": {
-      "message": "Creating SnapshotStartingData",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "5659016061937922595": {
-      "message": "Add starting %s: startingData=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "7506106334102501360": {
-      "message": "Added starting %s: startingWindow=%s startingView=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "1048048288756547220": {
-      "message": "Surface returned was null: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-1298801500610545721": {
-      "message": "Cleaning splash screen token=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-1948849214526113495": {
-      "message": "Clearing startingData for token=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "5545923784327902026": {
-      "message": "Schedule remove starting %s startingWindow=%s animate=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-5150982660941074218": {
-      "message": "startingWindow was set but startingSurface==null, couldn't remove",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-2178757341169633804": {
-      "message": "Tried to remove starting window but startingWindow was null: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "5521236266092347335": {
-      "message": "reparent: moving activity=%s to new task fragment in task=%d at %d",
-      "level": "INFO",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-9024836052864189016": {
-      "message": "moveFocusableActivityToTop: unfocusable activity=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "134255351804410010": {
-      "message": "moveFocusableActivityToTop: already on top and focused, activity=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-1058622321669556178": {
-      "message": "moveFocusableActivityToTop: set focused, activity=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "731006689098152100": {
-      "message": "moveFocusableActivityToTop: activity=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "3707721620395081349": {
-      "message": "Finishing activity r=%s, result=%d, data=%s, reason=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-3691592300155948194": {
-      "message": "Finish needs to pause: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "5813636479397543744": {
-      "message": "Finish waiting for pause of: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-2989211291975863399": {
-      "message": "destroyIfPossible: r=%s destroy returned removed=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_CONTAINERS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "3169053633576517098": {
-      "message": "Enqueueing pending finish: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "9050478058743283018": {
-      "message": "activity %s already destroying, skipping request with reason:%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "5672598223877126839": {
-      "message": "Moving to DESTROYING: %s (destroy requested)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-1834399855266808961": {
-      "message": "Moving to DESTROYED: %s (destroy skipped)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "3282063745558462269": {
-      "message": "Moving to DESTROYED: %s (no app)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "8836546031252812807": {
-      "message": "Removing activity %s, reason= %s callers=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "8348126473928520781": {
-      "message": "Moving to DESTROYED: %s (removed from history)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-8001673213497887656": {
-      "message": "activityDestroyedLocked: r=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_CONTAINERS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "587363723665813898": {
-      "message": "Removing activity %s hasSavedState=%b stateNotNeeded=%s finishing=%b state=%s callers=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-1842512343787359105": {
-      "message": "Removing app token: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "5548174277852675449": {
-      "message": "Removing app %s delayed=%b animation=%s animating=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-601582700132879947": {
-      "message": "removeAppToken: %s delayed=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "3478214322581157355": {
-      "message": "removeAppToken make exiting: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-7226216420432530281": {
-      "message": "Removing focused app token:%s displayId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "8361394136152947990": {
-      "message": "Moving existing starting %s from %s to %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-3450064502566932331": {
-      "message": "Removing starting %s from %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "8639603536400037285": {
-      "message": "Moving pending starting from %s to %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-3452055378690362514": {
-      "message": "setAppVisibility(%s, visible=%b): %s visible=%b mVisibleRequested=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "1728033820691545386": {
-      "message": "No longer Stopped: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "5062176994575790703": {
-      "message": "TRANSIT_FLAG_OPEN_BEHIND,  adding %s to mOpeningApps",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-477271988506706928": {
-      "message": "commitVisibility: %s: visible=%b visibleRequested=%b, isInTransition=%b, runningAnimation=%b, caller=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-6873410057142191118": {
-      "message": "State movement: %s from:%s to:%s reason:%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "4437231720834282527": {
-      "message": "State unchanged from:%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "926038819327785799": {
-      "message": "notifyAppResumed: wasStopped=%b %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "1734586111478674085": {
-      "message": "Resumed activity; dropping state of: %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-69666241054231397": {
-      "message": "Refreshed activity: %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "1256300416726217367": {
-      "message": "Activity paused: token=%s, timeout=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "6879640870754727133": {
-      "message": "Moving to PAUSED: %s %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "2737811012914917932": {
-      "message": "Executing finish of failed to pause activity: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-2566496855129705006": {
-      "message": "Waiting for pause to complete...",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "7498807658620137882": {
-      "message": "no-history finish of %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "3207149655622038378": {
-      "message": "Not finishing noHistory %s on stop because we're just sleeping",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-2530718588485487045": {
-      "message": "Moving to STOPPING: %s (stop requested)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-8424334454318351870": {
-      "message": "Stop failed; moving to STOPPED: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-4913512058893421188": {
-      "message": "Saving icicle of %s: %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "7613353074402340933": {
-      "message": "Moving to STOPPED: %s (stop complete)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "3981777934616509782": {
-      "message": "Scheduling idle now: forceIdle=%b immediate=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "1083992181663415298": {
-      "message": "Skipping set freeze of %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "3713860954819212080": {
-      "message": "Set freezing of %s: visible=%b freezing=%b visibleRequested=%b. %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "7696002120820208745": {
-      "message": "Clear freezing of %s force=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-8387262166329116492": {
-      "message": "No longer freezing: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-6965298896142649709": {
-      "message": "Finish starting %s: first real window is shown, no animation",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "3235691043029201724": {
-      "message": "Setting mOrientationChangeComplete=true because wtoken %s numInteresting=%d numDrawn=%d",
-      "level": "INFO",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "5991628884266137609": {
-      "message": "Creating animation bounds layer",
-      "level": "INFO",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-1836789237982086339": {
-      "message": "No thumbnail header bitmap for: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-8809523216004991008": {
-      "message": "Animation done in %s: reportedVisible=%b okToDisplay=%b okToAnimate=%b startingDisplayed=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-9178011226407552682": {
-      "message": "Setting requested orientation %s for %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-1963190756391505590": {
-      "message": "Sandbox max bounds for uid %s to bounds %s. config to never sandbox = %s, config to always sandbox = %s, letterboxing from mismatch with parent bounds = %s, has mCompatDisplayInsets = %s, should create compatDisplayInsets = %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "2612201759169917322": {
-      "message": "Pausing configuration dispatch for  %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "5153784493059555057": {
-      "message": "Resuming configuration dispatch for %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-8630021188868292872": {
-      "message": "Skipping config check (will change): %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-3976984054291875926": {
-      "message": "Configuration doesn't matter in finishing %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-1036762753077003128": {
-      "message": "Skipping config check in destroyed state %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-6543078196636665108": {
-      "message": "Skipping config check invisible: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-3588725633248053181": {
-      "message": "Ensuring correct configuration: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "4672360193194734037": {
-      "message": "Configuration & display unchanged in %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-8624278141553396410": {
-      "message": "Skipping config check for initializing activity: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "2485365009287691179": {
-      "message": "Configuration no differences in %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-8909639363543223474": {
-      "message": "Configuration changes for %s, allChanges=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-8048404379899908050": {
-      "message": "Configuration doesn't matter not running %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "4979286847769557939": {
-      "message": "Checking to restart %s: changed=0x%s, handles=0x%s, mLastReportedConfiguration=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "6779426581354721909": {
-      "message": "Config is relaunching %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "8969401915706456725": {
-      "message": "Config is relaunching invisible activity %s called by %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "328802837600679598": {
-      "message": "Moving to %s Relaunching %s callers=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "-3997125892953197985": {
-      "message": "Resumed after relaunch %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRecord.java"
-    },
-    "7211222997110112110": {
-      "message": "Refreshing activity for freeform camera compatibility treatment, activityRecord=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityRefresher.java"
-    },
-    "1665699123574159131": {
-      "message": "Starting activity when config will change = %b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityStarter.java"
-    },
-    "4748139468532105082": {
-      "message": "Updating to new configuration after starting activity.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityStarter.java"
-    },
-    "-2867366986304729": {
-      "message": "Bring to front target: %s from %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityStarter.java"
-    },
-    "-2190454940975874759": {
-      "message": "Starting new activity %s in new task %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityStarter.java"
-    },
-    "5445799252721678675": {
-      "message": "Initial config: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "-3811526397232923712": {
-      "message": "Cannot launch dream activity due to invalid state. dream component: %s packageName: %s",
-      "level": "ERROR",
-      "group": "WM_DEBUG_DREAM",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "-6981899770129924827": {
-      "message": "Dream packageName does not match active dream. Package %s does not match %s",
-      "level": "ERROR",
-      "group": "WM_DEBUG_DREAM",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "6075150529915862250": {
-      "message": "Applying new update lock state '%s' for %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IMMERSIVE",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "-4356952232698761083": {
-      "message": "setFocusedRootTask: taskId=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "301842347780487555": {
-      "message": "setFocusedTask: taskId=%d touchedActivity=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "7095858131234795548": {
-      "message": "moveTaskToFront: moving taskId=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "-4458288191054594222": {
-      "message": "Could not find task for id: %d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "-1136891560663761442": {
-      "message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "6954122272402912822": {
-      "message": "startLockTaskMode: %s",
-      "level": "WARN",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "-829638795650515884": {
-      "message": "Allowlisting %d:%s",
-      "level": "WARN",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "893763316922465955": {
-      "message": "moveRootTaskToDisplay: moving taskId=%d to displayId=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "8392804603924461448": {
-      "message": "%s: caller %d is using old GET_TASKS but privileged; allowing",
-      "level": "WARN",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "4303745325174700522": {
-      "message": "%s: caller %d does not hold REAL_GET_TASKS; limiting output",
-      "level": "WARN",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "-559595900417262876": {
-      "message": "Allowing features %d:0x%s",
-      "level": "WARN",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "2008996027621913637": {
-      "message": "Updating global configuration to: %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "-6404059840638143757": {
-      "message": "Update process config of %s to new config %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "-1123414663662718691": {
-      "message": "setVr2dDisplayId called for: %d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
-    },
-    "7803197981786977817": {
-      "message": "no-history finish of %s on new resume",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "4094852138446437211": {
-      "message": "realStartActivityLocked: Skipping start of r=%s some activities pausing...",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "1045761390992110034": {
-      "message": "Moving to PAUSED: %s (starting in paused state)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "-8529426827020190143": {
-      "message": "Launch on display check: displayId=%d callingPid=%d callingUid=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "9147909968067116569": {
-      "message": "Launch on display check: no caller info, skip check",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "4781135167649953680": {
-      "message": "Launch on display check: allow launch any on display",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "7828411869729995271": {
-      "message": "Launch on display check: disallow launch on virtual display for not-embedded activity.",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "-2215878620906309682": {
-      "message": "Launch on display check: disallow activity embedding without permission.",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "986565579776405555": {
-      "message": "Launch on display check: %s launch for userId=%d on displayId=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "-2201418325681949201": {
-      "message": "Launch on display check: allow launch for owner of the display",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "-4258279435559028377": {
-      "message": "Launch on display check: allow launch for caller present on the display",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "1496536241884839051": {
-      "message": "Stopping %s: nowVisible=%b animating=%b finishing=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "5677125188685281770": {
-      "message": "Ready to stop: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "3604633008357193496": {
-      "message": "Waiting for top state to be released by %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "3997062844427155487": {
-      "message": "Top resumed state released %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/ActivityTaskSupervisor.java"
-    },
-    "-4049608245387511746": {
-      "message": "applyAnimation:  override requested, but it is prohibited by policy.",
-      "level": "ERROR",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "-2133100418670643322": {
-      "message": "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "6121116119545820299": {
-      "message": "applyAnimation: anim=%s transit=%s Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "-8382864384468306610": {
-      "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s isEntrance=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "222576013987954454": {
-      "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM_IN_PLACE transit=%s Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "4808089291562562413": {
-      "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL transit=%s Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "-1463563572526433695": {
-      "message": "applyAnimation: anim=%s nextAppTransition=ANIM_SCALE_UP transit=%s isEntrance=%s Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "-8749850292010208926": {
-      "message": "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "5939232373291430513": {
-      "message": "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: anim=%s transit=%s isEntrance=true Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "9082776604722675018": {
-      "message": "applyAnimation: anim=%s transit=%s isEntrance=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "-1218632020771063497": {
-      "message": "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b  canCustomizeAppTransition=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "6217525691846442213": {
-      "message": "Override pending remote transitionSet=%b adapter=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "5233255302148535928": {
-      "message": "*** APP TRANSITION TIMEOUT. displayId=%d isTransitionSet()=%b mOpeningApps.size()=%d mClosingApps.size()=%d mChangingApps.size()=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransition.java"
-    },
-    "-5726018006883159788": {
-      "message": "Delaying app transition for recents animation to finish",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "6514556033257323299": {
-      "message": "**** GOOD TO GO",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "3518082157667760495": {
-      "message": "handleAppTransitionReady: displayId=%d appTransition={%s} openingApps=[%s] closingApps=[%s] transit=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "-2503124388387340567": {
-      "message": "Wallpaper animation!",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "855146509305002043": {
-      "message": "We don't support remote animation for Task with multiple TaskFragmentOrganizers.",
-      "level": "ERROR",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "59396412370137517": {
-      "message": "Override with TaskFragment remote animation for transit=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "2280055488397326910": {
-      "message": "Task=%d contains embedded TaskFragment. Disabled all input during TaskFragment remote animation.",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "-3156084190956669377": {
-      "message": "Changing app %s visible=%b performLayout=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "-8226278785414579647": {
-      "message": "getAnimationTarget in=%s, out=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "4418653408751596915": {
-      "message": "Now opening app %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "-8367738619313176909": {
-      "message": "Now closing app %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "1855459282905873641": {
-      "message": "Now changing app %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "2951634988136738868": {
-      "message": "Checking %d opening apps (frozen=%b timeout=%b)...",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "4963754906024950916": {
-      "message": "Delaying app transition for screen rotation animation to finish",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "5073676463280304697": {
-      "message": "Check opening app=%s: allDrawn=%b startingDisplayed=%b startingMoved=%b isRelaunching()=%b startingWindow=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "3437142041296647115": {
-      "message": "isFetchingAppTransitionSpecs=true",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "1461079689316480707": {
-      "message": "unknownApps is not empty: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "3579533288018884842": {
-      "message": "Organized TaskFragment is not ready= %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/AppTransitionController.java"
-    },
-    "495867940519492701": {
-      "message": "SyncGroup %d: onSurfacePlacement checking %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
-    },
-    "8452501904614439940": {
-      "message": "SyncGroup %d:  Unfinished dependencies: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
-    },
-    "616739530932040800": {
-      "message": "SyncGroup %d:  Unfinished container: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
-    },
-    "6649777898123506907": {
-      "message": "SyncGroup %d: Finished!",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
-    },
-    "4174320302463990554": {
-      "message": "PendingStartTransaction found",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
-    },
-    "6310906192788668020": {
-      "message": "SyncGroup %d: Set ready %b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
-    },
-    "-476337038362199951": {
-      "message": "SyncGroup %d: Adding to group: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
-    },
-    "-2978812352001196863": {
-      "message": "SyncGroup %d: Started %sfor listener: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
-    },
-    "-699215053676660941": {
-      "message": "No focused window, defaulting to top current task's window",
-      "level": "WARN",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "2881085074175114605": {
-      "message": "Focused window didn't have a valid surface drawn.",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "-6183551796617134986": {
-      "message": "Focus window is closing.",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "4039315468791789889": {
-      "message": "startBackNavigation currentTask=%s, topRunningActivity=%s, callbackInfo=%s, currentFocus=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "8456834061534378653": {
-      "message": "Previous Destination is Activity:%s Task:%s removedContainer:%s, backType=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "4900967164780429209": {
-      "message": "Pending back animation due to another animation is running",
-      "level": "WARN",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "-6431452312492819825": {
-      "message": "onTransactionReady, opening: %s, closing: %s, animating: %s, match: %b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "-4051770154814262074": {
-      "message": "Handling the deferred animation after transition finished",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "2077221835543623088": {
-      "message": "Setting Activity.mLauncherTaskBehind to true. Activity=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "-4442170697458371588": {
-      "message": "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "267946503010201613": {
-      "message": "onBackNavigationDone backType=%s, triggerBack=%b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
-    "-2963535976860666511": {
-      "message": "  BLACK %s: CREATE layer=%d",
-      "level": "INFO",
-      "group": "WM_SHOW_SURFACE_ALLOC",
-      "at": "com\/android\/server\/wm\/BlackFrame.java"
-    },
-    "-5633771912572750947": {
-      "message": "  BLACK %s: DESTROY",
-      "level": "INFO",
-      "group": "WM_SHOW_SURFACE_ALLOC",
-      "at": "com\/android\/server\/wm\/BlackFrame.java"
-    },
-    "8116030277393789125": {
-      "message": "Display id=%d is notified that Camera %s is open for package %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/CameraStateMonitor.java"
-    },
-    "-3774458166471278611": {
-      "message": "Display id=%d is notified that Camera %s is closed.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/CameraStateMonitor.java"
-    },
-    "-74949168947384056": {
-      "message": "Sending to proc %s new compat %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/CompatModePackages.java"
-    },
-    "-6620483833570774987": {
-      "message": "Content Recording: Unexpectedly null window container; unable to update recording for display %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "7226080178642957768": {
-      "message": "Content Recording: Display %d was already recording, but pause capture since the task is in PIP",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "-311001578548807570": {
-      "message": "Content Recording: Display %d was already recording, so apply transformations if necessary",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "2350883351096538149": {
-      "message": "Content Recording: Going ahead with updating recording for display %d to new bounds %s and\/or orientation %d and\/or surface size %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "8446758574558556540": {
-      "message": "Content Recording: Unable to update recording for display %d to new bounds %s and\/or orientation %d and\/or surface size %s, since the surface is not available.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "-4320004054011530388": {
-      "message": "Content Recording: Display %d has content (%b) so pause recording",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "5951434375221687741": {
-      "message": "Content Recording: Stop MediaProjection on virtual display %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "-3395581813971405090": {
-      "message": "Content Recording: waiting to record, so do nothing",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "6779858226066635065": {
-      "message": "Content Recording: Display %d should start recording, but don't yet since the task is in PIP",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "7051210836345306671": {
-      "message": "Content Recording: Unable to start recording for display %d since the surface is not available.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "2255758299558330282": {
-      "message": "Content Recording: Display %d has no content and is on, so start recording for state %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "2269158922723670768": {
-      "message": "Unable to retrieve window container to start recording for display %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "-2177493963028285555": {
-      "message": "Content Recording: Unable to start recording due to null token for display %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "-928577038848872043": {
-      "message": "Content Recording: Unable to retrieve task to start recording for display %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "-3564317873468917405": {
-      "message": "Content Recording: Unable to start recording due to invalid region for display %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "1100676037289065396": {
-      "message": "Content Recording: Apply transformations of shift %d x %d, scale %f x %f, crop (aka recorded content size) %d x %d for display %d; display has size %d x %d; surface has size %d x %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "2330946591287751995": {
-      "message": "Content Recording: Provided surface for recording on display %d is not present, so do not update the surface",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "7993045936648632984": {
-      "message": "Content Recording: Recorded task is removed, so stop recording on display %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "3197882223327917085": {
-      "message": "Content Recording: stopping active projection for display %d",
-      "level": "ERROR",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "4391984931064789228": {
-      "message": "Content Recording: Unable to tell MediaProjectionManagerService to stop the active projection for display %d: %s",
-      "level": "ERROR",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "6721270269112237694": {
-      "message": "Content Recording: Unable to tell MediaProjectionManagerService about resizing the active projection: %s",
-      "level": "ERROR",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "1600318776990120244": {
-      "message": "Content Recording: Unable to tell MediaProjectionManagerService about visibility change on the active projection: %s",
-      "level": "ERROR",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "-1451477179301743956": {
-      "message": "Content Recording: Unable to tell log windowing mode change: %s",
-      "level": "ERROR",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecorder.java"
-    },
-    "-225319884529912382": {
-      "message": "Content Recording: Accept session updating same display %d with granted consent, with an existing session %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecordingController.java"
-    },
-    "-5981322449150461244": {
-      "message": "Content Recording: Ignoring session on same display %d, with an existing session %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecordingController.java"
-    },
-    "4226710957373144819": {
-      "message": "Content Recording: Handle incoming session on display %d, with a pre-existing session %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecordingController.java"
-    },
-    "-1415855962859555663": {
-      "message": "Content Recording: Incoming session on display %d can't be set since it is already null; the corresponding VirtualDisplay must have already been removed.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecordingController.java"
-    },
-    "-5750232782380780139": {
-      "message": "Content Recording: Pause the recording session on display %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/ContentRecordingController.java"
-    },
-    "-8058211784911995417": {
-      "message": "DeferredDisplayUpdater: applying DisplayInfo immediately",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/DeferredDisplayUpdater.java"
-    },
-    "1944392458089872195": {
-      "message": "DeferredDisplayUpdater: partially applying DisplayInfo immediately",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/DeferredDisplayUpdater.java"
-    },
-    "8391643185322408089": {
-      "message": "DeferredDisplayUpdater: deferring DisplayInfo update",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/DeferredDisplayUpdater.java"
-    },
-    "-915675022936690176": {
-      "message": "DeferredDisplayUpdater: applied DisplayInfo after deferring",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/DeferredDisplayUpdater.java"
-    },
-    "3778139410556664218": {
-      "message": "%s skipping animation and directly setting alpha=%f, blur=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_DIMMER",
-      "at": "com\/android\/server\/wm\/DimmerAnimationHelper.java"
-    },
-    "-6357087772993832060": {
-      "message": "Starting animation on %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_DIMMER",
-      "at": "com\/android\/server\/wm\/DimmerAnimationHelper.java"
-    },
-    "-1187783168730646350": {
-      "message": "Dim animation requested: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_DIMMER",
-      "at": "com\/android\/server\/wm\/DimmerAnimationHelper.java"
-    },
-    "2230151187668089583": {
-      "message": "%s forcing orientation to %d for display id=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayArea.java"
-    },
-    "3968604152682328317": {
-      "message": "Register display organizer=%s uid=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
-    },
-    "-3066370283926570943": {
-      "message": "Don't organize or trigger events for untrusted displayId=%d",
-      "level": "WARN",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
-    },
-    "-943497726140336963": {
-      "message": "Unregister display organizer=%s uid=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
-    },
-    "5147103403966149923": {
-      "message": "Create TaskDisplayArea uid=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
-    },
-    "-1659480097203667175": {
-      "message": "Delete TaskDisplayArea uid=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
-    },
-    "-4514772405648277945": {
-      "message": "DisplayArea appeared name=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
-    },
-    "995846188225477231": {
-      "message": "DisplayArea vanished name=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
-    },
-    "-1007032390526684388": {
-      "message": "DisplayArea info changed name=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
-    },
-    "4917824058925068521": {
-      "message": "The TaskDisplayArea with %s does not exist.",
-      "level": "WARN",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/DisplayAreaPolicyBuilder.java"
-    },
-    "1432179297701477868": {
-      "message": "Looking for focus: %s, flags=%d, canReceive=%b, reason=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-1998969924927409574": {
-      "message": "findFocusedWindow: focusedApp=null using new focus @ %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-1513212297283619351": {
-      "message": "findFocusedWindow: focusedApp windows not focusable using new focus @ %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "271075236829935631": {
-      "message": "findFocusedWindow: Reached focused app=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "3066566560703920191": {
-      "message": "findFocusedWindow: Found new focus @ %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-8667452489821572603": {
-      "message": "First draw done in potential wallpaper target %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "6283995720623600346": {
-      "message": "handleNotObscuredLocked: %s was holding screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_KEEP_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "1959209522588955826": {
-      "message": "Acquiring screen wakelock due to %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_KEEP_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "352937214222086717": {
-      "message": "Releasing screen wakelock, obscured by %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_KEEP_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "2632363530212357762": {
-      "message": "Set mOrientationChanging of %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-9191821315942566105": {
-      "message": "Display id=%d is frozen while keyguard locked, return %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-74384795669614579": {
-      "message": "Display id=%d is ignoring orientation request for %d, return %d following a per-app override for %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-3395592185328682328": {
-      "message": "Display id=%d is ignoring orientation request for %d, return %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "3438870491084701232": {
-      "message": "No app or window is requesting an orientation, return %d for display id=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-1123818872155982592": {
-      "message": "findFocusedWindow: No focusable windows, display=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-2192125645150932161": {
-      "message": "Current transition prevents automatic focus change",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "3101160328044493048": {
-      "message": "Changing focus from %s to %s displayId=%d Callers=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "7634130879993688940": {
-      "message": "setFocusedApp %s displayId=%d Callers=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-4130402450005935184": {
-      "message": "SURFACE LEAK DESTROY: %s",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "4464269036743635127": {
-      "message": "setInputMethodTarget %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "4835192778854186097": {
-      "message": "create IME snapshot for %s, buff width=%s, height=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "2408509162360028352": {
-      "message": "Set IME snapshot position: (%d, %d)",
-      "level": "INFO",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "2005731931732324688": {
-      "message": "remove IME snapshot, caller=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-6495118720675662641": {
-      "message": "show IME snapshot, ime target=%s, callers=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-4354595179162289537": {
-      "message": "setInputMethodInputTarget %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "2432701541536053712": {
-      "message": "DisplayContent: boot is waiting for window of type %d to be drawn",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "5683557566110711213": {
-      "message": "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b wallEnabled=%b haveKeyguard=%b",
-      "level": "INFO",
-      "group": "WM_DEBUG_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-124113386733162358": {
-      "message": "onWindowAnimationFinished, wc=%s, type=%s, imeSnapshot=%s, target=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-1556099709547629010": {
-      "message": "ImeContainer just became organized. Reparenting under parent. imeParentSurfaceControl=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "1119786654111970652": {
-      "message": "ImeContainer just became organized but it doesn't have a parent or the parent doesn't have a surface control. mSurfaceControl=%s imeParentSurfaceControl=%s",
-      "level": "ERROR",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "7019634211809476510": {
-      "message": "Execute app transition: %s, displayId: %d Callers=%s",
-      "level": "WARN",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-3219913508985161450": {
-      "message": "Wallpaper layer changed: assigning layers + relayout",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-8165317816061445169": {
-      "message": "Content Recording: Display %d state was (%d), is now (%d), so update recording?",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "4162342172327950908": {
-      "message": "Content Recording: Attempting to mirror self on %d",
-      "level": "WARN",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "5489691866309868814": {
-      "message": "Content Recording: Found no matching mirror display for id=%d for DEFAULT_DISPLAY. Nothing to mirror.",
-      "level": "WARN",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-39794010824230928": {
-      "message": "Content Recording: Attempting to mirror %d from %d but no DisplayContent associated. Changing to mirror default display.",
-      "level": "WARN",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "6545352723229848841": {
-      "message": "Content Recording: Successfully created a ContentRecordingSession for displayId=%d to mirror content from displayId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONTENT_RECORDING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
-    "-6228339285356824882": {
-      "message": "finishScreenTurningOn: mAwake=%b, mScreenOnEarly=%b, mScreenOnFully=%b, mKeyguardDrawComplete=%b, mWindowManagerDrawComplete=%b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/DisplayPolicy.java"
-    },
-    "-6028033043540330282": {
-      "message": "Finished screen turning on...",
-      "level": "INFO",
-      "group": "WM_DEBUG_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/DisplayPolicy.java"
-    },
-    "-7427596081878257508": {
-      "message": "selectAnimation in %s: transit=%d",
-      "level": "INFO",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/DisplayPolicy.java"
-    },
-    "-6269658847003264525": {
-      "message": "**** STARTING EXIT",
-      "level": "INFO",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/DisplayPolicy.java"
-    },
-    "-6776561147903919733": {
-      "message": "Deferring rotation, rotation is paused.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "7439675997626642740": {
-      "message": "Deferring rotation, animation in progress.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "1104181226551849840": {
-      "message": "Deferring rotation, still finishing previous rotation",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "-2222079183499215612": {
-      "message": "Deferring rotation, display is not enabled.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "662988298513100908": {
-      "message": "Reverting orientation. Rotating to %s from %s rather than %s.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "-7113483678655694375": {
-      "message": "Computed rotation=%s (%d) for display id=%d based on lastOrientation=%s (%d) and oldRotation=%s (%d)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "-8809129029906317617": {
-      "message": "Display id=%d selected orientation %s (%d), got rotation %s (%d)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "6753221849083491323": {
-      "message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "-1216224951455892544": {
-      "message": "Performing post-rotate rotation after seamless rotation",
-      "level": "INFO",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "-7672508047849737424": {
-      "message": "selectRotationAnimation topFullscreen=%s rotationAnimation=%d forceJumpcut=%b",
-      "level": "INFO",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "-2426404033822048710": {
-      "message": "screenOnEarly=%b, awake=%b, currentAppOrientation=%d, orientationSensorEnabled=%b, keyguardDrawComplete=%b, windowManagerDrawComplete=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "7339471241580327852": {
-      "message": "rotationForOrientation(orient=%s (%d), last=%s (%d)); user=%s (%d) %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "5325136615007859122": {
-      "message": "Invalid surface rotation angle in config_deviceTabletopRotations: %d",
-      "level": "ERROR",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "4616480353797749295": {
-      "message": "config_deviceTabletopRotations is not defined. Half-fold letterboxing will work inconsistently.",
-      "level": "WARN",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "8852346340572084230": {
-      "message": "foldStateChanged: displayId %d, halfFoldStateChanged %s, saved rotation: %d, mUserRotation: %d, mLastSensorRotation: %d, mLastOrientation: %d, mRotation: %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "-8674269704471038429": {
-      "message": "onProposedRotationChanged, rotation=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "418312772547457152": {
-      "message": "Enabling listeners",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "4641814558273780952": {
-      "message": "Disabling listeners",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotation.java"
-    },
-    "7429138692709430028": {
-      "message": "Display id=%d is ignoring all orientation requests, camera is active and the top activity is eligible for force rotation, return %s,portrait activity: %b, is natural orientation portrait: %b.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
-    },
-    "-5176775281239247368": {
-      "message": "Reverting orientation after camera compat force rotation",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
-    },
-    "-2188976047008497712": {
-      "message": "Saving original orientation before camera compat, last orientation is %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
-    },
-    "-1534784331886673955": {
-      "message": "DisplayRotationCompatPolicy: Multi-window toast not shown as package '%s' cannot be found.",
-      "level": "ERROR",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
-    },
-    "-5121743609317543819": {
-      "message": "Display id=%d is notified that camera is closed but activity is still refreshing. Rescheduling an update.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
-    },
-    "1769752961776628557": {
-      "message": "Display id=%d is notified that Camera is closed, updating rotation.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
-    },
-    "-6949326633913532620": {
-      "message": "NOSENSOR override detected",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotationReversionController.java"
-    },
-    "-2060428960792625366": {
-      "message": "NOSENSOR override is absent: reverting",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotationReversionController.java"
-    },
-    "-4296736202875980050": {
-      "message": "Other orientation overrides are in place: not reverting",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DisplayRotationReversionController.java"
-    },
-    "7928129513685401229": {
-      "message": "Pausing rotation during drag",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DragState.java"
-    },
-    "8231481023986546563": {
-      "message": "Resuming rotation after drag",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/DragState.java"
-    },
-    "12662399232325663": {
-      "message": "DRAG %s: pos=(%d,%d)",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/DragState.java"
-    },
-    "-1797662102094201628": {
-      "message": "Attempt to transfer touch gesture with non-existent embedded window",
-      "level": "WARN",
-      "group": "WM_DEBUG_EMBEDDED_WINDOWS",
-      "at": "com\/android\/server\/wm\/EmbeddedWindowController.java"
-    },
-    "929964979835124721": {
-      "message": "Attempt to transfer touch gesture using embedded window with no associated host",
-      "level": "WARN",
-      "group": "WM_DEBUG_EMBEDDED_WINDOWS",
-      "at": "com\/android\/server\/wm\/EmbeddedWindowController.java"
-    },
-    "676191989331669410": {
-      "message": "Attempt to transfer touch gesture with host window not associated with embedded window",
-      "level": "WARN",
-      "group": "WM_DEBUG_EMBEDDED_WINDOWS",
-      "at": "com\/android\/server\/wm\/EmbeddedWindowController.java"
-    },
-    "553249487221306249": {
-      "message": "Attempt to transfer touch gesture using embedded window that has no input channel",
-      "level": "WARN",
-      "group": "WM_DEBUG_EMBEDDED_WINDOWS",
-      "at": "com\/android\/server\/wm\/EmbeddedWindowController.java"
-    },
-    "-8678904073078032058": {
-      "message": "Attempt to transfer touch gesture using a host window with no input channel",
-      "level": "WARN",
-      "group": "WM_DEBUG_EMBEDDED_WINDOWS",
-      "at": "com\/android\/server\/wm\/EmbeddedWindowController.java"
-    },
-    "-786355099910065121": {
-      "message": "IME target changed within ActivityRecord",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
-    },
-    "2634707843050913730": {
-      "message": "Schedule IME show for %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
-    },
-    "8923821958256605927": {
-      "message": "Run showImeRunner",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
-    },
-    "-3529253275087521638": {
-      "message": "call showInsets(ime) on %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
-    },
-    "7927729210300708186": {
-      "message": "showInsets(ime) was requested by different window: %s ",
-      "level": "WARN",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
-    },
-    "-6529782994356455131": {
-      "message": "abortShowImePostLayout",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
-    },
-    "-6629998049460863403": {
-      "message": "dcTarget: %s mImeRequester: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java"
-    },
-    "-8553129529717081823": {
-      "message": "Input focus has changed to %s display=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/InputMonitor.java"
-    },
-    "4027486077547983902": {
-      "message": "App %s is focused, but the window is not ready. Start a transaction to remove focus from the window of non-focused apps.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/InputMonitor.java"
-    },
-    "-8537908614386667236": {
-      "message": "Focus not requested for window=%s because it has no surface or is not focusable.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/InputMonitor.java"
-    },
-    "-6346673514571615151": {
-      "message": "Focus requested for window=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/InputMonitor.java"
-    },
-    "1522894362518893789": {
-      "message": "InsetsSource setWin %s for type %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WINDOW_INSETS",
-      "at": "com\/android\/server\/wm\/InsetsSourceProvider.java"
-    },
-    "6243049416211184258": {
-      "message": "InsetsSource Control %s for target %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WINDOW_INSETS",
-      "at": "com\/android\/server\/wm\/InsetsSourceProvider.java"
-    },
-    "-8234068212532234206": {
-      "message": "InsetsSource updateVisibility for %s, serverVisible: %s clientVisible: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WINDOW_INSETS",
-      "at": "com\/android\/server\/wm\/InsetsSourceProvider.java"
-    },
-    "-8601070090234611338": {
-      "message": "ControlAdapter startAnimation mSource: %s controlTarget: %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_WINDOW_INSETS",
-      "at": "com\/android\/server\/wm\/InsetsSourceProvider.java"
-    },
-    "-6857870589074001153": {
-      "message": "ControlAdapter onAnimationCancelled mSource: %s mControlTarget: %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_WINDOW_INSETS",
-      "at": "com\/android\/server\/wm\/InsetsSourceProvider.java"
-    },
-    "-6684172224226118673": {
-      "message": "onImeControlTargetChanged %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/InsetsStateController.java"
-    },
-    "8891808212671675155": {
-      "message": "clearLockedTasks: %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/LockTaskController.java"
-    },
-    "8970634498594714645": {
-      "message": "removeLockedTask: removed %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/LockTaskController.java"
-    },
-    "8735562128135241598": {
-      "message": "removeLockedTask: task=%s last task, reverting locktask mode. Callers=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/LockTaskController.java"
-    },
-    "737192738184050156": {
-      "message": "startLockTaskMode: Can't lock due to auth",
-      "level": "WARN",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/LockTaskController.java"
-    },
-    "-7119521978513736788": {
-      "message": "Mode default, asking user",
-      "level": "WARN",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/LockTaskController.java"
-    },
-    "-1557441750657584614": {
-      "message": "%s",
-      "level": "WARN",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/LockTaskController.java"
-    },
-    "-4314079913933391851": {
-      "message": "setLockTaskMode: Can't lock due to auth",
-      "level": "WARN",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/LockTaskController.java"
-    },
-    "3321878763832425380": {
-      "message": "setLockTaskMode: Locking to %s Callers=%s",
-      "level": "WARN",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/LockTaskController.java"
-    },
-    "-4819015209006579825": {
-      "message": "onLockTaskPackagesUpdated: removing %s mLockTaskAuth()=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/LockTaskController.java"
-    },
-    "2119751067469297845": {
-      "message": "onLockTaskPackagesUpdated: starting new locktask task=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/LockTaskController.java"
-    },
-    "3788905348567806832": {
-      "message": "startAnimation",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/NonAppWindowAnimationAdapter.java"
-    },
-    "705955074330737483": {
-      "message": "onAnimationCancelled",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/NonAppWindowAnimationAdapter.java"
-    },
-    "5106303602270682056": {
-      "message": "Adding display switch to existing collecting transition",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/PhysicalDisplaySwitchTransitionLauncher.java"
-    },
-    "-1640401313436844534": {
-      "message": "Resetting frozen recents task list reason=app touch win=%s x=%d y=%d insetFrame=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RecentTasks.java"
-    },
-    "-8803811426486764449": {
-      "message": "Setting frozen recents task list",
-      "level": "INFO",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RecentTasks.java"
-    },
-    "4040735335719974079": {
-      "message": "Resetting frozen recents task list reason=timeout",
-      "level": "INFO",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RecentTasks.java"
-    },
-    "3308140128142966415": {
-      "message": "remove RecentTask %s when finishing user %d",
-      "level": "INFO",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RecentTasks.java"
-    },
-    "-3758280623533049031": {
-      "message": "Preload recents with %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "-3365656764099317101": {
-      "message": "Updated config=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "-7165162073742035900": {
-      "message": "Real start recents",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "-3403665718306852375": {
-      "message": "startRecentsActivity(): intent=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "-8325607672707336373": {
-      "message": "No root task above target root task=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "-7278356485797757819": {
-      "message": "Moved rootTask=%s behind rootTask=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "1012359606301505741": {
-      "message": "Started intent=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "5474198007669537235": {
-      "message": "onAnimationFinished(): controller=%s reorderMode=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "3525834288436624965": {
-      "message": "onAnimationFinished(): targetRootTask=%s targetActivity=%s mRestoreTargetBehindRootTask=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "-5961176083217302671": {
-      "message": "Expected target rootTask=%s to be top most but found rootTask=%s",
-      "level": "WARN",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "-5893976429537642045": {
-      "message": "Expected target rootTask=%s to restored behind rootTask=%s but it is behind rootTask=%s",
-      "level": "WARN",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "4515487264815398694": {
-      "message": "onRootTaskOrderChanged(): rootTask=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimation.java"
-    },
-    "6530904107141905844": {
-      "message": "screenshotTask(%d): mCanceled=%b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "-3286551982713129633": {
-      "message": "setFinishTaskTransaction(%d): transaction=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "5187133389446459984": {
-      "message": "finish(%b): mCanceled=%b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "6879496555046975661": {
-      "message": "setInputConsumerEnabled(%s): mCanceled=%b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "-5305978958548091997": {
-      "message": "setHomeApp(%s)",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "-3801497203749932106": {
-      "message": "addAnimation(%s)",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "3721473589747203697": {
-      "message": "removeAnimation(%d)",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "5156407755139006078": {
-      "message": "removeWallpaperAnimation()",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "-1997836523186474317": {
-      "message": "startAnimation(): mPendingStart=%b mCanceled=%b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "-7532294363367395195": {
-      "message": "startAnimation(): Notify animation start: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "-1336603089105439710": {
-      "message": "collectTaskRemoteAnimations, target: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "2547528895718568379": {
-      "message": "createWallpaperAnimations()",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "5444932814080651576": {
-      "message": "cancelAnimation(): reason=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "622027757443954945": {
-      "message": "cleanupAnimation(): Notify animation finished mPendingAnimations=%d reorderMode=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
-    },
-    "-5444412205083968021": {
-      "message": "createAnimationAdapter(): container=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "6986037643494242400": {
-      "message": "goodToGo()",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-1902984034737899928": {
-      "message": "goodToGo(): Animation canceled already",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "6727618365838540075": {
-      "message": "goodToGo(): No apps to animate, mPendingAnimations=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-2525509826755873433": {
-      "message": "goodToGo(): onAnimationStart, transit=%s, apps=%d, wallpapers=%d, nonApps=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-1148281153370899511": {
-      "message": "startAnimation(): Notify animation start:",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "7501495587927045391": {
-      "message": "cancelAnimation(): reason=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-1424368765415574722": {
-      "message": "Starting remote animation",
-      "level": "INFO",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-2676700429940607853": {
-      "message": "%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "7094394833775573933": {
-      "message": "createAppAnimations()",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-4411070227420990074": {
-      "message": "\tAdd container=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-4411631520586057580": {
-      "message": "\tRemove container=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-7002230949892506736": {
-      "message": "createWallpaperAnimations()",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "8743612568733301175": {
-      "message": "createNonAppWindowAnimations()",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-2716313493239418198": {
-      "message": "onAnimationFinished(): mPendingAnimations=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "7221400292415257709": {
-      "message": "onAnimationFinished(): Notify animation finished:",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "7483194715776694698": {
-      "message": "\tcontainer=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "6697982664439247822": {
-      "message": "\twallpaper=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "6938838346517131964": {
-      "message": "\tnonApp=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-3880290251819699866": {
-      "message": "Finishing remote animation",
-      "level": "INFO",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "-7169244688499657832": {
-      "message": "app-onAnimationFinished(): mOuter=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "3923111589554171989": {
-      "message": "app-release(): mOuter=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "8918152561092803537": {
-      "message": "startAnimation",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
-    },
-    "1736084564226683342": {
-      "message": "Starting remote display change: from [rot = %d], to [%dx%d, rot = %d]",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/RemoteDisplayChangeController.java"
-    },
-    "-4617490621756721600": {
-      "message": "resetTaskIntendedTask: calling finishActivity on %s",
-      "level": "WARN",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java"
-    },
-    "3361857745281957526": {
-      "message": "Removing activity %s from task=%s adding to task=%s Callers=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java"
-    },
-    "3958829063955690349": {
-      "message": "Pushing next activity %s out to target's task %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java"
-    },
-    "1730793580703791926": {
-      "message": "Start pushing activity %s out to bottom task %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/ResetTargetTaskHelper.java"
-    },
-    "-8961882615747561040": {
-      "message": "Looking for task of %s in %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "8899721161806265460": {
-      "message": "Skipping task: (mismatch activity\/task) %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "6841550641928224256": {
-      "message": "Skipping %s: voice session",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "4468520936943270392": {
-      "message": "Skipping %s: different user",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "-4764624740388751268": {
-      "message": "Skipping %s: mismatch root %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "9031436623838917667": {
-      "message": "Skipping %s: mismatch activity type",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "6022828946761399284": {
-      "message": "Comparing existing cls=%s \/aff=%s to new cls=%s \/aff=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "-3413620974545388702": {
-      "message": "Found matching class!",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "-2649361982747625232": {
-      "message": "For Intent %s bringing to top: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "7046266138098744790": {
-      "message": "Found matching affinity candidate!",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "6481733556290926693": {
-      "message": "Not a match: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "3331249072840061049": {
-      "message": "New topFocusedDisplayId=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "865845626039449679": {
-      "message": "SURFACE RECOVER DESTROY: %s",
-      "level": "INFO",
-      "group": "WM_SHOW_SURFACE_ALLOC",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "-4150611780753674023": {
-      "message": "Wallpaper may change!  Adjusting",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "4177291132772627699": {
-      "message": "With display frozen, orientationChangeComplete=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "-5513616928833586179": {
-      "message": "Performing post-rotate rotation",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "-7698723716637247994": {
-      "message": "handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w.isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_KEEP_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "8621291657500572364": {
-      "message": "mUserActivityTimeout set to %d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_KEEP_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "-1418592110950138870": {
-      "message": "Looking for task of type=%s, taskAffinity=%s, intent=%s, info=%s, preferredTDA=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "2828976699481734755": {
-      "message": "No task found",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "-4405347314716558580": {
-      "message": "Create sleep token: tag=%s, displayId=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "1329131651776855609": {
-      "message": "Remove sleep token: tag=%s, displayId=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "1653728842643223887": {
-      "message": "allResumedActivitiesIdle: rootTask=%d %s not idle",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "3785779399471740019": {
-      "message": "allPausedActivitiesComplete: r=%s state=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
-    },
-    "4666728330189027178": {
-      "message": "Failed to register MediaProjectionWatcherCallback",
-      "level": "ERROR",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/ScreenRecordingCallbackController.java"
-    },
-    "8010999385228654193": {
-      "message": "  FREEZE %s: CREATE",
-      "level": "INFO",
-      "group": "WM_SHOW_SURFACE_ALLOC",
-      "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
-    },
-    "-6586462455018013482": {
-      "message": "Start rotation animation. customAnim=%s, mCurRotation=%s, mOriginalRotation=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
-    },
-    "-5825336546511998057": {
-      "message": "  FREEZE %s: DESTROY",
-      "level": "INFO",
-      "group": "WM_SHOW_SURFACE_ALLOC",
-      "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
-    },
-    "6883897856740637908": {
-      "message": "ScreenRotation still animating: type: %d\nmDisplayAnimator: %s\nmEnterBlackFrameAnimator: %s\nmRotateScreenAnimator: %s\nmScreenshotRotationAnimator: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
-    },
-    "-3943622313307983155": {
-      "message": "ScreenRotationAnimation onAnimationEnd",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
-    },
-    "-1594708154257031561": {
-      "message": "  NEW SURFACE SESSION %s",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/Session.java"
-    },
-    "2638961674625826260": {
-      "message": "  KILL SURFACE SESSION %s",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/Session.java"
-    },
-    "5380455212389185829": {
-      "message": "Removing dim surface %s on transaction %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_DIMMER",
-      "at": "com\/android\/server\/wm\/SmoothDimmer.java"
-    },
-    "-820649637734629482": {
-      "message": "Animation start delayed for %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/SurfaceAnimator.java"
-    },
-    "1371702561758591499": {
-      "message": "Animation start for %s, anim=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/SurfaceAnimator.java"
-    },
-    "-5370506662233296228": {
-      "message": "Cancelling animation restarting=%b for %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/SurfaceAnimator.java"
-    },
-    "-3045933321063743917": {
-      "message": "Reparenting to original parent: %s for %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/SurfaceAnimator.java"
-    },
-    "-855083149623806053": {
-      "message": "Reparenting to leash for %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/SurfaceAnimator.java"
-    },
-    "-2595923278763115975": {
-      "message": "  THUMBNAIL %s: CREATE",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/SurfaceFreezer.java"
-    },
-    "-8609432747982701423": {
-      "message": "Setting Intent of %s to %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/Task.java"
-    },
-    "-9155008290180285590": {
-      "message": "Setting Intent of %s to target %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TASKS",
-      "at": "com\/android\/server\/wm\/Task.java"
-    },
-    "6424220442758232673": {
-      "message": "Removing and adding activity %s to root task at top callers=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/Task.java"
-    },
-    "-1028890010429408946": {
-      "message": "addChild: %s at top.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/Task.java"
-    },
-    "38991867929900764": {
-      "message": "setLockTaskAuth: task=%s mLockTaskAuth=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_LOCKTASK",
-      "at": "com\/android\/server\/wm\/Task.java"
-    },
-    "-3401780415681318335": {
-      "message": "applyAnimationUnchecked, control: %s, task: %s, transit: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RECENTS_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/Task.java"
-    },
-    "4037728373502324767": {
-      "message": "resumeNextFocusableActivityWhenRootTaskIsEmpty: %s, go home",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/Task.java"
-    },
-    "-2261257617975724313": {
-      "message": "Adding activity %s to task %s callers: %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/Task.java"
-    },
-    "7378236902389922467": {
-      "message": "App is requesting an orientation, return %d for display id=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
-    },
-    "2005499548343677845": {
-      "message": "No app is requesting an orientation, return %d for display id=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/TaskDisplayArea.java"
-    },
-    "646076184396185067": {
-      "message": "App died while pausing: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-7596917112222697106": {
-      "message": "Waiting for screen on due to %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-8472961767591168851": {
-      "message": "Sleep needs to pause %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-1472885369931482317": {
-      "message": "Sleep still waiting to pause %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-2693016397674039814": {
-      "message": "Sleep still need to stop %d activities",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "8892147402270850613": {
-      "message": "resumeTopActivity: Skip resume: some activity pausing.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "958293038551087087": {
-      "message": "resumeTopActivity: Top activity resumed %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "4340810061306869942": {
-      "message": "resumeTopActivity: Going to sleep and all paused",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-7681635901109618685": {
-      "message": "resumeTopActivity: Pausing %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-3463034909521330970": {
-      "message": "resumeTopActivity: Skip resume: need to start pausing",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-2264725269594226780": {
-      "message": "resumeTopActivity: Top activity resumed (dontWaitForPause) %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-8359248677489986541": {
-      "message": "Moving to RESUMED: %s (in existing)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-8483536760290526299": {
-      "message": "resumeTopActivity: Resumed %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-4911500660485375799": {
-      "message": "Resume failed; resetting state to %s: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "3723891427717889172": {
-      "message": "resumeTopActivity: Restarting %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "1529152423206006904": {
-      "message": "startPausing: taskFrag =%s mResumedActivity=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "136971836458873178": {
-      "message": "Moving to PAUSING: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-208996201631695262": {
-      "message": "Auto-PIP allowed, requesting PIP mode via requestStartTransition(): %s, willAutoPip: %b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-4123447037565780632": {
-      "message": "Auto-PIP allowed, entering PIP mode directly: %s, didAutoPip: %b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-3710776151994843320": {
-      "message": "Key dispatch not paused for screen off",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "8543865526552245064": {
-      "message": "Activity not running or entered PiP, resuming next.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "1917394294249960915": {
-      "message": "Enqueueing pending pause: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-8936154984341817384": {
-      "message": "Complete pause: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "4971958459026584561": {
-      "message": "Executing finish of activity: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-7113165071559345173": {
-      "message": "Enqueue pending stop if needed: %s wasStopping=%b visibleRequested=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-3777748052684097788": {
-      "message": "App died during pause, not stopping: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STATES",
-      "at": "com\/android\/server\/wm\/TaskFragment.java"
-    },
-    "-2808577027789344626": {
-      "message": "TaskFragment appeared name=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "-3582112419663037270": {
-      "message": "TaskFragment vanished name=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "3294593748816836746": {
-      "message": "TaskFragment info changed name=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "5007230330523630579": {
-      "message": "TaskFragment parent info changed name=%s parentTaskId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "6475066005515810081": {
-      "message": "Sending TaskFragment error exception=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "-7893265697482064583": {
-      "message": "Activity=%s reparent to taskId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "7048981249808281819": {
-      "message": "Defer transition id=%d for TaskFragmentTransaction=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "-1315509853595025526": {
-      "message": "Deferred transition id=%d has been continued before the TaskFragmentTransaction=%s is finished",
-      "level": "WARN",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "7421521217481553621": {
-      "message": "Continue transition id=%d for TaskFragmentTransaction=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "3509684748201636981": {
-      "message": "Register task fragment organizer=%s uid=%d pid=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "-6777461169027010201": {
-      "message": "Unregister task fragment organizer=%s uid=%d pid=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "1327792561585467865": {
-      "message": "Register remote animations for organizer=%s uid=%d pid=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "-2524361347368208519": {
-      "message": "Unregister remote animations for organizer=%s uid=%d pid=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskFragmentOrganizerController.java"
-    },
-    "-6181189296332065162": {
-      "message": "Task appeared taskId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "6535296991997214354": {
-      "message": "Task vanished taskId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "-6638141753476761854": {
-      "message": "Task info changed taskId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "-8100069665346602959": {
-      "message": "Task back pressed on root taskId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "-610138383571469481": {
-      "message": "Register task organizer=%s uid=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "1705860547080436016": {
-      "message": "Unregister task organizer=%s uid=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "-2286607251115721394": {
-      "message": "createRootTask unknown displayId=%d",
-      "level": "ERROR",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "8466395828406204368": {
-      "message": "Create root task displayId=%d winMode=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "6867170298997192615": {
-      "message": "Delete root task display=%d winMode=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "-4296644831871159510": {
-      "message": "Set intercept back pressed on root=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "-558727273888268534": {
-      "message": "Restart top activity process of Task taskId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "-7064081458956324316": {
-      "message": "Update camera compat control state to %s for taskId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
-    },
-    "3007492640459931179": {
-      "message": "Pausing rotation during re-position",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/TaskPositioner.java"
-    },
-    "5478864901888225320": {
-      "message": "Resuming rotation after re-position",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/TaskPositioner.java"
-    },
-    "-2700498872917476567": {
-      "message": "Starting a Recents transition which can be parallel.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-8676279589273455859": {
-      "message": "Transition %d: Set %s as transient-launch",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "2734227875286695843": {
-      "message": "Override sync-method for %s because seamless rotating",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "2808217645990556209": {
-      "message": "Starting Transition %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-4672522645315112127": {
-      "message": "Collecting in transition %d: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "65881049096729394": {
-      "message": " Creating Ready-group for Transition %d with root=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "1101215730201607371": {
-      "message": "Existence Changed in transition %d: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-3942072270654590479": {
-      "message": "Set transition ready=%b %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-4688704756793656554": {
-      "message": "  Commit activity becoming invisible: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "1817207111271920503": {
-      "message": "  Skipping post-transition snapshot for task %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-2960171012238790176": {
-      "message": "  Commit wallpaper becoming invisible: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "1230784960534033968": {
-      "message": "Aborting Transition: %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-892865733969888022": {
-      "message": "Force Playing Transition: %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-1354622424895965634": {
-      "message": "#%d: Met condition: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-5350671621840749173": {
-      "message": "Calling onTransitionReady: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "1830385055586991567": {
-      "message": "Apply and finish immediately because player is disabled for transition #%d .",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-758501334967569539": {
-      "message": "      SKIP: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-2714847784842612086": {
-      "message": "      SKIP: is wallpaper",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "1855461834864671586": {
-      "message": "      check sibling %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-6292043690918793069": {
-      "message": "        SKIP: sibling is visible but not part of transition",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "7897657428993391672": {
-      "message": "        unrelated invisible sibling %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "3873493605120555608": {
-      "message": "        sibling is a participant with mode %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "7665553560859456426": {
-      "message": "          SKIP: common mode mismatch. was %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-8916099332247176657": {
-      "message": "    checking %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-6818387694968032301": {
-      "message": "      SKIP: its sibling was rejected",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-7326702978448933012": {
-      "message": "        keep as target %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "943961036184959431": {
-      "message": "        remove from targets %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "841543868388687804": {
-      "message": "      CAN PROMOTE: promoting to parent %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "743586316159041023": {
-      "message": "Start calculating TransitionInfo based on participants: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-7247430213293162757": {
-      "message": "  Rejecting as detached: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-5811837191094192313": {
-      "message": "  Rejecting as no-op: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-1153926883525904120": {
-      "message": "  Initial targets: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-9191328656870721224": {
-      "message": "  Final targets: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-2971560715211489406": {
-      "message": " Add condition %s for #%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "7631061720069910622": {
-      "message": " Met condition %s for #%d (%d left)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-4770394322045550928": {
-      "message": " Setting Ready-group to %b. group=%s from %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "6039132370452820927": {
-      "message": " Setting allReady override",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-3263748870548668913": {
-      "message": " allReady query: used=%b override=%b defer=%d states=[%s]",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "2699903406935781477": {
-      "message": "Screenshotting %s [%s]",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/Transition.java"
-    },
-    "-233096875591058130": {
-      "message": "Creating Transition: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "2154694726162725342": {
-      "message": "Start collecting in Transition: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-4546322749928357965": {
-      "message": "Registering transition player %s over %d other players",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-4250307779892136611": {
-      "message": "Registering transition player %s ",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "3242771541905259983": {
-      "message": "Attempt to unregister transition player %s but it isn't registered",
-      "level": "WARN",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "3691912781236221027": {
-      "message": "Unregistering active transition player %s at index=%d leaving %d in stack",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-2879980134100946679": {
-      "message": "Unregistering transition player %s at index=%d leaving %d in stack",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-4235778637051052061": {
-      "message": "Disabling player for transition #%d because display isn't enabled yet",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "4005704720444963797": {
-      "message": "Requesting StartTransition: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-6030030735787868329": {
-      "message": "Finish Transition: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-1611886029896664304": {
-      "message": "Moving #%d from collecting to waiting.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-7097461682459496366": {
-      "message": "Playing #%d in parallel on track #%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-7364464699035275052": {
-      "message": "Marking #%d animation as SYNC.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-5509640937151643757": {
-      "message": "Queueing transition: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-2741593375634604522": {
-      "message": "Queueing legacy sync-set: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "-5051723169912572741": {
-      "message": "%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "4281568181321808508": {
-      "message": "    startWCT=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "5141999957143860655": {
-      "message": "    info=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS_MIN",
-      "at": "com\/android\/server\/wm\/TransitionController.java"
-    },
-    "3445530300764535903": {
-      "message": "unregister failed, couldn't find deathRecipient for %s with id=%d",
-      "level": "ERROR",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "-6140852484700685564": {
-      "message": "Registering listener=%s with id=%d for window=%s with %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "3691097873058247482": {
-      "message": "Unregistering listener=%s with id=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "6408851516381868623": {
-      "message": "Checking %d windows",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "7718187745767272532": {
-      "message": "Skipping %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "-1135667737459933313": {
-      "message": "coveredRegionsAbove updated with %s frame:%s region:%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "854487339271667012": {
-      "message": "checkIfInThreshold fractionRendered=%f alpha=%f currTimeMs=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "-2248576188205088843": {
-      "message": "lastState=%s newState=%s alpha=%f minAlpha=%f fractionRendered=%f minFractionRendered=%f",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "6236170793308011579": {
-      "message": "Adding untrusted state listener=%s with id=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "5405816744363636527": {
-      "message": "Adding trusted state listener=%s with id=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "-5162728346383863020": {
-      "message": "computeFractionRendered: visibleRegion=%s screenBounds=%s contentSize=%s scale=%f,%f",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "898769258643799441": {
-      "message": "fractionRendered scale=%f",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "-455501334697331596": {
-      "message": "fractionRendered boundsOverSource=%f",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_TPL",
-      "at": "com\/android\/server\/wm\/TrustedPresentationListenerController.java"
-    },
-    "1964980935866463086": {
-      "message": "\tWallpaper of display=%s is not visible",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
-    },
-    "8131665298937888044": {
-      "message": "startAnimation",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
-    },
-    "8030745595351281943": {
-      "message": "onAnimationCancelled",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
-      "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
-    },
-    "-5254364639040552989": {
-      "message": "Hiding wallpaper %s from %s target=%s prev=%s callers=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "-6856158722649737204": {
-      "message": "Waiting for offset complete...",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "-5966696477376431672": {
-      "message": "Offset complete!",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "4198834090919802045": {
-      "message": "Timeout waiting for wallpaper to offset: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "-3477087868568520027": {
-      "message": "No longer animating wallpaper targets!",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "-3751289048117070874": {
-      "message": "New wallpaper target: %s prevTarget: %s caller=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "5625223922466895079": {
-      "message": "New animation: %s old animation: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "7634524672408826188": {
-      "message": "Animating wallpapers: old: %s hidden=%b new: %s hidden=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "-4345077332231178044": {
-      "message": "Old wallpaper still the target.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "257349083882992098": {
-      "message": "updateWallpaperTokens requestedVisibility=%b on keyguardLocked=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "7408402065665963407": {
-      "message": "Wallpaper at display %d - visibility: %b, keyguardLocked: %b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "-8598497865499265448": {
-      "message": "Wallpaper target=%s prev=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "-5402010429724738603": {
-      "message": "Wallpaper should be visible but has not been drawn yet. mWallpaperDrawState=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "4151327328872447804": {
-      "message": "New home screen wallpaper: %s, prev: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "6943105284590482059": {
-      "message": "New lock\/shared screen wallpaper: %s, prev: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperController.java"
-    },
-    "-7936547457136708587": {
-      "message": "Wallpaper token %s visible=%b",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WALLPAPER",
-      "at": "com\/android\/server\/wm\/WallpaperWindowToken.java"
-    },
-    "7214407534407465113": {
-      "message": "commitVisibility: %s: visible=%b mVisibleRequested=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/WallpaperWindowToken.java"
-    },
-    "-5360147928134631656": {
-      "message": ">>> OPEN TRANSACTION animate",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowAnimator.java"
-    },
-    "-3993586364046165922": {
-      "message": "<<< CLOSE TRANSACTION animate",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowAnimator.java"
-    },
-    "-5231580410559054259": {
-      "message": "%s is requesting orientation %d (%s)",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "6949303417875346627": {
-      "message": "Starting animation on %s: type=%d, anim=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "-8730310387200541562": {
-      "message": "applyAnimation: transition animation is disabled or skipped. container=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "2363818604357955690": {
-      "message": "applyAnimation: transit=%s, enter=%b, wc=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "2262119454684034794": {
-      "message": "applyAnimation: container=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "5857165752965610762": {
-      "message": "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s surfaceInsets=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "9017113545720281233": {
-      "message": "Loaded animation %s for %s, duration: %d, stack=%s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "5272307326252759722": {
-      "message": "onSyncFinishedDrawing %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "-8311909671193661340": {
-      "message": "setSyncGroup #%d on %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "-3871009616397322067": {
-      "message": "finishSync cancel=%b for %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "-4267530270533009730": {
-      "message": "Error sending initial configuration change to WindowContainer overlay",
-      "level": "ERROR",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "5179630990780610966": {
-      "message": "Error sending initial insets change to WindowContainer overlay",
-      "level": "ERROR",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowContainer.java"
-    },
-    "-131600102855790053": {
-      "message": "  THUMBNAIL %s: CREATE",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowContainerThumbnail.java"
-    },
-    "2163930285157267092": {
-      "message": "The listener does not exist.",
-      "level": "INFO",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowContextListenerController.java"
-    },
-    "6139364662459841509": {
-      "message": "Could not register window container listener token=%s, container=%s",
-      "level": "ERROR",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowContextListenerController.java"
-    },
-    "3655576047584951173": {
-      "message": "Window Manager Crash %s",
-      "level": "WTF",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-3029436704707366221": {
-      "message": "Attempted to add window with a client %s that is dead. Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1303710477998542095": {
-      "message": "Attempted to add window to a display that does not exist: %d. Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "8039410207325630747": {
-      "message": "Attempted to add window to a display for which the application does not have access: %d.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-3451016577701561221": {
-      "message": "Window %s is already added",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "7245919222637411747": {
-      "message": "Attempted to add window with token that is not a window: %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-8579305050440451727": {
-      "message": "Attempted to add window with token that is a sub-window: %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1075040941127814341": {
-      "message": "Attempted to add private presentation window to a non-private display.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "7599690046549866326": {
-      "message": "Attempted to add presentation window to a non-suitable display.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-2546047231197102533": {
-      "message": "Trying to add window with invalid user=%d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "3713874359318494804": {
-      "message": "Attempted to add window with non-application token .%s Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-6507147599943157469": {
-      "message": "Attempted to add window with exiting application token .%s Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1409483453189443362": {
-      "message": "Attempted to add starting window to token with already existing starting window",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1806907994917883598": {
-      "message": "Attempted to add starting window to token but already cleaned",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-5450131464624918523": {
-      "message": "Attempted to add input method window with bad token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-6484128707849211138": {
-      "message": "Attempted to add voice interaction window with bad token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "7768591536609704658": {
-      "message": "Attempted to add wallpaper window with bad token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "7497077135474110999": {
-      "message": "Attempted to add Accessibility overlay window with bad token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "8957851092580119204": {
-      "message": "Attempted to add a toast window with bad token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1945746969404688952": {
-      "message": "Attempted to add QS dialog window with bad token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "3419934373251134563": {
-      "message": "Non-null activity for system window of rootType=%d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1161056447389155729": {
-      "message": "Adding more than one toast window for UID at a time.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-7518552252637236411": {
-      "message": "Window types in WindowContext and LayoutParams.type should match! Type from LayoutParams is %d, but type from WindowContext is %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-6055615852717459196": {
-      "message": "addWindow: %s startingWindow=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-2829980616540274784": {
-      "message": "addWindow: New client %s: window=%s Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-7315179333005789167": {
-      "message": "Attempted to add application window with unknown token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-7547709658889961930": {
-      "message": "Attempted to add input method window with unknown token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "3009864422591182484": {
-      "message": "Attempted to add voice interaction window with unknown token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-2639914438438144071": {
-      "message": "Attempted to add wallpaper window with unknown token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-7529563697886120786": {
-      "message": "Attempted to add QS dialog window with unknown token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "4253401518117961686": {
-      "message": "Attempted to add Accessibility overlay window with unknown token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "5834230650841873680": {
-      "message": "Attempted to add a toast window with unknown token %s.  Aborting.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "5265273548711408921": {
-      "message": "postWindowRemoveCleanupLocked: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-3847568084407666790": {
-      "message": "Final remove of window: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_MOVEMENT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "1419572818243106725": {
-      "message": "Removing %s from %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "8312693933819247897": {
-      "message": "Relayout %s: oldVis=%d newVis=%d. %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "8319702790708803735": {
-      "message": "Exception thrown when creating surface for client %s (%s). %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "212929172223901460": {
-      "message": "Relayout of %s: focusMayChange=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-255991894956556845": {
-      "message": "Set animatingExit: reason=startExitingAnimation\/%s win=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "6555160513135851764": {
-      "message": "OUT SURFACE %s: copied",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-196459205494031145": {
-      "message": "Failed to create surface control for %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-5512006943172316333": {
-      "message": "finishDrawingWindow: %s mDrawState=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-2577785761087081584": {
-      "message": "Permission Denial: %s from pid=%d, uid=%d requires %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "4547566763172245740": {
-      "message": "addWindowToken: Attempted to add token: %s for non-exiting displayId=%d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-972832559831959983": {
-      "message": "addWindowToken: Attempted to add binder token: %s for already created window token: %s displayId=%d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "8372202339190060748": {
-      "message": "attachWindowContextToDisplayArea: calling from non-existing process pid=%d uid=%d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "1904306629015452865": {
-      "message": "attachWindowContextToDisplayArea: trying to attach to a non-existing display:%d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-6845859096032432107": {
-      "message": "attachWindowContextToDisplayContent: calling from non-existing process pid=%d uid=%d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "1473791807245791604": {
-      "message": "attachWindowContextToWindowToken: calling from non-existing process pid=%d uid=%d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-2056866750160555704": {
-      "message": "Then token:%s is invalid. It might be removed",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1045756671264607145": {
-      "message": "removeWindowToken: Attempted to remove token: %s for non-exiting displayId=%d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "874825105313641295": {
-      "message": "removeWindowToken: Attempted to remove non-existing token: %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "5128669121055635771": {
-      "message": "moveWindowTokenToDisplay: Attempted to move token: %s to non-exiting displayId=%d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "6497954191906583839": {
-      "message": "moveWindowTokenToDisplay: Attempted to move non-existing token: %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "2865882097969084039": {
-      "message": "moveWindowTokenToDisplay: Cannot move to the original display for token: %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-886583195545553099": {
-      "message": "Not moving display (displayId=%d) to top. Top focused displayId=%d. Reason: FLAG_STEAL_TOP_FOCUS_DISABLED",
-      "level": "INFO",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1557387535886241553": {
-      "message": "enableScreenAfterBoot: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-6467850045030187736": {
-      "message": "enableScreenIfNeededLocked: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "179762478329442868": {
-      "message": "***** BOOT TIMEOUT: forcing display enabled",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-3417569256875279779": {
-      "message": "performEnableScreen: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-7516915153725082358": {
-      "message": "performEnableScreen: Waited %dms for all windows to be drawn",
-      "level": "INFO",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1541244520024033685": {
-      "message": "performEnableScreen: Waiting for anim complete",
-      "level": "INFO",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "2670150656385758826": {
-      "message": "performEnableScreen: bootFinished() failed.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "530628508916855904": {
-      "message": "******************** ENABLING SCREEN!",
-      "level": "INFO",
-      "group": "WM_DEBUG_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "5477889324043875194": {
-      "message": "Notified TransitionController that the display is ready.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-2061779801633179448": {
-      "message": "checkBootAnimationComplete: Waiting for anim complete",
-      "level": "INFO",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-8177456840019985809": {
-      "message": "checkBootAnimationComplete: Animation complete!",
-      "level": "INFO",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-333924817004774456": {
-      "message": "showBootMessage: msg=%s always=%b mAllowBootMessages=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "2994810644159608200": {
-      "message": "hideBootMessagesLocked: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-6625203651195752178": {
-      "message": "freezeDisplayRotation: current rotation=%d, new rotation=%d, caller=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "8988910478484254861": {
-      "message": "thawRotation: mRotation=%d, caller=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "7261084872394224738": {
-      "message": "updateRotationUnchecked: alwaysSendConfiguration=%b forceRelayout=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "8664813170125714536": {
-      "message": "View server did not start",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-8019372496359375449": {
-      "message": "Could not send command %s with parameters %s. %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "1893303527772009363": {
-      "message": "Devices still not ready after waiting %d milliseconds before attempting to detect safe mode.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-3652974372240081071": {
-      "message": "SAFE MODE ENABLED (menu=%d s=%d dpad=%d trackball=%d)",
-      "level": "INFO",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "4945624619344146947": {
-      "message": "SAFE MODE not enabled",
-      "level": "INFO",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-3428027271337724889": {
-      "message": "Focus changing: %s -> %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "1624328195833150047": {
-      "message": "App freeze timeout expired.",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "5830724144971462783": {
-      "message": "Timeout waiting for drawn: undrawn=%s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-2240705227895260140": {
-      "message": "CHECK_IF_BOOT_ANIMATION_FINISHED:",
-      "level": "INFO",
-      "group": "WM_DEBUG_BOOT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "8641557333789260779": {
-      "message": "FORCED DISPLAY SIZE: %dx%d",
-      "level": "INFO",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "3781141652793604337": {
-      "message": "FORCED DISPLAY SCALING DISABLED",
-      "level": "INFO",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "4117606810523219596": {
-      "message": "Failed looking up window session=%s callers=%s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "1233670725456443473": {
-      "message": "Changing surface while display frozen: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1716033239040181528": {
-      "message": "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d",
-      "level": "INFO",
-      "group": "WM_DEBUG_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-4609828204247499633": {
-      "message": "Aborted waiting for drawn: %s",
-      "level": "WARN",
-      "group": "WM_DEBUG_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-7561054602203220590": {
-      "message": "Window drawn win=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "2809030008663191766": {
-      "message": "All windows drawn!",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_SCREEN_ON",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1615905649072328410": {
-      "message": "startFreezingDisplayLocked: exitAnim=%d enterAnim=%d called by %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "4565793239453546297": {
-      "message": "stopFreezingDisplayLocked: Returning waitingForConfig=%b, waitingForRemoteDisplayChange=%b, mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, mClientFreezingScreen=%b, mOpeningApps.size()=%d",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-6877112251967196129": {
-      "message": "stopFreezingDisplayLocked: Unfreezing now",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "721393258715103117": {
-      "message": "%s",
-      "level": "INFO",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-5706083447992207254": {
-      "message": "**** Dismissing screen rotation animation",
-      "level": "INFO",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "2233371241933584073": {
-      "message": "Performing post-rotate rotation",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "1010635158502326025": {
-      "message": "unable to call receiver for empty keyboard shortcuts",
-      "level": "ERROR",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "1278715281433572858": {
-      "message": "Bad requesting window %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-6186782212018913664": {
-      "message": "Invalid displayId for requestScrollCapture: %d",
-      "level": "ERROR",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "51378282333944649": {
-      "message": "requestScrollCapture: caught exception dispatching to window.token=%s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-8972916676375201577": {
-      "message": "requestScrollCapture: caught exception dispatching callback: %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-1875125162673622728": {
-      "message": "Attempted to get windowing mode of a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "3938331948687900219": {
-      "message": "Attempted to set windowing mode to a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "4200292050699107329": {
-      "message": "Attempted to get remove mode of a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-5574580669790275797": {
-      "message": "Attempted to set remove mode to a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "525945815055875796": {
-      "message": "Attempted to get flag of a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "8186524992939307511": {
-      "message": "Attempted to set flag to a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-600035824255550632": {
-      "message": "Attempted to get system decors flag of a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "3056518663346732662": {
-      "message": "Attempted to set system decors flag to a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "5177195624625618567": {
-      "message": "Attempted to get IME policy of a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "3932627933834459400": {
-      "message": "Attempted to set IME policy to a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "5770211341769258866": {
-      "message": "setWallpaperShowWhenLocked: non-existent wallpaper token: %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "698926505694016512": {
-      "message": "setWallpaperCropHints: non-existent wallpaper token: %s",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-7428028317216329062": {
-      "message": "hideIme target: %s ",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "1006302987953651112": {
-      "message": "hideIme Control target: %s ",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_IME",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "5213970642134448962": {
-      "message": "Attempted to get home support flag of a display that does not exist: %d",
-      "level": "WARN",
-      "group": "WM_ERROR",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-2065144681579661392": {
-      "message": "onPointerDownOutsideFocusLocked called on %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-7394143854567081754": {
-      "message": "grantEmbeddedWindowFocus win=%s dropped focus so setting focus to null since no candidate was found",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "-6056928081282320632": {
-      "message": "grantEmbeddedWindowFocus win=%s grantFocus=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
-    "6110791601270766802": {
-      "message": "TaskFragmentTransaction changes are not collected in transition because there is an ongoing sync for applySyncTransaction().",
-      "level": "WARN",
-      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/WindowOrganizerController.java"
-    },
-    "9200403125156001641": {
-      "message": "Apply window transaction, syncId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/WindowOrganizerController.java"
-    },
-    "433446585990132440": {
-      "message": "Set sync ready, syncId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/WindowOrganizerController.java"
-    },
-    "6552038620140878489": {
-      "message": "Transaction ready, syncId=%d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_WINDOW_ORGANIZER",
-      "at": "com\/android\/server\/wm\/WindowOrganizerController.java"
-    },
-    "-4629255026637000251": {
-      "message": "Sending to proc %s new config %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_CONFIGURATION",
-      "at": "com\/android\/server\/wm\/WindowProcessController.java"
-    },
-    "-7237767461056267619": {
-      "message": "%s: Setting back callback %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "8135615413833185273": {
-      "message": "Adding %s to %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "8842744325264128950": {
-      "message": "Resize reasons for w=%s:  %s configChanged=%b didFrameInsetsChange=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_RESIZE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-8636590597069784069": {
-      "message": "Resizing window %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_RESIZE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-2710188685736986208": {
-      "message": "Orientation not waiting for draw in %s, surfaceController %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "5236278969232209904": {
-      "message": "onMovedByResize: Moving %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RESIZE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "7646042751617940718": {
-      "message": "Set animatingExit: reason=onAppVisibilityChanged win=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "1783521309242112490": {
-      "message": "onResize: Resizing %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_RESIZE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "1351053513466395411": {
-      "message": "WS.removeImmediately: %s Already removed...",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "3927343382258792268": {
-      "message": "removeIfPossible: %s callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-4831815184899821371": {
-      "message": "Starting window removed %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-5803097884846965819": {
-      "message": "Remove client=%x, surfaceController=%s Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-2547748024041128829": {
-      "message": "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b mHasSurface=%b surfaceShowing=%b animating=%b app-animation=%b mDisplayFrozen=%b callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "7789778354950913237": {
-      "message": "Set animatingExit: reason=remove\/applyAnimation win=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-4143841388126586338": {
-      "message": "Not removing %s due to exit animation",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "4419190702135590390": {
-      "message": "Set animatingExit: reason=remove\/isAnimating win=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-6167820560758523840": {
-      "message": "setAnimationLocked: setting mFocusMayChange true",
-      "level": "INFO",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-208079497999140637": {
-      "message": "WindowState.hideLw: setting mFocusMayChange true",
-      "level": "INFO",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "8812513438749898553": {
-      "message": "set mOrientationChanging of %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-2964267636425934067": {
-      "message": "win=%s destroySurfaces: appStopped=%b win.mWindowRemovalAllowed=%b win.mRemoveOnExit=%b",
-      "level": "ERROR",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "7336961102428192483": {
-      "message": "Clear animatingExit: reason=destroySurface win=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-6920306331987525705": {
-      "message": "Reporting new frame to %s: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_RESIZE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "2714651498627020992": {
-      "message": "Resizing %s WITH DRAW PENDING",
-      "level": "INFO",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-5755338358883139945": {
-      "message": "Requested redraw for orientation change: %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-5211036212243647844": {
-      "message": "notifyInsetsChanged for %s ",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WINDOW_INSETS",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-3186229270467822891": {
-      "message": "notifyInsetsControlChanged for %s ",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_WINDOW_INSETS",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-7413136364930452718": {
-      "message": "performShowLocked: mDrawState=HAS_DRAWN in %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "7624470121297688739": {
-      "message": "shouldWaitAnimatingExit: isTransition: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "810267895099109466": {
-      "message": "shouldWaitAnimatingExit: isAnimating: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-1760879391350377377": {
-      "message": "shouldWaitAnimatingExit: isWallpaperTarget: %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "272960397873328729": {
-      "message": "Clear window stuck on animatingExit status: %s",
-      "level": "WARN",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-1007526574020149845": {
-      "message": "onExitAnimationDone in %s: exiting=%b remove=%b selfAnimating=%b anim=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "1738645946553610841": {
-      "message": "Exit animation finished in %s: remove=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-7737516306844862315": {
-      "message": "Clear animatingExit: reason=exitAnimationDone win=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-3153130647145726082": {
-      "message": "Clear animatingExit: reason=clearAnimatingFlags win=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-5202247309108694583": {
-      "message": "Clear animatingExit: reason=relayoutVisibleWindow win=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "6291563604478341956": {
-      "message": "Setting move animation on %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-5774445199273871848": {
-      "message": "Preparing to sync a window that was already in the sync, so try dropping buffer. win=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "8097934579596343476": {
-      "message": "Got a buffer for request id=%d but latest request is id=%d. Since the buffer is out-of-date, drop it. win=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_SYNC_ENGINE",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "8269653477215188641": {
-      "message": "SURFACE isSecure=%b: %s",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
-    "-1495677286613044867": {
-      "message": "Animation done in %s: exiting=%b, reportedVisible=%b",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "3436877176443058520": {
-      "message": "Finishing drawing window %s: mDrawState=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "345647873457403698": {
-      "message": "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_DRAW",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "-2385558637577093121": {
-      "message": "Draw state now committed in %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_STARTING_WINDOW",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "-3490933626936411542": {
-      "message": "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW %s",
-      "level": "INFO",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "-6088246515441976339": {
-      "message": "createSurface %s: mDrawState=DRAW_PENDING",
-      "level": "INFO",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "2353125758087345363": {
-      "message": "  CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x \/ %s",
-      "level": "INFO",
-      "group": "WM_SHOW_SURFACE_ALLOC",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "-4491856282178275074": {
-      "message": "SURFACE DESTROY: %s. %s",
-      "level": "INFO",
-      "group": "WM_SHOW_SURFACE_ALLOC",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "8602950884833508970": {
-      "message": "Orientation change skips hidden %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "-5079712802591263622": {
-      "message": "SURFACE controller=%s alpha=%f HScale=%f, VScale=%f: %s",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "-2824875917893878016": {
-      "message": "Orientation continue waiting for draw in %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "7457181879495900576": {
-      "message": "Orientation change complete in %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ORIENTATION",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "-5668794009329913533": {
-      "message": "applyAnimation: win=%s anim=%d attr=0x%x a=%s transit=%d type=%d isEntrance=%b Callers %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ANIM",
-      "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
-    },
-    "-2055407587764455051": {
-      "message": "SURFACE HIDE ( %s ): %s",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
-    },
-    "-5854683348829455340": {
-      "message": "Destroying surface %s called by %s",
-      "level": "INFO",
-      "group": "WM_SHOW_SURFACE_ALLOC",
-      "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
-    },
-    "7813672046338784579": {
-      "message": "SURFACE isOpaque=%b: %s",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
-    },
-    "-8864150640874799238": {
-      "message": "SURFACE isColorSpaceAgnostic=%b: %s",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
-    },
-    "-8398940245851553814": {
-      "message": "SURFACE SHOW (performLayout): %s",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
-    },
-    "8174298531248485625": {
-      "message": "removeAllWindowsIfPossible: removing win=%s",
-      "level": "WARN",
-      "group": "WM_DEBUG_WINDOW_MOVEMENT",
-      "at": "com\/android\/server\/wm\/WindowToken.java"
-    },
-    "2740931087734487464": {
-      "message": "addWindow: win=%s Callers=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_FOCUS",
-      "at": "com\/android\/server\/wm\/WindowToken.java"
-    },
-    "2382798629637143561": {
-      "message": "Adding %s to %s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_ADD_REMOVE",
-      "at": "com\/android\/server\/wm\/WindowToken.java"
-    },
-    "-7314975896738778749": {
-      "message": "setClientVisible: %s clientVisible=%b Callers=%s",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_APP_TRANSITIONS",
-      "at": "com\/android\/server\/wm\/WindowToken.java"
-    }
-  },
-  "groups": {
-    "WM_DEBUG_ADD_REMOVE": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_ANIM": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_APP_TRANSITIONS": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_APP_TRANSITIONS_ANIM": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_BACK_PREVIEW": {
-      "tag": "CoreBackPreview"
-    },
-    "WM_DEBUG_BOOT": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_CONFIGURATION": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_CONTAINERS": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_CONTENT_RECORDING": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_DIMMER": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_DRAW": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_DREAM": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_EMBEDDED_WINDOWS": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_FOCUS": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_FOCUS_LIGHT": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_IME": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_IMMERSIVE": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_KEEP_SCREEN_ON": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_LOCKTASK": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_ORIENTATION": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_RECENTS_ANIMATIONS": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_REMOTE_ANIMATIONS": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_RESIZE": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_SCREEN_ON": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_STARTING_WINDOW": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_STATES": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_SWITCH": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_SYNC_ENGINE": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_TASKS": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_TPL": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_WALLPAPER": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_WINDOW_INSETS": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_WINDOW_MOVEMENT": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_WINDOW_ORGANIZER": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_WINDOW_TRANSITIONS": {
-      "tag": "WindowManager"
-    },
-    "WM_DEBUG_WINDOW_TRANSITIONS_MIN": {
-      "tag": "WindowManager"
-    },
-    "WM_ERROR": {
-      "tag": "WindowManager"
-    },
-    "WM_SHOW_SURFACE_ALLOC": {
-      "tag": "WindowManager"
-    },
-    "WM_SHOW_TRANSACTIONS": {
-      "tag": "WindowManager"
-    }
-  }
-}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index eade86e..d888fa9 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -658,27 +658,28 @@
     }
 
     /**
-     * Returns the expanded bounds if the {@code bounds} violate minimum dimension or are not fully
-     * covered by the task bounds. Otherwise, returns {@code bounds}.
+     * Returns the expanded bounds if the {@code relBounds} violate minimum dimension or are not
+     * fully covered by the task bounds. Otherwise, returns {@code relBounds}.
      */
     @NonNull
-    static Rect sanitizeBounds(@NonNull Rect bounds, @Nullable Size minDimension,
+    static Rect sanitizeBounds(@NonNull Rect relBounds, @Nullable Size minDimension,
                         @NonNull TaskFragmentContainer container) {
-        if (bounds.isEmpty()) {
+        if (relBounds.isEmpty()) {
             // Don't need to check if the bounds follows the task bounds.
-            return bounds;
+            return relBounds;
         }
-        if (boundsSmallerThanMinDimensions(bounds, minDimension)) {
+        if (boundsSmallerThanMinDimensions(relBounds, minDimension)) {
             // Expand the bounds if the bounds are smaller than minimum dimensions.
             return new Rect();
         }
         final TaskContainer taskContainer = container.getTaskContainer();
-        final Rect taskBounds = taskContainer.getBounds();
-        if (!taskBounds.contains(bounds)) {
+        final Rect relTaskBounds = new Rect(taskContainer.getBounds());
+        relTaskBounds.offsetTo(0, 0);
+        if (!relTaskBounds.contains(relBounds)) {
             // Expand the bounds if the bounds exceed the task bounds.
             return new Rect();
         }
-        return bounds;
+        return relBounds;
     }
 
     @Override
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
index 0972d40..7a0b9a0 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
@@ -409,6 +409,22 @@
     }
 
     @Test
+    public void testSanitizeBounds_taskInSplitScreen() {
+        final TaskFragmentContainer overlayContainer =
+                createTestOverlayContainer(TASK_ID, "test1");
+        TaskContainer taskContainer = overlayContainer.getTaskContainer();
+        spyOn(taskContainer);
+        doReturn(new Rect(TASK_BOUNDS.left + TASK_BOUNDS.width() / 2, TASK_BOUNDS.top,
+                TASK_BOUNDS.right, TASK_BOUNDS.bottom)).when(taskContainer).getBounds();
+        final Rect taskBounds = taskContainer.getBounds();
+        final Rect bounds = new Rect(taskBounds.width() / 2, 0, taskBounds.width(),
+                taskBounds.height());
+
+        assertThat(sanitizeBounds(bounds, null, overlayContainer)
+                .isEmpty()).isFalse();
+    }
+
+    @Test
     public void testCreateOrUpdateOverlayTaskFragmentIfNeeded_createOverlay() {
         final Rect bounds = new Rect(0, 0, 100, 100);
         mSplitController.setActivityStackAttributesCalculator(params ->
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 5600664..8c36554 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
@@ -18,7 +18,6 @@
 
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_PREDICTIVE_BACK_HOME;
 import static com.android.window.flags.Flags.predictiveBackSystemAnims;
-import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 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;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index da530d7..1279fc4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -305,6 +305,7 @@
                 getUser().getIdentifier(),
                 getPackageName(),
                 getTitle(),
+                getAppName(),
                 isImportantConversation());
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 317e00a..d9055fb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -518,7 +518,7 @@
     }
 
     private ExternalInterfaceBinder createExternalInterface() {
-        return new BubbleController.IBubblesImpl(this);
+        return new IBubblesImpl(this);
     }
 
     @VisibleForTesting
@@ -2354,6 +2354,8 @@
         @Override
         public void invalidate() {
             mController = null;
+            // Unregister the listeners to ensure any binder death recipients are unlinked
+            mListener.unregister();
         }
 
         @Override
@@ -2531,17 +2533,6 @@
 
         private CachedState mCachedState = new CachedState();
 
-        private IBubblesImpl mIBubbles;
-
-        @Override
-        public IBubbles createExternalInterface() {
-            if (mIBubbles != null) {
-                mIBubbles.invalidate();
-            }
-            mIBubbles = new IBubblesImpl(BubbleController.this);
-            return mIBubbles;
-        }
-
         @Override
         public boolean isBubbleNotificationSuppressedFromShade(String key, String groupKey) {
             return mCachedState.isBubbleNotificationSuppressedFromShade(key, groupKey);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ExecutorUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ExecutorUtils.java
deleted file mode 100644
index b29058b..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ExecutorUtils.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.common;
-
-import android.Manifest;
-import android.util.Slog;
-
-import java.util.function.Consumer;
-
-/**
- * Helpers for working with executors
- */
-public class ExecutorUtils {
-
-    /**
-     * Checks that the caller has the MANAGE_ACTIVITY_TASKS permission and executes the given
-     * callback.
-     */
-    public static <T> void executeRemoteCallWithTaskPermission(RemoteCallable<T> controllerInstance,
-            String log, Consumer<T> callback) {
-        executeRemoteCallWithTaskPermission(controllerInstance, log, callback,
-                false /* blocking */);
-    }
-
-    /**
-     * Checks that the caller has the MANAGE_ACTIVITY_TASKS permission and executes the given
-     * callback.
-     */
-    public static <T> void executeRemoteCallWithTaskPermission(RemoteCallable<T> controllerInstance,
-            String log, Consumer<T> callback, boolean blocking) {
-        if (controllerInstance == null) return;
-
-        final RemoteCallable<T> controller = controllerInstance;
-        controllerInstance.getContext().enforceCallingPermission(
-                Manifest.permission.MANAGE_ACTIVITY_TASKS, log);
-        if (blocking) {
-            try {
-                controllerInstance.getRemoteCallExecutor().executeBlocking(() -> {
-                    callback.accept((T) controller);
-                });
-            } catch (InterruptedException e) {
-                Slog.e("ExecutorUtils", "Remote call failed", e);
-            }
-        } else {
-            controllerInstance.getRemoteCallExecutor().execute(() -> {
-                callback.accept((T) controller);
-            });
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ExternalInterfaceBinder.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ExternalInterfaceBinder.java
index aa5b0cb..d6f4d81 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ExternalInterfaceBinder.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ExternalInterfaceBinder.java
@@ -16,7 +16,11 @@
 
 package com.android.wm.shell.common;
 
+import android.Manifest;
 import android.os.IBinder;
+import android.util.Slog;
+
+import java.util.function.Consumer;
 
 /**
  * An interface for binders which can be registered to be sent to other processes.
@@ -31,4 +35,40 @@
      * Returns the IBinder to send.
      */
     IBinder asBinder();
+
+    /**
+     * Checks that the caller has the MANAGE_ACTIVITY_TASKS permission and executes the given
+     * callback.
+     */
+    default <T> void executeRemoteCallWithTaskPermission(RemoteCallable<T> controllerInstance,
+            String log, Consumer<T> callback) {
+        executeRemoteCallWithTaskPermission(controllerInstance, log, callback,
+                false /* blocking */);
+    }
+
+    /**
+     * Checks that the caller has the MANAGE_ACTIVITY_TASKS permission and executes the given
+     * callback.
+     */
+    default <T> void executeRemoteCallWithTaskPermission(RemoteCallable<T> controllerInstance,
+            String log, Consumer<T> callback, boolean blocking) {
+        if (controllerInstance == null) return;
+
+        final RemoteCallable<T> controller = controllerInstance;
+        controllerInstance.getContext().enforceCallingPermission(
+                Manifest.permission.MANAGE_ACTIVITY_TASKS, log);
+        if (blocking) {
+            try {
+                controllerInstance.getRemoteCallExecutor().executeBlocking(() -> {
+                    callback.accept((T) controller);
+                });
+            } catch (InterruptedException e) {
+                Slog.e("ExternalInterfaceBinder", "Remote call failed", e);
+            }
+        } else {
+            controllerInstance.getRemoteCallExecutor().execute(() -> {
+                callback.accept((T) controller);
+            });
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/RemoteCallable.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/RemoteCallable.java
index 30f535b..0d90fb7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/RemoteCallable.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/RemoteCallable.java
@@ -19,7 +19,7 @@
 import android.content.Context;
 
 /**
- * An interface for controllers that can receive remote calls.
+ * An interface for controllers (of type T) that can receive remote calls.
  */
 public interface RemoteCallable<T> {
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
index 24608d6..829af08 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleInfo.java
@@ -45,10 +45,12 @@
     private Icon mIcon;
     @Nullable
     private String mTitle;
+    @Nullable
+    private String mAppName;
     private boolean mIsImportantConversation;
 
     public BubbleInfo(String key, int flags, @Nullable String shortcutId, @Nullable Icon icon,
-            int userId, String packageName, @Nullable String title,
+            int userId, String packageName, @Nullable String title, @Nullable String appName,
             boolean isImportantConversation) {
         mKey = key;
         mFlags = flags;
@@ -57,6 +59,7 @@
         mUserId = userId;
         mPackageName = packageName;
         mTitle = title;
+        mAppName = appName;
         mIsImportantConversation = isImportantConversation;
     }
 
@@ -68,6 +71,7 @@
         mUserId = source.readInt();
         mPackageName = source.readString();
         mTitle = source.readString();
+        mAppName = source.readString();
         mIsImportantConversation = source.readBoolean();
     }
 
@@ -102,6 +106,11 @@
         return mTitle;
     }
 
+    @Nullable
+    public String getAppName() {
+        return mAppName;
+    }
+
     public boolean isImportantConversation() {
         return mIsImportantConversation;
     }
@@ -161,6 +170,7 @@
         parcel.writeInt(mUserId);
         parcel.writeString(mPackageName);
         parcel.writeString(mTitle);
+        parcel.writeString(mAppName);
         parcel.writeBoolean(mIsImportantConversation);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
index 8fb9bda..5d121c2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java
@@ -143,6 +143,8 @@
     /**
      * Releases the surface control of the current {@link DividerView} and tear down the view
      * hierarchy.
+     * @param t If supplied, the surface removal will be bundled with this Transaction. If
+     *          called with null, removes the surface immediately.
      */
     void release(@Nullable SurfaceControl.Transaction t) {
         if (mDividerView != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 14c9999..0cdd181 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -54,7 +54,6 @@
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayLayout
-import com.android.wm.shell.common.ExecutorUtils
 import com.android.wm.shell.common.ExternalInterfaceBinder
 import com.android.wm.shell.common.LaunchAdjacentController
 import com.android.wm.shell.common.MultiInstanceHelper
@@ -962,7 +961,7 @@
         }
         val wct = WindowContainerTransaction()
         if (isDesktopDensityOverrideSet()) {
-            wct.setDensityDpi(task.token, DESKTOP_DENSITY_OVERRIDE)
+            // TODO(344599474) reintroduce density changes behind a disabled flag
         }
         // Desktop Mode is showing and we're launching a new Task - we might need to minimize
         // a Task.
@@ -1471,13 +1470,13 @@
         }
 
         override fun showDesktopApps(displayId: Int, remoteTransition: RemoteTransition?) {
-            ExecutorUtils.executeRemoteCallWithTaskPermission(controller, "showDesktopApps") { c ->
+            executeRemoteCallWithTaskPermission(controller, "showDesktopApps") { c ->
                 c.showDesktopApps(displayId, remoteTransition)
             }
         }
 
         override fun showDesktopApp(taskId: Int) {
-            ExecutorUtils.executeRemoteCallWithTaskPermission(controller, "showDesktopApp") { c ->
+            executeRemoteCallWithTaskPermission(controller, "showDesktopApp") { c ->
                 c.moveTaskToFront(taskId)
             }
         }
@@ -1495,7 +1494,7 @@
 
         override fun getVisibleTaskCount(displayId: Int): Int {
             val result = IntArray(1)
-            ExecutorUtils.executeRemoteCallWithTaskPermission(
+            executeRemoteCallWithTaskPermission(
                 controller,
                 "getVisibleTaskCount",
                 { controller -> result[0] = controller.getVisibleTaskCount(displayId) },
@@ -1505,7 +1504,7 @@
         }
 
         override fun onDesktopSplitSelectAnimComplete(taskInfo: RunningTaskInfo) {
-            ExecutorUtils.executeRemoteCallWithTaskPermission(
+            executeRemoteCallWithTaskPermission(
                 controller,
                 "onDesktopSplitSelectAnimComplete"
             ) { c ->
@@ -1519,13 +1518,13 @@
                 "IDesktopModeImpl: set task listener=%s",
                 listener ?: "null"
             )
-            ExecutorUtils.executeRemoteCallWithTaskPermission(controller, "setTaskListener") { _ ->
+            executeRemoteCallWithTaskPermission(controller, "setTaskListener") { _ ->
                 listener?.let { remoteListener.register(it) } ?: remoteListener.unregister()
             }
         }
 
         override fun moveToDesktop(taskId: Int, transitionSource: DesktopModeTransitionSource) {
-            ExecutorUtils.executeRemoteCallWithTaskPermission(controller, "moveToDesktop") { c ->
+            executeRemoteCallWithTaskPermission(controller, "moveToDesktop") { c ->
                 c.moveToDesktop(taskId, transitionSource = transitionSource)
             }
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
index 9aa5f4f..0acc7df 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/changes.md
@@ -54,8 +54,8 @@
   extend `ExternalInterfaceBinder` and implement `invalidate()` to ensure it doesn't hold long
   references to the outer controller
 - Make the controller implement `RemoteCallable<T>`, and have all incoming calls use one of
-  the `ExecutorUtils.executeRemoteCallWithTaskPermission()` calls to verify the caller's identity
-  and ensure the call happens on the main shell thread and not the binder thread
+  the `executeRemoteCallWithTaskPermission()` calls to verify the caller's identity and ensure the
+  call happens on the main shell thread and not the binder thread
 - Inject `ShellController` and add the instance of the implementation as external interface
 - In Launcher, update `TouchInteractionService` to pass the interface to `SystemUIProxy`, and then
   call the SystemUIProxy method as needed in that code
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
index 7e70d6a..c374eb8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
@@ -32,7 +32,6 @@
 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 
-import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_DRAG_AND_DROP;
 
 import android.app.ActivityManager;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index 39b9000..962309f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -19,7 +19,6 @@
 import static android.os.UserHandle.myUserId;
 import static android.view.Display.DEFAULT_DISPLAY;
 
-import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE;
 import static com.android.wm.shell.onehanded.OneHandedState.STATE_ENTERING;
 import static com.android.wm.shell.onehanded.OneHandedState.STATE_EXITING;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 85f9194..de105c0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -22,7 +22,6 @@
 import static android.view.WindowManager.INPUT_CONSUMER_PIP;
 
 import static com.android.internal.jank.InteractionJankMonitor.CUJ_PIP_TRANSITION;
-import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_ALPHA;
 import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_EXPAND_OR_UNEXPAND;
 import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index f5afeea..1846720 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -19,7 +19,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
 
-import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_PIP;
 
 import android.app.ActivityManager;
@@ -391,6 +390,7 @@
         @Override
         public void invalidate() {
             mController = null;
+            // Unregister the listener to ensure any registered binder death recipients are unlinked
             mListener.unregister();
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/OWNERS
new file mode 100644
index 0000000..3f3308c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/OWNERS
@@ -0,0 +1 @@
+include platform/development:/tools/winscope/OWNERS
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 19af3d5..497c3f7 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
@@ -18,6 +18,8 @@
 
 import com.android.internal.protolog.common.IProtoLogGroup;
 
+import java.util.UUID;
+
 /**
  * Defines logging groups for ProtoLog.
  *
@@ -116,6 +118,11 @@
         this.mLogToLogcat = logToLogcat;
     }
 
+    @Override
+    public int getId() {
+        return Consts.START_ID + this.ordinal();
+    }
+
     private static class Consts {
         private static final String TAG_WM_SHELL = "WindowManagerShell";
         private static final String TAG_WM_STARTING_WINDOW = "ShellStartingWindow";
@@ -124,5 +131,9 @@
 
         private static final boolean ENABLE_DEBUG = true;
         private static final boolean ENABLE_LOG_TO_PROTO_DEBUG = true;
+
+        private static final int START_ID = (int) (
+                UUID.nameUUIDFromBytes(ShellProtoLogGroup.class.getName().getBytes())
+                        .getMostSignificantBits() % Integer.MAX_VALUE);
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 863202d..9d16246 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -20,7 +20,6 @@
 import static android.content.pm.PackageManager.FEATURE_PC;
 
 import static com.android.window.flags.Flags.enableDesktopWindowingTaskbarRunningApps;
-import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_RECENT_TASKS;
 
 import android.app.ActivityManager;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index b9d70e1..dd219d3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -24,7 +24,6 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
 
-import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.common.MultiInstanceHelper.getComponent;
 import static com.android.wm.shell.common.MultiInstanceHelper.getShortcutComponent;
 import static com.android.wm.shell.common.MultiInstanceHelper.samePackage;
@@ -1241,8 +1240,9 @@
         @Override
         public void invalidate() {
             mController = null;
-            // Unregister the listener to ensure any registered binder death recipients are unlinked
+            // Unregister the listeners to ensure any binder death recipients are unlinked
             mListener.unregister();
+            mSelectListener.unregister();
         }
 
         @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 82ef422..cc995ea 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -1846,7 +1846,7 @@
 
     void finishEnterSplitScreen(SurfaceControl.Transaction finishT) {
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "finishEnterSplitScreen");
-        mSplitLayout.update(finishT, true /* resetImePosition */);
+        mSplitLayout.update(null, true /* resetImePosition */);
         mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash);
         mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash);
         setDividerVisibility(true, finishT);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
index bec4ba3..fa084c58 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
@@ -23,7 +23,6 @@
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_WINDOWLESS;
 
-import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_STARTING_WINDOW;
 
 import android.app.ActivityManager.RunningTaskInfo;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
index b1a1e59..299da13 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
@@ -133,5 +133,7 @@
      */
     public void invalidate(Transitions transitions) {
         transitions.unregisterObserver(this);
+        // Unregister the listener to ensure any registered binder death recipients are unlinked
+        mListener.unregister();
     }
 }
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 65fda97..b2180db 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
@@ -35,7 +35,6 @@
 import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
 
 import static com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary;
-import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
 import static com.android.wm.shell.shared.TransitionUtil.isOpeningType;
 import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SHELL_TRANSITIONS;
@@ -655,8 +654,10 @@
             }
             if (change.hasFlags(FLAG_NO_ANIMATION)) {
                 hasNoAnimation = true;
-            } else {
-                // at-least one relevant participant *is* animated, so we need to animate.
+            } else if (!TransitionUtil.isOrderOnly(change) && !change.hasFlags(FLAG_IS_OCCLUDED)) {
+                // Ignore the order only or occluded changes since they shouldn't be visible during
+                // animation. For anything else, we need to animate if at-least one relevant
+                // participant *is* animated,
                 return false;
             }
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index d452428..eeb3662 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -439,7 +439,7 @@
             } else if (id == R.id.caption_handle || id == R.id.open_menu_button) {
                 if (!decoration.isHandleMenuActive()) {
                     moveTaskToFront(decoration.mTaskInfo);
-                    decoration.createHandleMenu();
+                    decoration.createHandleMenu(mSplitScreenController);
                 } else {
                     decoration.closeHandleMenu();
                 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 644fd4b..d822dfd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -68,6 +68,7 @@
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
 import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder;
 import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
@@ -650,7 +651,7 @@
     /**
      * Create and display handle menu window.
      */
-    void createHandleMenu() {
+    void createHandleMenu(SplitScreenController splitScreenController) {
         loadAppInfoIfNeeded();
         mHandleMenu = new HandleMenu.Builder(this)
                 .setAppIcon(mAppIconBitmap)
@@ -660,6 +661,8 @@
                 .setLayoutId(mRelayoutParams.mLayoutResId)
                 .setWindowingButtonsVisible(DesktopModeStatus.canEnterDesktopMode(mContext))
                 .setCaptionHeight(mResult.mCaptionHeight)
+                .setDisplayController(mDisplayController)
+                .setSplitScreenController(splitScreenController)
                 .build();
         mWindowDecorViewHolder.onHandleMenuOpened();
         mHandleMenu.show();
@@ -815,11 +818,15 @@
         // We want handle to remain pressed if the pointer moves outside of it during a drag.
         handle.setPressed((inHandle && action == ACTION_DOWN)
                 || (handle.isPressed() && action != ACTION_UP && action != ACTION_CANCEL));
-        if (isHandleMenuActive()) {
+        if (isHandleMenuActive() && !isMenuAboveStatusBar()) {
             mHandleMenu.checkMotionEvent(ev);
         }
     }
 
+    private boolean isMenuAboveStatusBar() {
+        return Flags.enableAdditionalWindowsAboveStatusBar() && !mTaskInfo.isFreeform();
+    }
+
     private boolean pointInView(View v, float x, float y) {
         return v != null && v.getLeft() <= x && v.getRight() >= x
                 && v.getTop() <= y && v.getBottom() >= y;
@@ -868,6 +875,10 @@
         return exclusionRegion;
     }
 
+    int getCaptionX() {
+        return mResult.mCaptionX;
+    }
+
     @Override
     int getCaptionHeightId(@WindowingMode int windowingMode) {
         return getCaptionHeightIdStatic(windowingMode);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
index c22b621..bfc4e0d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
@@ -23,6 +23,8 @@
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_UP;
 
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager.RunningTaskInfo;
@@ -34,6 +36,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.PointF;
+import android.graphics.Rect;
 import android.view.MotionEvent;
 import android.view.SurfaceControl;
 import android.view.View;
@@ -42,7 +45,15 @@
 import android.widget.TextView;
 import android.window.SurfaceSyncGroup;
 
+import androidx.annotation.VisibleForTesting;
+
+import com.android.window.flags.Flags;
 import com.android.wm.shell.R;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer;
+import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer;
 
 /**
  * Handle menu opened when the appropriate button is clicked on.
@@ -56,15 +67,19 @@
     private static final String TAG = "HandleMenu";
     private static final boolean SHOULD_SHOW_MORE_ACTIONS_PILL = false;
     private final Context mContext;
-    private final WindowDecoration mParentDecor;
-    private WindowDecoration.AdditionalWindow mHandleMenuWindow;
-    private final PointF mHandleMenuPosition = new PointF();
+    private final DesktopModeWindowDecoration mParentDecor;
+    @VisibleForTesting
+    AdditionalViewContainer mHandleMenuViewContainer;
+    @VisibleForTesting
+    final PointF mHandleMenuPosition = new PointF();
     private final boolean mShouldShowWindowingPill;
     private final Bitmap mAppIconBitmap;
     private final CharSequence mAppName;
     private final View.OnClickListener mOnClickListener;
     private final View.OnTouchListener mOnTouchListener;
     private final RunningTaskInfo mTaskInfo;
+    private final DisplayController mDisplayController;
+    private final SplitScreenController mSplitScreenController;
     private final int mLayoutResId;
     private int mMarginMenuTop;
     private int mMarginMenuStart;
@@ -74,12 +89,16 @@
     private HandleMenuAnimator mHandleMenuAnimator;
 
 
-    HandleMenu(WindowDecoration parentDecor, int layoutResId, View.OnClickListener onClickListener,
-            View.OnTouchListener onTouchListener, Bitmap appIcon, CharSequence appName,
-            boolean shouldShowWindowingPill, int captionHeight) {
+    HandleMenu(DesktopModeWindowDecoration parentDecor, int layoutResId,
+            View.OnClickListener onClickListener, View.OnTouchListener onTouchListener,
+            Bitmap appIcon, CharSequence appName, DisplayController displayController,
+            SplitScreenController splitScreenController, boolean shouldShowWindowingPill,
+            int captionHeight) {
         mParentDecor = parentDecor;
         mContext = mParentDecor.mDecorWindowContext;
         mTaskInfo = mParentDecor.mTaskInfo;
+        mDisplayController = displayController;
+        mSplitScreenController = splitScreenController;
         mLayoutResId = layoutResId;
         mOnClickListener = onClickListener;
         mOnTouchListener = onTouchListener;
@@ -95,20 +114,27 @@
         final SurfaceSyncGroup ssg = new SurfaceSyncGroup(TAG);
         SurfaceControl.Transaction t = new SurfaceControl.Transaction();
 
-        createHandleMenuWindow(t, ssg);
+        createHandleMenuViewContainer(t, ssg);
         ssg.addTransaction(t);
         ssg.markSyncReady();
         setupHandleMenu();
         animateHandleMenu();
     }
 
-    private void createHandleMenuWindow(SurfaceControl.Transaction t, SurfaceSyncGroup ssg) {
+    private void createHandleMenuViewContainer(SurfaceControl.Transaction t,
+            SurfaceSyncGroup ssg) {
         final int x = (int) mHandleMenuPosition.x;
         final int y = (int) mHandleMenuPosition.y;
-        mHandleMenuWindow = mParentDecor.addWindow(
-                R.layout.desktop_mode_window_decor_handle_menu, "Handle Menu",
-                t, ssg, x, y, mMenuWidth, mMenuHeight);
-        final View handleMenuView = mHandleMenuWindow.mWindowViewHost.getView();
+        if (!mTaskInfo.isFreeform() && Flags.enableAdditionalWindowsAboveStatusBar()) {
+            mHandleMenuViewContainer = new AdditionalSystemViewContainer(mContext,
+                    R.layout.desktop_mode_window_decor_handle_menu, mTaskInfo.taskId,
+                    x, y, mMenuWidth, mMenuHeight);
+        } else {
+            mHandleMenuViewContainer = mParentDecor.addWindow(
+                    R.layout.desktop_mode_window_decor_handle_menu, "Handle Menu",
+                    t, ssg, x, y, mMenuWidth, mMenuHeight);
+        }
+        final View handleMenuView = mHandleMenuViewContainer.getView();
         mHandleMenuAnimator = new HandleMenuAnimator(handleMenuView, mMenuWidth, mCaptionHeight);
     }
 
@@ -129,7 +155,7 @@
      * pill.
      */
     private void setupHandleMenu() {
-        final View handleMenu = mHandleMenuWindow.mWindowViewHost.getView();
+        final View handleMenu = mHandleMenuViewContainer.getView();
         handleMenu.setOnTouchListener(mOnTouchListener);
         setupAppInfoPill(handleMenu);
         if (mShouldShowWindowingPill) {
@@ -147,6 +173,7 @@
         final ImageView appIcon = handleMenu.findViewById(R.id.application_icon);
         final TextView appName = handleMenu.findViewById(R.id.application_name);
         collapseBtn.setOnClickListener(mOnClickListener);
+        collapseBtn.setTaskInfo(mTaskInfo);
         appIcon.setImageBitmap(mAppIconBitmap);
         appName.setText(mAppName);
     }
@@ -215,32 +242,55 @@
      * Updates handle menu's position variables to reflect its next position.
      */
     private void updateHandleMenuPillPositions() {
-        final int menuX, menuY;
-        final int captionWidth = mTaskInfo.getConfiguration()
-                .windowConfiguration.getBounds().width();
+        int menuX;
+        final int menuY;
         if (mLayoutResId == R.layout.desktop_mode_app_header) {
-            // Align the handle menu to the left of the caption.
+            // Align the handle menu to the left side of the caption.
             menuX = mMarginMenuStart;
             menuY = mMarginMenuTop;
         } else {
-            // Position the handle menu at the center of the caption.
-            menuX = (captionWidth / 2) - (mMenuWidth / 2);
-            menuY = mMarginMenuStart;
+            final int handleWidth = loadDimensionPixelSize(mContext.getResources(),
+                    R.dimen.desktop_mode_fullscreen_decor_caption_width);
+            final int handleOffset = (mMenuWidth / 2) - (handleWidth / 2);
+            final int captionX = mParentDecor.getCaptionX();
+            // TODO(b/343561161): This needs to be calculated differently if the task is in
+            //  top/bottom split.
+            if (Flags.enableAdditionalWindowsAboveStatusBar()) {
+                final Rect leftOrTopStageBounds = new Rect();
+                if (mSplitScreenController.getSplitPosition(mTaskInfo.taskId)
+                        == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+                    mSplitScreenController.getStageBounds(leftOrTopStageBounds, new Rect());
+                }
+                // In a focused decor, we use global coordinates for handle menu. Therefore we
+                // need to account for other factors like split stage and menu/handle width to
+                // center the menu.
+                final DisplayLayout layout = mDisplayController
+                        .getDisplayLayout(mTaskInfo.displayId);
+                menuX = captionX + handleOffset - (layout.width() / 2);
+                if (mSplitScreenController.getSplitPosition(mTaskInfo.taskId)
+                        == SPLIT_POSITION_BOTTOM_OR_RIGHT && layout.isLandscape()) {
+                    // If this task in the right stage, we need to offset by left stage's width
+                    menuX += leftOrTopStageBounds.width();
+                }
+                menuY = mMarginMenuStart - ((layout.height() - mMenuHeight) / 2);
+            } else {
+                final int captionWidth = mTaskInfo.getConfiguration()
+                        .windowConfiguration.getBounds().width();
+                menuX = (captionWidth / 2) - (mMenuWidth / 2);
+                menuY = mMarginMenuTop;
+            }
         }
-
         // Handle Menu position setup.
         mHandleMenuPosition.set(menuX, menuY);
-
     }
 
     /**
      * Update pill layout, in case task changes have caused positioning to change.
      */
     void relayout(SurfaceControl.Transaction t) {
-        if (mHandleMenuWindow != null) {
+        if (mHandleMenuViewContainer != null) {
             updateHandleMenuPillPositions();
-            t.setPosition(mHandleMenuWindow.mWindowSurface,
-                    mHandleMenuPosition.x, mHandleMenuPosition.y);
+            mHandleMenuViewContainer.setPosition(t, mHandleMenuPosition.x, mHandleMenuPosition.y);
         }
     }
 
@@ -252,7 +302,7 @@
      * @param ev the MotionEvent to compare against.
      */
     void checkMotionEvent(MotionEvent ev) {
-        final View handleMenu = mHandleMenuWindow.mWindowViewHost.getView();
+        final View handleMenu = mHandleMenuViewContainer.getView();
         final HandleMenuImageButton collapse = handleMenu.findViewById(R.id.collapse_menu_button);
         final PointF inputPoint = translateInputToLocalSpace(ev);
         final boolean inputInCollapseButton = pointInView(collapse, inputPoint.x, inputPoint.y);
@@ -280,7 +330,7 @@
     boolean isValidMenuInput(PointF inputPoint) {
         if (!viewsLaidOut()) return true;
         return pointInView(
-                mHandleMenuWindow.mWindowViewHost.getView(),
+                mHandleMenuViewContainer.getView(),
                 inputPoint.x - mHandleMenuPosition.x,
                 inputPoint.y - mHandleMenuPosition.y);
     }
@@ -294,7 +344,7 @@
      * Check if the views for handle menu can be seen.
      */
     private boolean viewsLaidOut() {
-        return mHandleMenuWindow.mWindowViewHost.getView().isLaidOut();
+        return mHandleMenuViewContainer.getView().isLaidOut();
     }
 
     private void loadHandleMenuDimensions() {
@@ -333,8 +383,8 @@
 
     void close() {
         final Runnable after = () -> {
-            mHandleMenuWindow.releaseView();
-            mHandleMenuWindow = null;
+            mHandleMenuViewContainer.releaseView();
+            mHandleMenuViewContainer = null;
         };
         if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
                 || mTaskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW) {
@@ -345,7 +395,7 @@
     }
 
     static final class Builder {
-        private final WindowDecoration mParent;
+        private final DesktopModeWindowDecoration mParent;
         private CharSequence mName;
         private Bitmap mAppIcon;
         private View.OnClickListener mOnClickListener;
@@ -353,9 +403,10 @@
         private int mLayoutId;
         private boolean mShowWindowingPill;
         private int mCaptionHeight;
+        private DisplayController mDisplayController;
+        private SplitScreenController mSplitScreenController;
 
-
-        Builder(@NonNull WindowDecoration parent) {
+        Builder(@NonNull DesktopModeWindowDecoration parent) {
             mParent = parent;
         }
 
@@ -394,9 +445,20 @@
             return this;
         }
 
+        Builder setDisplayController(DisplayController displayController) {
+            mDisplayController = displayController;
+            return this;
+        }
+
+        Builder setSplitScreenController(SplitScreenController splitScreenController) {
+            mSplitScreenController = splitScreenController;
+            return this;
+        }
+
         HandleMenu build() {
-            return new HandleMenu(mParent, mLayoutId, mOnClickListener, mOnTouchListener,
-                    mAppIcon, mName, mShowWindowingPill, mCaptionHeight);
+            return new HandleMenu(mParent, mLayoutId, mOnClickListener,
+                    mOnTouchListener, mAppIcon, mName, mDisplayController, mSplitScreenController,
+                    mShowWindowingPill, mCaptionHeight);
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt
index 7898567..18757ef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt
@@ -15,6 +15,10 @@
  */
 package com.android.wm.shell.windowdecor
 
+import android.app.ActivityManager.RunningTaskInfo
+import com.android.window.flags.Flags
+import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
+
 import android.content.Context
 import android.util.AttributeSet
 import android.view.MotionEvent
@@ -25,10 +29,20 @@
  * This is due to the hover events being handled by [DesktopModeWindowDecorViewModel]
  * in order to take the status bar layer into account. Handling it in both classes results in a
  * flicker when the hover moves from outside to inside status bar layer.
+ * TODO(b/342229481): Remove this and all uses of it once [AdditionalSystemViewContainer] is no longer
+ *  guarded by a flag.
  */
-class HandleMenuImageButton(context: Context?, attrs: AttributeSet?) :
-    ImageButton(context, attrs) {
+class HandleMenuImageButton(
+    context: Context?,
+    attrs: AttributeSet?
+) : ImageButton(context, attrs) {
+    lateinit var taskInfo: RunningTaskInfo
+
     override fun onHoverEvent(motionEvent: MotionEvent): Boolean {
-        return false
+        if (Flags.enableAdditionalWindowsAboveStatusBar() || taskInfo.isFreeform) {
+            return super.onHoverEvent(motionEvent)
+        } else {
+            return false
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
index 22f0adc..c903d3b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
@@ -50,7 +50,7 @@
 import com.android.wm.shell.animation.Interpolators.EMPHASIZED_DECELERATE
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.SyncTransactionQueue
-import com.android.wm.shell.windowdecor.WindowDecoration.AdditionalWindow
+import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer
 import java.util.function.Supplier
 
 
@@ -70,7 +70,7 @@
         private val menuPosition: PointF,
         private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() }
 ) {
-    private var maximizeMenu: AdditionalWindow? = null
+    private var maximizeMenu: AdditionalViewHostViewContainer? = null
     private lateinit var viewHost: SurfaceControlViewHost
     private lateinit var leash: SurfaceControl
     private val openMenuAnimatorSet = AnimatorSet()
@@ -145,7 +145,8 @@
                 .setPosition(leash, menuPosition.x, menuPosition.y)
                 .setCornerRadius(leash, cornerRadius)
                 .show(leash)
-        maximizeMenu = AdditionalWindow(leash, viewHost, transactionSupplier)
+        maximizeMenu =
+            AdditionalViewHostViewContainer(leash, viewHost, transactionSupplier)
 
         syncQueue.runInSync { transaction ->
             transaction.merge(t)
@@ -154,8 +155,7 @@
     }
 
     private fun animateOpenMenu() {
-        val viewHost = maximizeMenu?.mWindowViewHost
-        val maximizeMenuView = viewHost?.view ?: return
+        val maximizeMenuView = maximizeMenu?.view ?: return
         val maximizeWindowText = maximizeMenuView.requireViewById<TextView>(
                 R.id.maximize_menu_maximize_window_text)
         val snapWindowText = maximizeMenuView.requireViewById<TextView>(
@@ -233,7 +233,7 @@
     }
 
     private fun setupMaximizeMenu() {
-        val maximizeMenuView = maximizeMenu?.mWindowViewHost?.view ?: return
+        val maximizeMenuView = maximizeMenu?.view ?: return
 
         maximizeMenuView.setOnGenericMotionListener(onGenericMotionListener)
         maximizeMenuView.setOnTouchListener(onTouchListener)
@@ -275,7 +275,7 @@
      * Check if the views for maximize menu can be seen.
      */
     private fun viewsLaidOut(): Boolean {
-        return maximizeMenu?.mWindowViewHost?.view?.isLaidOut ?: false
+        return maximizeMenu?.view?.isLaidOut ?: false
     }
 
     fun onMaximizeMenuHoverEnter(viewId: Int, ev: MotionEvent) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 2ae3cb9..a08f97c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -22,6 +22,7 @@
 import static android.view.WindowInsets.Type.captionBar;
 import static android.view.WindowInsets.Type.mandatorySystemGestures;
 import static android.view.WindowInsets.Type.statusBars;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -56,6 +57,7 @@
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.shared.DesktopModeStatus;
 import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams.OccludingCaptionElement;
+import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -402,7 +404,7 @@
         mCaptionWindowManager.setConfiguration(taskConfig);
         final WindowManager.LayoutParams lp =
                 new WindowManager.LayoutParams(outResult.mCaptionWidth, outResult.mCaptionHeight,
-                        WindowManager.LayoutParams.TYPE_APPLICATION,
+                        TYPE_APPLICATION,
                         WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
         lp.setTitle("Caption of Task=" + mTaskInfo.taskId);
         lp.setTrustedOverlay();
@@ -569,10 +571,11 @@
      * @param yPos         y position of new window
      * @param width        width of new window
      * @param height       height of new window
-     * @return the {@link AdditionalWindow} that was added.
+     * @return the {@link AdditionalViewHostViewContainer} that was added.
      */
-    AdditionalWindow addWindow(int layoutId, String namePrefix, SurfaceControl.Transaction t,
-            SurfaceSyncGroup ssg, int xPos, int yPos, int width, int height) {
+    AdditionalViewHostViewContainer addWindow(int layoutId, String namePrefix,
+            SurfaceControl.Transaction t, SurfaceSyncGroup ssg, int xPos, int yPos,
+            int width, int height) {
         final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get();
         SurfaceControl windowSurfaceControl = builder
                 .setName(namePrefix + " of Task=" + mTaskInfo.taskId)
@@ -586,9 +589,9 @@
                 .setWindowCrop(windowSurfaceControl, width, height)
                 .show(windowSurfaceControl);
         final WindowManager.LayoutParams lp =
-                new WindowManager.LayoutParams(width, height,
-                        WindowManager.LayoutParams.TYPE_APPLICATION,
-                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
+                new WindowManager.LayoutParams(width, height, TYPE_APPLICATION,
+                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                        PixelFormat.TRANSPARENT);
         lp.setTitle("Additional window of Task=" + mTaskInfo.taskId);
         lp.setTrustedOverlay();
         WindowlessWindowManager windowManager = new WindowlessWindowManager(mTaskInfo.configuration,
@@ -596,7 +599,7 @@
         SurfaceControlViewHost viewHost = mSurfaceControlViewHostFactory
                 .create(mDecorWindowContext, mDisplay, windowManager);
         ssg.add(viewHost.getSurfacePackage(), () -> viewHost.setView(v, lp));
-        return new AdditionalWindow(windowSurfaceControl, viewHost,
+        return new AdditionalViewHostViewContainer(windowSurfaceControl, viewHost,
                 mSurfaceControlTransactionSupplier);
     }
 
@@ -739,41 +742,4 @@
             return Objects.hash(mToken, mOwner, mFrame, Arrays.hashCode(mBoundingRects));
         }
     }
-
-    /**
-     * Subclass for additional windows associated with this WindowDecoration
-     */
-    static class AdditionalWindow {
-        SurfaceControl mWindowSurface;
-        SurfaceControlViewHost mWindowViewHost;
-        Supplier<SurfaceControl.Transaction> mTransactionSupplier;
-
-        AdditionalWindow(SurfaceControl surfaceControl,
-                SurfaceControlViewHost surfaceControlViewHost,
-                Supplier<SurfaceControl.Transaction> transactionSupplier) {
-            mWindowSurface = surfaceControl;
-            mWindowViewHost = surfaceControlViewHost;
-            mTransactionSupplier = transactionSupplier;
-        }
-
-        void releaseView() {
-            WindowlessWindowManager windowManager = mWindowViewHost.getWindowlessWM();
-
-            if (mWindowViewHost != null) {
-                mWindowViewHost.release();
-                mWindowViewHost = null;
-            }
-            windowManager = null;
-            final SurfaceControl.Transaction t = mTransactionSupplier.get();
-            boolean released = false;
-            if (mWindowSurface != null) {
-                t.remove(mWindowSurface);
-                mWindowSurface = null;
-                released = true;
-            }
-            if (released) {
-                t.apply();
-            }
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
new file mode 100644
index 0000000..6c2c8fd
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor.additionalviewcontainer
+
+import android.content.Context
+import android.graphics.PixelFormat
+import android.view.LayoutInflater
+import android.view.SurfaceControl
+import android.view.View
+import android.view.WindowManager
+
+/**
+ * An [AdditionalViewContainer] that uses the system [WindowManager] instance. Intended
+ * for view containers that should be above the status bar layer.
+ */
+class AdditionalSystemViewContainer(
+    private val context: Context,
+    layoutId: Int,
+    taskId: Int,
+    x: Int,
+    y: Int,
+    width: Int,
+    height: Int
+) : AdditionalViewContainer() {
+    override val view: View
+
+    init {
+        view = LayoutInflater.from(context).inflate(layoutId, null)
+        val lp = WindowManager.LayoutParams(
+            width, height, x, y,
+            WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
+            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+            PixelFormat.TRANSPARENT
+        )
+        lp.title = "Additional view container of Task=$taskId"
+        lp.setTrustedOverlay()
+        val wm: WindowManager? = context.getSystemService(WindowManager::class.java)
+        wm?.addView(view, lp)
+    }
+
+    override fun releaseView() {
+        context.getSystemService(WindowManager::class.java)?.removeViewImmediate(view)
+    }
+
+    override fun setPosition(t: SurfaceControl.Transaction, x: Float, y: Float) {
+        val lp = (view.layoutParams as WindowManager.LayoutParams).apply {
+            this.x = x.toInt()
+            this.y = y.toInt()
+        }
+        view.layoutParams = lp
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalViewContainer.kt
new file mode 100644
index 0000000..2650648
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalViewContainer.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor.additionalviewcontainer
+
+import android.view.SurfaceControl
+import android.view.View
+import com.android.wm.shell.windowdecor.WindowDecoration
+
+/**
+ * Class for additional view containers associated with a [WindowDecoration].
+ */
+abstract class AdditionalViewContainer internal constructor(
+) {
+    abstract val view: View?
+
+    /** Release the view associated with this container and perform needed cleanup. */
+    abstract fun releaseView()
+
+    /** Reposition the view container using provided coordinates. */
+    abstract fun setPosition(t: SurfaceControl.Transaction, x: Float, y: Float)
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalViewHostViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalViewHostViewContainer.kt
new file mode 100644
index 0000000..2227612
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalViewHostViewContainer.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor.additionalviewcontainer
+
+import android.view.SurfaceControl
+import android.view.SurfaceControlViewHost
+import java.util.function.Supplier
+
+/**
+ * An [AdditionalViewContainer] that uses a [SurfaceControlViewHost] to show the window.
+ * Intended for view containers in freeform tasks that do not extend beyond task bounds.
+ */
+class AdditionalViewHostViewContainer(
+    private val windowSurface: SurfaceControl,
+    private val windowViewHost: SurfaceControlViewHost,
+    private val transactionSupplier: Supplier<SurfaceControl.Transaction>,
+) : AdditionalViewContainer() {
+
+    override val view
+        get() = windowViewHost.view
+
+    override fun releaseView() {
+        windowViewHost.release()
+        val t = transactionSupplier.get()
+        t.remove(windowSurface)
+        t.apply()
+    }
+
+    override fun setPosition(t: SurfaceControl.Transaction, x: Float, y: Float) {
+        t.setPosition(windowSurface, x, y)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleInfoTest.kt
index 432909f..5b22edd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleInfoTest.kt
@@ -32,7 +32,17 @@
     @Test
     fun bubbleInfo() {
         val bubbleInfo =
-            BubbleInfo("key", 0, "shortcut id", null, 6, "com.some.package", "title", true)
+            BubbleInfo(
+                "key",
+                0,
+                "shortcut id",
+                null,
+                6,
+                "com.some.package",
+                "title",
+                "Some app",
+                true
+            )
         val parcel = Parcel.obtain()
         bubbleInfo.writeToParcel(parcel, PARCELABLE_WRITE_RETURN_VALUE)
         parcel.setDataPosition(0)
@@ -46,6 +56,7 @@
         assertThat(bubbleInfo.userId).isEqualTo(bubbleInfoFromParcel.userId)
         assertThat(bubbleInfo.packageName).isEqualTo(bubbleInfoFromParcel.packageName)
         assertThat(bubbleInfo.title).isEqualTo(bubbleInfoFromParcel.title)
+        assertThat(bubbleInfo.appName).isEqualTo(bubbleInfoFromParcel.appName)
         assertThat(bubbleInfo.isImportantConversation)
             .isEqualTo(bubbleInfoFromParcel.isImportantConversation)
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index ae05bf5..b526838 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -1113,6 +1113,8 @@
 
   @Test
   fun handleRequest_freeformTask_alreadyInDesktop_noOverrideDensity_noConfigDensityChange() {
+    // TODO(344599474) enable the test once the density change is behind a flag
+    assumeTrue(false)
     assumeTrue(ENABLE_SHELL_TRANSITIONS)
     whenever(DesktopModeStatus.isDesktopDensityOverrideSet()).thenReturn(false)
 
@@ -1127,6 +1129,8 @@
 
   @Test
   fun handleRequest_freeformTask_alreadyInDesktop_overrideDensity_hasConfigDensityChange() {
+    // TODO(344599474) enable the test once the density change is behind a flag
+    assumeTrue(false)
     assumeTrue(ENABLE_SHELL_TRANSITIONS)
     whenever(DesktopModeStatus.isDesktopDensityOverrideSet()).thenReturn(true)
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
new file mode 100644
index 0000000..5582e0f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor
+
+import android.app.ActivityManager
+import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
+import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
+import android.graphics.Bitmap
+import android.graphics.Color
+import android.graphics.Rect
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.Display
+import android.view.LayoutInflater
+import android.view.SurfaceControl
+import android.view.SurfaceControlViewHost
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.window.flags.Flags
+import com.android.wm.shell.R
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
+import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
+import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED
+import com.android.wm.shell.splitscreen.SplitScreenController
+import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
+import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.kotlin.any
+import org.mockito.kotlin.whenever
+
+/**
+ * Tests for [HandleMenu].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:HandleMenuTest
+ */
+@SmallTest
[email protected]
+@RunWith(AndroidTestingRunner::class)
+class HandleMenuTest : ShellTestCase() {
+    @JvmField
+    @Rule
+    val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
+    @Mock
+    private lateinit var mockDesktopWindowDecoration: DesktopModeWindowDecoration
+    @Mock
+    private lateinit var onClickListener: View.OnClickListener
+    @Mock
+    private lateinit var onTouchListener: View.OnTouchListener
+    @Mock
+    private lateinit var appIcon: Bitmap
+    @Mock
+    private lateinit var appName: CharSequence
+    @Mock
+    private lateinit var displayController: DisplayController
+    @Mock
+    private lateinit var splitScreenController: SplitScreenController
+    @Mock
+    private lateinit var displayLayout: DisplayLayout
+    @Mock
+    private lateinit var mockSurfaceControlViewHost: SurfaceControlViewHost
+
+    private lateinit var handleMenu: HandleMenu
+
+    @Before
+    fun setUp() {
+        val mockAdditionalViewHostViewContainer = AdditionalViewHostViewContainer(
+            mock(SurfaceControl::class.java),
+            mockSurfaceControlViewHost,
+        ) {
+            SurfaceControl.Transaction()
+        }
+        val menuView = LayoutInflater.from(context).inflate(
+            R.layout.desktop_mode_window_decor_handle_menu, null)
+        whenever(mockDesktopWindowDecoration.addWindow(
+            anyInt(), any(), any(), any(), anyInt(), anyInt(), anyInt(), anyInt())
+        ).thenReturn(mockAdditionalViewHostViewContainer)
+        whenever(mockAdditionalViewHostViewContainer.view).thenReturn(menuView)
+        whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
+        whenever(displayLayout.width()).thenReturn(DISPLAY_BOUNDS.width())
+        whenever(displayLayout.height()).thenReturn(DISPLAY_BOUNDS.height())
+        whenever(displayLayout.isLandscape).thenReturn(true)
+        mockDesktopWindowDecoration.mDecorWindowContext = context
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
+    fun testFullscreenMenuUsesSystemViewContainer() {
+        createTaskInfo(WINDOWING_MODE_FULLSCREEN, SPLIT_POSITION_UNDEFINED)
+        val handleMenu = createAndShowHandleMenu()
+        assertTrue(handleMenu.mHandleMenuViewContainer is AdditionalSystemViewContainer)
+        // Verify menu is created at coordinates that, when added to WindowManager,
+        // show at the top-center of display.
+        assertTrue(handleMenu.mHandleMenuPosition.equals(16f, -512f))
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
+    fun testFreeformMenu_usesViewHostViewContainer() {
+        createTaskInfo(WINDOWING_MODE_FREEFORM, SPLIT_POSITION_UNDEFINED)
+        handleMenu = createAndShowHandleMenu()
+        assertTrue(handleMenu.mHandleMenuViewContainer is AdditionalViewHostViewContainer)
+        // Verify menu is created near top-left of task.
+        assertTrue(handleMenu.mHandleMenuPosition.equals(12f, 8f))
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
+    fun testSplitLeftMenu_usesSystemViewContainer() {
+        createTaskInfo(WINDOWING_MODE_MULTI_WINDOW, SPLIT_POSITION_TOP_OR_LEFT)
+        handleMenu = createAndShowHandleMenu()
+        assertTrue(handleMenu.mHandleMenuViewContainer is AdditionalSystemViewContainer)
+        // Verify menu is created at coordinates that, when added to WindowManager,
+        // show at the top of split left task.
+        assertTrue(handleMenu.mHandleMenuPosition.equals(-624f, -512f))
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_ADDITIONAL_WINDOWS_ABOVE_STATUS_BAR)
+    fun testSplitRightMenu_usesSystemViewContainer() {
+        createTaskInfo(WINDOWING_MODE_MULTI_WINDOW, SPLIT_POSITION_BOTTOM_OR_RIGHT)
+        handleMenu = createAndShowHandleMenu()
+        assertTrue(handleMenu.mHandleMenuViewContainer is AdditionalSystemViewContainer)
+        // Verify menu is created at coordinates that, when added to WindowManager,
+        // show at the top of split right task.
+        assertTrue(handleMenu.mHandleMenuPosition.equals(656f, -512f))
+    }
+
+    private fun createTaskInfo(windowingMode: Int, splitPosition: Int) {
+        val taskDescriptionBuilder = ActivityManager.TaskDescription.Builder()
+            .setBackgroundColor(Color.YELLOW)
+        val bounds = when (windowingMode) {
+            WINDOWING_MODE_FULLSCREEN -> DISPLAY_BOUNDS
+            WINDOWING_MODE_FREEFORM -> FREEFORM_BOUNDS
+            WINDOWING_MODE_MULTI_WINDOW -> {
+                if (splitPosition == SPLIT_POSITION_TOP_OR_LEFT) {
+                    SPLIT_LEFT_BOUNDS
+                } else {
+                    SPLIT_RIGHT_BOUNDS
+                }
+            }
+            else -> error("Unsupported windowing mode")
+        }
+        mockDesktopWindowDecoration.mTaskInfo = TestRunningTaskInfoBuilder()
+            .setDisplayId(Display.DEFAULT_DISPLAY)
+            .setTaskDescriptionBuilder(taskDescriptionBuilder)
+            .setWindowingMode(windowingMode)
+            .setBounds(bounds)
+            .setVisible(true)
+            .build()
+        // Calculate captionX similar to how WindowDecoration calculates it.
+        whenever(mockDesktopWindowDecoration.captionX).thenReturn(
+            (mockDesktopWindowDecoration.mTaskInfo.configuration.windowConfiguration
+                .bounds.width() - context.resources.getDimensionPixelSize(
+                R.dimen.desktop_mode_fullscreen_decor_caption_width)) / 2)
+        whenever(splitScreenController.getSplitPosition(any())).thenReturn(splitPosition)
+        whenever(splitScreenController.getStageBounds(any(), any())).thenAnswer {
+            (it.arguments.first() as Rect).set(SPLIT_LEFT_BOUNDS)
+        }
+    }
+
+    private fun createAndShowHandleMenu(): HandleMenu {
+        val layoutId = if (mockDesktopWindowDecoration.mTaskInfo.isFreeform) {
+            R.layout.desktop_mode_app_header
+        } else {
+            R.layout.desktop_mode_app_header
+        }
+        val handleMenu = HandleMenu(mockDesktopWindowDecoration, layoutId,
+            onClickListener, onTouchListener, appIcon, appName, displayController,
+            splitScreenController, true /* shouldShowWindowingPill */,
+            50 /* captionHeight */ )
+        handleMenu.show()
+        return handleMenu
+    }
+
+    companion object {
+        private val DISPLAY_BOUNDS = Rect(0, 0, 2560, 1600)
+        private val FREEFORM_BOUNDS = Rect(500, 500, 2000, 1200)
+        private val SPLIT_LEFT_BOUNDS = Rect(0, 0, 1280, 1600)
+        private val SPLIT_RIGHT_BOUNDS = Rect(1280, 0, 2560, 1600)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index 4831081..e73069a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -76,6 +76,7 @@
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.shared.DesktopModeStatus;
 import com.android.wm.shell.tests.R;
+import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -371,7 +372,7 @@
     }
 
     @Test
-    public void testAddWindow() {
+    public void testAddViewHostViewContainer() {
         final Display defaultDisplay = mock(Display.class);
         doReturn(defaultDisplay).when(mMockDisplayController)
                 .getDisplay(Display.DEFAULT_DISPLAY);
@@ -393,6 +394,7 @@
         final ActivityManager.RunningTaskInfo taskInfo = new TestRunningTaskInfoBuilder()
                 .setDisplayId(Display.DEFAULT_DISPLAY)
                 .setTaskDescriptionBuilder(taskDescriptionBuilder)
+                .setWindowingMode(WINDOWING_MODE_FREEFORM)
                 .setBounds(TASK_BOUNDS)
                 .setPositionInParent(TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y)
                 .setVisible(true)
@@ -407,7 +409,7 @@
                 createMockSurfaceControlBuilder(additionalWindowSurface);
         mMockSurfaceControlBuilders.add(additionalWindowSurfaceBuilder);
 
-        WindowDecoration.AdditionalWindow additionalWindow = windowDecor.addTestWindow();
+        windowDecor.addTestViewContainer();
 
         verify(additionalWindowSurfaceBuilder).setContainerLayer();
         verify(additionalWindowSurfaceBuilder).setParent(decorContainerSurface);
@@ -421,12 +423,6 @@
         verify(mMockSurfaceControlAddWindowT).show(additionalWindowSurface);
         verify(mMockSurfaceControlViewHostFactory, Mockito.times(2))
                 .create(any(), eq(defaultDisplay), any());
-        assertThat(additionalWindow.mWindowViewHost).isNotNull();
-
-        additionalWindow.releaseView();
-
-        assertThat(additionalWindow.mWindowViewHost).isNull();
-        assertThat(additionalWindow.mWindowSurface).isNull();
     }
 
     @Test
@@ -905,16 +901,16 @@
                     mMockWindowContainerTransaction, mMockView, mRelayoutResult);
         }
 
-        private WindowDecoration.AdditionalWindow addTestWindow() {
+        private AdditionalViewContainer addTestViewContainer() {
             final Resources resources = mDecorWindowContext.getResources();
-            int width = loadDimensionPixelSize(resources, mCaptionMenuWidthId);
-            int height = loadDimensionPixelSize(resources, mRelayoutParams.mCaptionHeightId);
-            String name = "Test Window";
-            WindowDecoration.AdditionalWindow additionalWindow =
+            final int width = loadDimensionPixelSize(resources, mCaptionMenuWidthId);
+            final int height = loadDimensionPixelSize(resources, mRelayoutParams.mCaptionHeightId);
+            final String name = "Test Window";
+            final AdditionalViewContainer additionalViewContainer =
                     addWindow(R.layout.desktop_mode_window_decor_handle_menu, name,
                             mMockSurfaceControlAddWindowT, mMockSurfaceSyncGroup, 0 /* x */,
                             0 /* y */, width, height);
-            return additionalWindow;
+            return additionalViewContainer;
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainerTest.kt
new file mode 100644
index 0000000..d3e996b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainerTest.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor.additionalviewcontainer
+
+import android.content.Context
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.WindowManager
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.R
+import com.android.wm.shell.ShellTestCase
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+/**
+ * Tests for [AdditionalSystemViewContainer].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:AdditionalSystemViewContainerTest
+ */
+@SmallTest
[email protected]
+@RunWith(AndroidTestingRunner::class)
+class AdditionalSystemViewContainerTest : ShellTestCase() {
+    @Mock
+    private lateinit var mockView: View
+    @Mock
+    private lateinit var mockLayoutInflater: LayoutInflater
+    @Mock
+    private lateinit var mockContext: Context
+    @Mock
+    private lateinit var mockWindowManager: WindowManager
+    private lateinit var viewContainer: AdditionalSystemViewContainer
+
+    @Before
+    fun setUp() {
+        whenever(mockContext.getSystemService(WindowManager::class.java))
+            .thenReturn(mockWindowManager)
+        whenever(mockContext.getSystemService(Context
+            .LAYOUT_INFLATER_SERVICE)).thenReturn(mockLayoutInflater)
+        whenever(mockLayoutInflater.inflate(
+            R.layout.desktop_mode_window_decor_handle_menu, null)).thenReturn(mockView)
+    }
+
+    @Test
+    fun testReleaseView_ViewRemoved() {
+        viewContainer = AdditionalSystemViewContainer(
+            mockContext,
+            R.layout.desktop_mode_window_decor_handle_menu,
+            TASK_ID,
+            X,
+            Y,
+            WIDTH,
+            HEIGHT
+        )
+        verify(mockWindowManager).addView(eq(mockView), any())
+        viewContainer.releaseView()
+        verify(mockWindowManager).removeViewImmediate(mockView)
+    }
+
+    companion object {
+        private const val X = 500
+        private const val Y = 50
+        private const val WIDTH = 400
+        private const val HEIGHT = 600
+        private const val TASK_ID = 5
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalViewHostViewContainerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalViewHostViewContainerTest.kt
new file mode 100644
index 0000000..82d557a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalViewHostViewContainerTest.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.windowdecor.additionalviewcontainer
+
+import android.testing.AndroidTestingRunner
+import android.view.SurfaceControl
+import android.view.SurfaceControlViewHost
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+import java.util.function.Supplier
+
+/**
+ * Tests for [AdditionalViewHostViewContainer].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:AdditionalViewHostViewContainerTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class AdditionalViewHostViewContainerTest : ShellTestCase() {
+    @Mock
+    private lateinit var mockTransactionSupplier: Supplier<SurfaceControl.Transaction>
+    @Mock
+    private lateinit var mockTransaction: SurfaceControl.Transaction
+    @Mock
+    private lateinit var mockSurface: SurfaceControl
+    @Mock
+    private lateinit var mockViewHost: SurfaceControlViewHost
+    private lateinit var viewContainer: AdditionalViewHostViewContainer
+
+    @Before
+    fun setUp() {
+        whenever(mockTransactionSupplier.get()).thenReturn(mockTransaction)
+    }
+
+    @Test
+    fun testReleaseView_ViewRemoved() {
+        viewContainer = AdditionalViewHostViewContainer(
+            mockSurface,
+            mockViewHost,
+            mockTransactionSupplier
+        )
+        viewContainer.releaseView()
+        verify(mockViewHost).release()
+        verify(mockTransaction).remove(mockSurface)
+        verify(mockTransaction).apply()
+    }
+}
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 68befff..e618245 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -926,8 +926,8 @@
 
     //printf("USING Zip '%s'\n", pEntry->getFileName());
 
-    if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,
-            NULL, NULL))
+    if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, nullptr, nullptr,
+            nullptr, nullptr, nullptr))
     {
         ALOGW("getEntryInfo failed\n");
         return NULL;
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index 839c7b6..10651cd 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -119,14 +119,6 @@
  * appear to be bogus.
  */
 bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
- uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
- uint32_t* pModWhen, uint32_t* pCrc32) const
-{
-     return getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset, pModWhen,
-      pCrc32, nullptr);
-}
-
-bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
     uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
     uint32_t* pModWhen, uint32_t* pCrc32, uint16_t* pExtraFieldSize) const
 {
diff --git a/libs/androidfw/include/androidfw/ZipFileRO.h b/libs/androidfw/include/androidfw/ZipFileRO.h
index f7c5007..0f3f19c 100644
--- a/libs/androidfw/include/androidfw/ZipFileRO.h
+++ b/libs/androidfw/include/androidfw/ZipFileRO.h
@@ -147,10 +147,6 @@
      * Returns "false" if "entry" is bogus or if the data in the Zip file
      * appears to be bad.
      */
-    bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, uint32_t* pUncompLen,
-        uint32_t* pCompLen, off64_t* pOffset, uint32_t* pModWhen,
-        uint32_t* pCrc32) const;
-
     bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
         uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
         uint32_t* pModWhen, uint32_t* pCrc32, uint16_t* pExtraFieldSize) const;
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 7b7ccf5..7a82938 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -46,7 +46,6 @@
         "liblog",
         "libutils",
         "libgui",
-        "libui",
         "libinput",
     ],
 
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
index a470f93..88704da 100644
--- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -412,7 +412,7 @@
                             false);
                     if (!mOnHost && !autoTransact) {
                         Log.e(TAG, "Ignoring polling-loop-filter " + plf
-                                + " for offhost service that isn't autoTranact");
+                                + " for offhost service that isn't autoTransact");
                     } else {
                         mAutoTransact.put(plf, autoTransact);
                     }
@@ -429,7 +429,7 @@
                             false);
                     if (!mOnHost && !autoTransact) {
                         Log.e(TAG, "Ignoring polling-loop-filter " + plf
-                                + " for offhost service that isn't autoTranact");
+                                + " for offhost service that isn't autoTransact");
                     } else {
                         mAutoTransactPatterns.put(Pattern.compile(plf), autoTransact);
                     }
@@ -1028,6 +1028,9 @@
         pw.println("    Settings Activity: " + mSettingsActivityName);
         pw.println("    Requires Device Unlock: " + mRequiresDeviceUnlock);
         pw.println("    Requires Device ScreenOn: " + mRequiresDeviceScreenOn);
+        pw.println("    Should Default to Observe Mode: " + mShouldDefaultToObserveMode);
+        pw.println("    Auto-Transact Mapping: " + mAutoTransact);
+        pw.println("    Auto-Transact Patterns: " + mAutoTransactPatterns);
     }
 
 
diff --git a/packages/EasterEgg/AndroidManifest.xml b/packages/EasterEgg/AndroidManifest.xml
index d1db237..1500583 100644
--- a/packages/EasterEgg/AndroidManifest.xml
+++ b/packages/EasterEgg/AndroidManifest.xml
@@ -36,8 +36,28 @@
         android:icon="@drawable/android14_patch_adaptive"
         android:label="@string/app_name">
 
-        <!-- Android U easter egg -->
+        <!-- Android V easter egg: Daydream version of Landroid
+             (must be enabled by unlocking the egg) -->
+        <service
+            android:name=".landroid.DreamUniverse"
+            android:exported="true"
+            android:icon="@drawable/android14_patch_adaptive"
+            android:label="@string/v_egg_name"
+            android:description="@string/dream_description"
+            android:enabled="false"
+            android:permission="android.permission.BIND_DREAM_SERVICE"
+            >
 
+            <intent-filter>
+                <action android:name="android.service.dreams.DreamService" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data
+                android:name="android.service.dream"
+                android:resource="@xml/landroid_dream"/>
+        </service>
+
+        <!-- Android U easter egg -->
         <activity
             android:name=".landroid.MainActivity"
             android:exported="true"
@@ -52,7 +72,6 @@
             </intent-filter>
         </activity>
 
-
         <!-- Android Q easter egg -->
         <activity
             android:name=".quares.QuaresActivity"
diff --git a/packages/EasterEgg/res/values/landroid_strings.xml b/packages/EasterEgg/res/values/landroid_strings.xml
index 1394f2f..1bbfcca 100644
--- a/packages/EasterEgg/res/values/landroid_strings.xml
+++ b/packages/EasterEgg/res/values/landroid_strings.xml
@@ -1,21 +1,13 @@
-<?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.
--->
-
+<?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="u_egg_name" translatable="false">Android 14 Easter Egg</string>
+
+    <!-- No Android's Sky -->
+    <!-- Char Star Field -->
+    <!-- V-leet: Harmless -->
+    <!-- Contemplating My Orbital Mechanics -->
+    <string name="u_egg_name" translatable="false">Landroid</string>
+    <string name="v_egg_name" translatable="false">Landroid</string>
+    <string name="dream_description" translatable="false">---- AUTOPILOT ENGAGED ----</string>
 
     <string-array name="planet_descriptors" translatable="false">
         <item>earthy</item>
@@ -365,7 +357,64 @@
         <item>relaxed</item>
         <item>skunky</item>
         <item>breezy</item>
-        <item>soup </item>
+        <item>soup</item>
+    </string-array>
+
+    <string-array name="fauna_generic_plurals" translatable="false">
+        <item>fauna</item>
+        <item>animals</item>
+        <item>locals</item>
+        <item>creatures</item>
+        <item>critters</item>
+        <item>wildlife</item>
+        <item>specimens</item>
+        <item>life</item>
+        <item>cells</item>
+    </string-array>
+
+    <string-array name="flora_generic_plurals" translatable="false">
+        <item>flora</item>
+        <item>plants</item>
+        <item>flowers</item>
+        <item>trees</item>
+        <item>mosses</item>
+        <item>specimens</item>
+        <item>life</item>
+        <item>cells</item>
+    </string-array>
+
+    <string-array name="atmo_generic_plurals" translatable="false">
+        <item>air</item>
+        <item>atmosphere</item>
+        <item>clouds</item>
+        <item>atmo</item>
+        <item>gases</item>
+    </string-array>
+
+    <string-array name="activities" translatable="false">
+        <item>refueling</item>
+        <item>sightseeing</item>
+        <item>vacationing</item>
+        <item>luncheoning</item>
+        <item>recharging</item>
+        <item>taking up space</item>
+        <item>reticulating space splines</item>
+        <item>using facilities</item>
+        <item>spelunking</item>
+        <item>repairing</item>
+        <item>herding {fauna}</item>
+        <item>taming {fauna}</item>
+        <item>breeding {fauna}</item>
+        <item>singing lullabies to {fauna}</item>
+        <item>singing lullabies to {flora}</item>
+        <item>singing lullabies to the {planet}</item>
+        <item>gardening {flora}</item>
+        <item>collecting {flora}</item>
+        <item>surveying the {planet}</item>
+        <item>mapping the {planet}</item>
+        <item>breathing {atmo}</item>
+        <item>reprocessing {atmo}</item>
+        <item>bottling {atmo}</item>
     </string-array>
 
 </resources>
diff --git a/packages/EasterEgg/res/xml/landroid_dream.xml b/packages/EasterEgg/res/xml/landroid_dream.xml
new file mode 100644
index 0000000..adf82bd
--- /dev/null
+++ b/packages/EasterEgg/res/xml/landroid_dream.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<dream xmlns:android="http://schemas.android.com/apk/res/android"
+    android:previewImage="@*android:drawable/platlogo" />
diff --git a/packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java b/packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java
index 5820b5a..30320d6 100644
--- a/packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java
+++ b/packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java
@@ -18,11 +18,14 @@
 
 import android.app.Activity;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.pm.PackageManager;
 import android.provider.Settings;
 import android.util.Log;
 import android.widget.Toast;
 
+import com.android.egg.flags.Flags;
+import com.android.egg.landroid.DreamUniverse;
 import com.android.egg.neko.NekoControlsService;
 import com.android.egg.widget.PaintChipsActivity;
 import com.android.egg.widget.PaintChipsWidget;
@@ -33,7 +36,9 @@
 public class ComponentActivationActivity extends Activity {
     private static final String TAG = "EasterEgg";
 
+    // check PlatLogoActivity.java for these
     private static final String S_EGG_UNLOCK_SETTING = "egg_mode_s";
+    private static final String V_EGG_UNLOCK_SETTING = "egg_mode_v";
 
     private void toastUp(String s) {
         Toast toast = Toast.makeText(this, s, Toast.LENGTH_SHORT);
@@ -44,14 +49,39 @@
     public void onStart() {
         super.onStart();
 
-        final PackageManager pm = getPackageManager();
-        final ComponentName[] cns = new ComponentName[] {
-                new ComponentName(this, NekoControlsService.class),
-                new ComponentName(this, PaintChipsActivity.class),
-                new ComponentName(this, PaintChipsWidget.class)
-        };
-        final long unlockValue = Settings.System.getLong(getContentResolver(),
-                S_EGG_UNLOCK_SETTING, 0);
+        lockUnlockComponents(this);
+
+        finish();
+    }
+
+    /**
+     * Check easter egg unlock state and update unlockable components to match.
+     */
+    public static void lockUnlockComponents(Context context) {
+        final PackageManager pm = context.getPackageManager();
+        final ComponentName[] cns;
+        final String unlockSettingsKey;
+        final boolean shouldReLock;
+        final long unlockValue;
+        if (Flags.flagFlag()) {
+            unlockSettingsKey = V_EGG_UNLOCK_SETTING;
+            unlockValue = 1; // since we're not toggling we actually don't need to check the setting
+            shouldReLock = false;
+            cns = new ComponentName[]{
+                    new ComponentName(context, DreamUniverse.class)
+            };
+        } else {
+            unlockSettingsKey = S_EGG_UNLOCK_SETTING;
+            unlockValue = Settings.System.getLong(context.getContentResolver(),
+                    unlockSettingsKey, 0);
+            shouldReLock = true;
+            cns = new ComponentName[]{
+                    new ComponentName(context, NekoControlsService.class),
+                    new ComponentName(context, PaintChipsActivity.class),
+                    new ComponentName(context, PaintChipsWidget.class),
+                    new ComponentName(context, DreamUniverse.class)
+            };
+        }
         for (ComponentName cn : cns) {
             final boolean componentEnabled = pm.getComponentEnabledSetting(cn)
                     == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
@@ -77,7 +107,5 @@
                 }
             }
         }
-
-        finish();
     }
 }
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Autopilot.kt b/packages/EasterEgg/src/com/android/egg/landroid/Autopilot.kt
new file mode 100644
index 0000000..f71abee
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Autopilot.kt
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import kotlin.math.min
+import kotlin.math.sign
+
+class Autopilot(val ship: Spacecraft, val universe: Universe) : Entity {
+    val BRAKING_TIME = 5f
+    val SIGHTSEEING_TIME = 10f
+    val STRATEGY_MIN_TIME = 0.5f
+
+    var enabled = false
+
+    var target: Planet? = null
+
+    var landingAltitude = 0f
+
+    var nextStrategyTime = 0f
+
+    var brakingDistance = 0f
+
+    // used by rendering
+    var leadingPos = Vec2.Zero
+    var leadingVector = Vec2.Zero
+
+    val telemetry: String
+        get() =
+            listOf(
+                    "---- AUTOPILOT ENGAGED ----",
+                    "TGT: " + (target?.name?.toUpperCase() ?: "SELECTING..."),
+                    "EXE: $strategy" + if (debug.isNotEmpty()) " ($debug)" else "",
+                )
+                .joinToString("\n")
+
+    private var strategy: String = "NONE"
+    private var debug: String = ""
+
+    override fun update(sim: Simulator, dt: Float) {
+        if (!enabled) return
+
+        if (sim.now < nextStrategyTime) {
+            return
+        }
+
+        val currentStrategy = strategy
+
+        if (ship.landing != null) {
+            if (target != null) {
+                strategy = "LANDED"
+                debug = ""
+                // we just got here. see the sights.
+                target = null
+                landingAltitude = 0f
+                nextStrategyTime = sim.now + SIGHTSEEING_TIME
+            } else {
+                // full power until we blast off
+                ship.thrust = Vec2.makeWithAngleMag(ship.angle, 1f)
+
+                strategy = "LAUNCHING"
+                debug = ""
+                nextStrategyTime = sim.now + 2f
+            }
+        } else {
+            // select new target
+
+            if (target == null) {
+                // testing: target the first planet
+                //   target = universe.planets[0]
+
+                // target the nearest unexplored planet
+                target =
+                    universe.planets
+                        .sortedBy { (it.pos - ship.pos).mag() }
+                        .firstOrNull { !it.explored }
+                brakingDistance = 0f
+
+                // if we've explored them all, pick one at random
+                if (target == null) target = universe.planets.random()
+            }
+
+            target?.let { target -> // should be nonnull
+                val shipV = ship.velocity
+                val targetV = target.velocity
+                val targetVector = (target.pos - ship.pos)
+                val altitude = targetVector.mag() - target.radius
+
+                landingAltitude = min(target.radius, 100f)
+
+                // the following is in the moving reference frame of the target
+                val relativeV: Vec2 = shipV - targetV
+                val projection = relativeV.dot(targetVector / targetVector.mag())
+                val relativeSpeed = relativeV.mag() * projection.sign
+                val timeToTarget = if (relativeSpeed != 0f) altitude / relativeSpeed else 1_000f
+
+                val newBrakingDistance =
+                    BRAKING_TIME * if (relativeSpeed > 0) relativeSpeed else MAIN_ENGINE_ACCEL
+                brakingDistance =
+                    expSmooth(brakingDistance, newBrakingDistance, dt = sim.dt, speed = 5f)
+
+                // We're going to aim at where the target will be, but we want to make sure to
+                // compute
+                leadingPos =
+                    target.pos +
+                        Vec2.makeWithAngleMag(
+                            target.velocity.angle(),
+                            min(altitude / 2, target.velocity.mag())
+                        )
+                leadingVector = leadingPos - ship.pos
+
+                if (altitude < landingAltitude) {
+                    strategy = "LANDING"
+                    // Strategy: zero thrust, face away, prepare for landing
+
+                    ship.angle = (ship.pos - target.pos).angle() // point away from ground
+                    ship.thrust = Vec2.Zero
+                } else {
+                    if (relativeSpeed < 0 || altitude > brakingDistance) {
+                        strategy = "CHASING"
+                        // Strategy: Make tracks. We are either a long way away, or falling behind.
+                        ship.angle = leadingVector.angle()
+
+                        ship.thrust = Vec2.makeWithAngleMag(ship.angle, 1.0f)
+                    } else {
+                        strategy = "APPROACHING"
+                        // Strategy: Just slow down. If we get caught in the gravity well, it will
+                        // gradually start pulling us more in the direction of the planet, which
+                        // will create a graceful deceleration
+                        ship.angle = (-ship.velocity).angle()
+
+                        // We want to bleed off velocity over time. Specifically, relativeSpeed px/s
+                        // over timeToTarget seconds.
+                        val decel = relativeSpeed / timeToTarget
+                        val decelThrust =
+                            decel / MAIN_ENGINE_ACCEL * 0.9f // not quite slowing down enough
+                        ship.thrust = Vec2.makeWithAngleMag(ship.angle, decelThrust)
+                    }
+                }
+                debug = ("DV=%.0f D=%.0f T%+.1f").format(relativeSpeed, altitude, timeToTarget)
+            }
+            if (strategy != currentStrategy) {
+                nextStrategyTime = sim.now + STRATEGY_MIN_TIME
+            }
+        }
+    }
+
+    override fun postUpdate(sim: Simulator, dt: Float) {
+        if (!enabled) return
+    }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Colors.kt b/packages/EasterEgg/src/com/android/egg/landroid/Colors.kt
index f5657ae..24c4975 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/Colors.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Colors.kt
@@ -19,11 +19,22 @@
 import androidx.compose.ui.graphics.Color
 
 /** Various UI colors. */
-object Colors {
-    val Eigengrau = Color(0xFF16161D)
-    val Eigengrau2 = Color(0xFF292936)
-    val Eigengrau3 = Color(0xFF3C3C4F)
-    val Eigengrau4 = Color(0xFFA7A7CA)
+class Colors {
+    object Android {
+        val Green = Color(0xFF34A853)
+        val Blue = Color(0xFF4285F4)
+        val Mint = Color(0xFFE8F5E9)
+        val Chartreuse = Color(0xFFC6FF00)
+    }
+    companion object {
+        val Eigengrau = Color(0xFF16161D)
+        val Eigengrau2 = Color(0xFF292936)
+        val Eigengrau3 = Color(0xFF3C3C4F)
+        val Eigengrau4 = Color(0xFFA7A7CA)
 
-    val Console = Color(0xFFB7B7FF)
+        val Console = Color(0xFFB7B7FF)
+        val Autopilot = Android.Blue
+        val Track = Android.Green
+        val Flag = Android.Chartreuse
+    }
 }
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/DreamUniverse.kt b/packages/EasterEgg/src/com/android/egg/landroid/DreamUniverse.kt
new file mode 100644
index 0000000..8c87c5d
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/DreamUniverse.kt
@@ -0,0 +1,120 @@
+/*
+ * 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.egg.landroid
+
+import android.service.dreams.DreamService
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.ComposeView
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleRegistry
+import androidx.lifecycle.setViewTreeLifecycleOwner
+import androidx.savedstate.SavedStateRegistryController
+import androidx.savedstate.SavedStateRegistryOwner
+import androidx.savedstate.setViewTreeSavedStateRegistryOwner
+import androidx.window.layout.FoldingFeature
+import kotlin.random.Random
+
+class DreamUniverse : DreamService() {
+    private var foldState = mutableStateOf<FoldingFeature?>(null) // unused
+
+    private val lifecycleOwner =
+        object : SavedStateRegistryOwner {
+            override val lifecycle = LifecycleRegistry(this)
+            override val savedStateRegistry
+                get() = savedStateRegistryController.savedStateRegistry
+
+            private val savedStateRegistryController =
+                SavedStateRegistryController.create(this).apply { performAttach() }
+
+            fun onCreate() {
+                savedStateRegistryController.performRestore(null)
+                lifecycle.currentState = Lifecycle.State.CREATED
+            }
+
+            fun onStart() {
+                lifecycle.currentState = Lifecycle.State.STARTED
+            }
+
+            fun onStop() {
+                lifecycle.currentState = Lifecycle.State.CREATED
+            }
+        }
+
+    override fun onAttachedToWindow() {
+        super.onAttachedToWindow()
+
+        val universe = VisibleUniverse(namer = Namer(resources), randomSeed = randomSeed())
+
+        isInteractive = false
+
+        if (TEST_UNIVERSE) {
+            universe.initTest()
+        } else {
+            universe.initRandom()
+
+            // We actually don't want the deterministic random position of the ship, we want
+            // true randomness to keep things interesting. So use Random (not universe.rng).
+            universe.ship.pos =
+                universe.star.pos +
+                    Vec2.makeWithAngleMag(
+                        Random.nextFloat() * PI2f,
+                        Random.nextFloatInRange(
+                            PLANET_ORBIT_RANGE.start,
+                            PLANET_ORBIT_RANGE.endInclusive
+                        )
+                    )
+        }
+
+        // enable autopilot in screensaver mode
+        val autopilot = Autopilot(universe.ship, universe)
+        universe.ship.autopilot = autopilot
+        universe.add(autopilot)
+        autopilot.enabled = true
+
+        // much more visually interesting in a screensaver context
+        DYNAMIC_ZOOM = true
+
+        val composeView = ComposeView(this)
+        composeView.setContent {
+            Spaaaace(modifier = Modifier.fillMaxSize(), u = universe, foldState = foldState)
+            DebugText(DEBUG_TEXT)
+            Telemetry(universe)
+        }
+
+        composeView.setViewTreeLifecycleOwner(lifecycleOwner)
+        composeView.setViewTreeSavedStateRegistryOwner(lifecycleOwner)
+
+        setContentView(composeView)
+    }
+
+    override fun onCreate() {
+        super.onCreate()
+        lifecycleOwner.onCreate()
+    }
+
+    override fun onDreamingStarted() {
+        super.onDreamingStarted()
+        lifecycleOwner.onStart()
+    }
+
+    override fun onDreamingStopped() {
+        super.onDreamingStopped()
+        lifecycleOwner.onStop()
+    }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt b/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt
index 5a9b814..79f8b5fc 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt
@@ -21,12 +21,10 @@
 import android.util.Log
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
+import androidx.activity.enableEdgeToEdge
 import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.core.CubicBezierEasing
 import androidx.compose.animation.core.animateFloatAsState
-import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.withInfiniteAnimationFrameNanos
-import androidx.compose.animation.fadeIn
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.border
 import androidx.compose.foundation.gestures.awaitFirstDown
@@ -34,12 +32,14 @@
 import androidx.compose.foundation.gestures.rememberTransformableState
 import androidx.compose.foundation.gestures.transformable
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxWithConstraints
 import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.ColumnScope
-import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.WindowInsets
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.safeContent
+import androidx.compose.foundation.layout.windowInsetsPadding
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
@@ -49,6 +49,7 @@
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.AbsoluteAlignment.Left
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.geometry.Offset
@@ -59,8 +60,10 @@
 import androidx.compose.ui.graphics.drawscope.translate
 import androidx.compose.ui.input.pointer.PointerEvent
 import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.toUpperCase
 import androidx.compose.ui.tooling.preview.Devices
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
@@ -94,12 +97,12 @@
 val RANDOM_SEED_TYPE = RandomSeedType.Daily
 
 const val FIXED_RANDOM_SEED = 5038L
-const val DEFAULT_CAMERA_ZOOM = 0.25f
+const val DEFAULT_CAMERA_ZOOM = 1f
 const val MIN_CAMERA_ZOOM = 250f / UNIVERSE_RANGE // 0.0025f
 const val MAX_CAMERA_ZOOM = 5f
-const val TOUCH_CAMERA_PAN = false
-const val TOUCH_CAMERA_ZOOM = true
-const val DYNAMIC_ZOOM = false // @@@ FIXME
+var TOUCH_CAMERA_PAN = false
+var TOUCH_CAMERA_ZOOM = false
+var DYNAMIC_ZOOM = false
 
 fun dailySeed(): Long {
     val today = GregorianCalendar()
@@ -134,39 +137,21 @@
 }
 
 @Composable
-fun ColumnScope.ConsoleText(
-    modifier: Modifier = Modifier,
-    visible: Boolean = true,
-    random: Random = Random.Default,
-    text: String
-) {
-    AnimatedVisibility(
-        modifier = modifier,
-        visible = visible,
-        enter =
-            fadeIn(
-                animationSpec =
-                    tween(
-                        durationMillis = 1000,
-                        easing = flickerFadeEasing(random) * CubicBezierEasing(0f, 1f, 1f, 0f)
-                    )
-            )
-    ) {
-        Text(
-            fontFamily = FontFamily.Monospace,
-            fontWeight = FontWeight.Medium,
-            fontSize = 12.sp,
-            color = Color(0xFFFF8000),
-            text = text
-        )
-    }
-}
-
-@Composable
 fun Telemetry(universe: VisibleUniverse) {
     var topVisible by remember { mutableStateOf(false) }
     var bottomVisible by remember { mutableStateOf(false) }
 
+    var catalogFontSize by remember { mutableStateOf(9.sp) }
+
+    val textStyle =
+        TextStyle(
+            fontFamily = FontFamily.Monospace,
+            fontWeight = FontWeight.Medium,
+            fontSize = 12.sp,
+            letterSpacing = 1.sp,
+            lineHeight = 12.sp,
+        )
+
     LaunchedEffect("blah") {
         delay(1000)
         bottomVisible = true
@@ -174,65 +159,109 @@
         topVisible = true
     }
 
-    Column(modifier = Modifier.fillMaxSize().padding(6.dp)) {
-        universe.triggerDraw.value // recompose on every frame
-        val explored = universe.planets.filter { it.explored }
+    universe.triggerDraw.value // recompose on every frame
 
-        AnimatedVisibility(modifier = Modifier, visible = topVisible, enter = flickerFadeIn) {
-            Text(
-                fontFamily = FontFamily.Monospace,
-                fontWeight = FontWeight.Medium,
-                fontSize = 12.sp,
-                color = Colors.Console,
-                modifier = Modifier.align(Left),
-                text =
-                    with(universe.star) {
-                        "  STAR: $name (UDC-${universe.randomSeed % 100_000})\n" +
-                            " CLASS: ${cls.name}\n" +
-                            "RADIUS: ${radius.toInt()}\n" +
-                            "  MASS: %.3g\n".format(mass) +
-                            "BODIES: ${explored.size} / ${universe.planets.size}\n" +
-                            "\n"
-                    } +
-                        explored
-                            .map {
-                                "  BODY: ${it.name}\n" +
-                                    "  TYPE: ${it.description.capitalize()}\n" +
-                                    "  ATMO: ${it.atmosphere.capitalize()}\n" +
-                                    " FAUNA: ${it.fauna.capitalize()}\n" +
-                                    " FLORA: ${it.flora.capitalize()}\n"
-                            }
-                            .joinToString("\n")
+    val explored = universe.planets.filter { it.explored }
 
-                // TODO: different colors, highlight latest discovery
+    BoxWithConstraints(
+        modifier =
+            Modifier.fillMaxSize().padding(6.dp).windowInsetsPadding(WindowInsets.safeContent),
+    ) {
+        val wide = maxWidth > maxHeight
+        Column(
+            modifier =
+                Modifier.align(if (wide) Alignment.BottomEnd else Alignment.BottomStart)
+                    .fillMaxWidth(if (wide) 0.45f else 1.0f)
+        ) {
+            universe.ship.autopilot?.let { autopilot ->
+                if (autopilot.enabled) {
+                    AnimatedVisibility(
+                        modifier = Modifier,
+                        visible = bottomVisible,
+                        enter = flickerFadeIn
+                    ) {
+                        Text(
+                            style = textStyle,
+                            color = Colors.Autopilot,
+                            modifier = Modifier.align(Left),
+                            text = autopilot.telemetry
+                        )
+                    }
+                }
+            }
+
+            AnimatedVisibility(
+                modifier = Modifier,
+                visible = bottomVisible,
+                enter = flickerFadeIn
+            ) {
+                Text(
+                    style = textStyle,
+                    color = Colors.Console,
+                    modifier = Modifier.align(Left),
+                    text =
+                        with(universe.ship) {
+                            val closest = universe.closestPlanet()
+                            val distToClosest = ((closest.pos - pos).mag() - closest.radius).toInt()
+                            listOfNotNull(
+                                    landing?.let {
+                                        "LND: ${it.planet.name.toUpperCase()}\nJOB: ${it.text}"
+                                    }
+                                        ?: if (distToClosest < 10_000) {
+                                            "ALT: $distToClosest"
+                                        } else null,
+                                    "THR: %.0f%%".format(thrust.mag() * 100f),
+                                    "POS: %s".format(pos.str("%+7.0f")),
+                                    "VEL: %.0f".format(velocity.mag())
+                                )
+                                .joinToString("\n")
+                        }
                 )
+            }
         }
 
-        Spacer(modifier = Modifier.weight(1f))
-
-        AnimatedVisibility(modifier = Modifier, visible = bottomVisible, enter = flickerFadeIn) {
+        AnimatedVisibility(
+            modifier = Modifier.align(Alignment.TopStart),
+            visible = topVisible,
+            enter = flickerFadeIn
+        ) {
             Text(
-                fontFamily = FontFamily.Monospace,
-                fontWeight = FontWeight.Medium,
-                fontSize = 12.sp,
+                style = textStyle,
+                fontSize = catalogFontSize,
+                lineHeight = catalogFontSize,
+                letterSpacing = 1.sp,
                 color = Colors.Console,
-                modifier = Modifier.align(Left),
-                text =
-                    with(universe.ship) {
-                        val closest = universe.closestPlanet()
-                        val distToClosest = (closest.pos - pos).mag().toInt()
-                        listOfNotNull(
-                                landing?.let { "LND: ${it.planet.name}" }
-                                    ?: if (distToClosest < 10_000) {
-                                        "ALT: $distToClosest"
-                                    } else null,
-                                if (thrust != Vec2.Zero) "THR: %.0f%%".format(thrust.mag() * 100f)
-                                else null,
-                                "POS: %s".format(pos.str("%+7.0f")),
-                                "VEL: %.0f".format(velocity.mag())
-                            )
-                            .joinToString("\n")
+                onTextLayout = { textLayoutResult ->
+                    if (textLayoutResult.didOverflowHeight) {
+                        catalogFontSize = 8.sp
                     }
+                },
+                text =
+                    (with(universe.star) {
+                            listOf(
+                                "  STAR: $name (UDC-${universe.randomSeed % 100_000})",
+                                " CLASS: ${cls.name}",
+                                "RADIUS: ${radius.toInt()}",
+                                "  MASS: %.3g".format(mass),
+                                "BODIES: ${explored.size} / ${universe.planets.size}",
+                                ""
+                            )
+                        } +
+                            explored
+                                .map {
+                                    listOf(
+                                        "  BODY: ${it.name}",
+                                        "  TYPE: ${it.description.capitalize()}",
+                                        "  ATMO: ${it.atmosphere.capitalize()}",
+                                        " FAUNA: ${it.fauna.capitalize()}",
+                                        " FLORA: ${it.flora.capitalize()}",
+                                        ""
+                                    )
+                                }
+                                .flatten())
+                        .joinToString("\n")
+
+                // TODO: different colors, highlight latest discovery
             )
         }
     }
@@ -246,6 +275,8 @@
 
         onWindowLayoutInfoChange()
 
+        enableEdgeToEdge()
+
         val universe = VisibleUniverse(namer = Namer(resources), randomSeed = randomSeed())
 
         if (TEST_UNIVERSE) {
@@ -254,6 +285,15 @@
             universe.initRandom()
         }
 
+        com.android.egg.ComponentActivationActivity.lockUnlockComponents(applicationContext)
+
+        // for autopilot testing in the activity
+        //        val autopilot = Autopilot(universe.ship, universe)
+        //        universe.ship.autopilot = autopilot
+        //        universe.add(autopilot)
+        //        autopilot.enabled = true
+        //        DYNAMIC_ZOOM = autopilot.enabled
+
         setContent {
             Spaaaace(modifier = Modifier.fillMaxSize(), u = universe, foldState = foldState)
             DebugText(DEBUG_TEXT)
@@ -437,8 +477,13 @@
         val distToNearestSurf = max(0f, (u.ship.pos - closest.pos).mag() - closest.radius * 1.2f)
         //        val normalizedDist = clamp(distToNearestSurf, 50f, 50_000f) / 50_000f
         if (DYNAMIC_ZOOM) {
-            //            cameraZoom = lerp(0.1f, 5f, smooth(1f-normalizedDist))
-            cameraZoom = clamp(500f / distToNearestSurf, MIN_CAMERA_ZOOM, MAX_CAMERA_ZOOM)
+            cameraZoom =
+                expSmooth(
+                    cameraZoom,
+                    clamp(500f / distToNearestSurf, MIN_CAMERA_ZOOM, MAX_CAMERA_ZOOM),
+                    dt = u.dt,
+                    speed = 1.5f
+                )
         } else if (!TOUCH_CAMERA_ZOOM) cameraZoom = DEFAULT_CAMERA_ZOOM
         if (!TOUCH_CAMERA_PAN) cameraOffset = (u.follow?.pos ?: Vec2.Zero) * -1f
 
@@ -478,26 +523,26 @@
                 "star: '${u.star.name}' designation=UDC-${u.randomSeed % 100_000} " +
                 "class=${u.star.cls.name} r=${u.star.radius.toInt()} m=${u.star.mass}\n" +
                 "planets: ${u.planets.size}\n" +
-                    u.planets.joinToString("\n") {
-                        val range = (u.ship.pos - it.pos).mag()
-                        val vorbit = sqrt(GRAVITATION * it.mass / range)
-                        val vescape = sqrt(2 * GRAVITATION * it.mass / it.radius)
-                        " * ${it.name}:\n" +
-                                if (it.explored) {
-                                    "   TYPE:  ${it.description.capitalize()}\n" +
-                                            "   ATMO:  ${it.atmosphere.capitalize()}\n" +
-                                            "   FAUNA: ${it.fauna.capitalize()}\n" +
-                                            "   FLORA: ${it.flora.capitalize()}\n"
-                                } else {
-                                    "   (Unexplored)\n"
-                                } +
-                                "   orbit=${(it.pos - it.orbitCenter).mag().toInt()}" +
-                                " radius=${it.radius.toInt()}" +
-                                " mass=${"%g".format(it.mass)}" +
-                                " vel=${(it.speed).toInt()}" +
-                                " // range=${"%.0f".format(range)}" +
-                                " vorbit=${vorbit.toInt()} vescape=${vescape.toInt()}"
-                    })
+                u.planets.joinToString("\n") {
+                    val range = (u.ship.pos - it.pos).mag()
+                    val vorbit = sqrt(GRAVITATION * it.mass / range)
+                    val vescape = sqrt(2 * GRAVITATION * it.mass / it.radius)
+                    " * ${it.name}:\n" +
+                        if (it.explored) {
+                            "   TYPE:  ${it.description.capitalize()}\n" +
+                                "   ATMO:  ${it.atmosphere.capitalize()}\n" +
+                                "   FAUNA: ${it.fauna.capitalize()}\n" +
+                                "   FLORA: ${it.flora.capitalize()}\n"
+                        } else {
+                            "   (Unexplored)\n"
+                        } +
+                        "   orbit=${(it.pos - it.orbitCenter).mag().toInt()}" +
+                        " radius=${it.radius.toInt()}" +
+                        " mass=${"%g".format(it.mass)}" +
+                        " vel=${(it.speed).toInt()}" +
+                        " // range=${"%.0f".format(range)}" +
+                        " vorbit=${vorbit.toInt()} vescape=${vescape.toInt()}"
+                })
 
         zoom(cameraZoom) {
             // All coordinates are space coordinates now.
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Maths.kt b/packages/EasterEgg/src/com/android/egg/landroid/Maths.kt
index fdf29f7..a1e8212 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/Maths.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Maths.kt
@@ -16,6 +16,7 @@
 
 package com.android.egg.landroid
 
+import kotlin.math.exp
 import kotlin.math.pow
 
 /** smoothstep. Ken Perlin's version */
@@ -32,3 +33,8 @@
 fun lexp(start: Float, end: Float, progress: Float): Float {
     return (progress - start) / (end - start)
 }
+
+/** Exponentially smooth current toward target by a factor of speed. */
+fun expSmooth(current: Float, target: Float, dt: Float = 1f / 60, speed: Float = 5f): Float {
+    return current + (target - current) * (1 - exp(-dt * speed))
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt b/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt
index 67d536e..7331807 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt
@@ -17,9 +17,8 @@
 package com.android.egg.landroid
 
 import android.content.res.Resources
-import kotlin.random.Random
-
 import com.android.egg.R
+import kotlin.random.Random
 
 const val SUFFIX_PROB = 0.75f
 const val LETTER_PROB = 0.3f
@@ -62,6 +61,11 @@
             0.1f to "(^*!%@##!!"
         )
 
+    private var activities = Bag(resources.getStringArray(R.array.activities))
+    private var floraGenericPlurals = Bag(resources.getStringArray(R.array.flora_generic_plurals))
+    private var faunaGenericPlurals = Bag(resources.getStringArray(R.array.fauna_generic_plurals))
+    private var atmoGenericPlurals = Bag(resources.getStringArray(R.array.atmo_generic_plurals))
+
     fun describePlanet(rng: Random): String {
         return planetTable.roll(rng).pull(rng) + " " + planetTypes.pull(rng)
     }
@@ -93,4 +97,30 @@
     fun describeAtmo(rng: Random): String {
         return atmoTable.roll(rng).pull(rng)
     }
+
+    fun floraPlural(rng: Random): String {
+        return floraGenericPlurals.pull(rng)
+    }
+    fun faunaPlural(rng: Random): String {
+        return faunaGenericPlurals.pull(rng)
+    }
+    fun atmoPlural(rng: Random): String {
+        return atmoGenericPlurals.pull(rng)
+    }
+
+    val TEMPLATE_REGEX = Regex("""\{(flora|fauna|planet|atmo)\}""")
+    fun describeActivity(rng: Random, target: Planet?): String {
+        return activities
+            .pull(rng)
+            .replace(TEMPLATE_REGEX) {
+                when (it.groupValues[1]) {
+                    "flora" -> (target?.flora ?: "SOME") + " " + floraPlural(rng)
+                    "fauna" -> (target?.fauna ?: "SOME") + " " + faunaPlural(rng)
+                    "atmo" -> (target?.atmosphere ?: "SOME") + " " + atmoPlural(rng)
+                    "planet" -> (target?.description ?: "SOME BODY") // once told me
+                    else -> "unknown template tag: ${it.groupValues[0]}"
+                }
+            }
+            .toUpperCase()
+    }
 }
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/PathTools.kt b/packages/EasterEgg/src/com/android/egg/landroid/PathTools.kt
index 8510640..cd87335 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/PathTools.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/PathTools.kt
@@ -32,6 +32,13 @@
     }
 }
 
+fun createPolygonPoints(radius: Float, sides: Int): List<Vec2> {
+    val angleStep = PI2f / sides
+    return (0 until sides).map { i ->
+        Vec2(radius * cos(angleStep * i), radius * sin(angleStep * i))
+    }
+}
+
 fun createStar(radius1: Float, radius2: Float, points: Int): Path {
     return Path().apply {
         val angleStep = PI2f / points
@@ -46,15 +53,16 @@
 }
 
 fun Path.parseSvgPathData(d: String) {
-    Regex("([A-Z])([-.,0-9e ]+)").findAll(d.trim()).forEach {
+    Regex("([A-Za-z])\\s*([-.,0-9e ]+)").findAll(d.trim()).forEach {
         val cmd = it.groups[1]!!.value
         val args =
             it.groups[2]?.value?.split(Regex("\\s+"))?.map { v -> v.toFloat() } ?: emptyList()
-        Log.d("Landroid", "cmd = $cmd, args = " + args.joinToString(","))
+        // Log.d("Landroid", "cmd = $cmd, args = " + args.joinToString(","))
         when (cmd) {
             "M" -> moveTo(args[0], args[1])
             "C" -> cubicTo(args[0], args[1], args[2], args[3], args[4], args[5])
             "L" -> lineTo(args[0], args[1])
+            "l" -> relativeLineTo(args[0], args[1])
             "Z" -> close()
             else -> Log.v("Landroid", "unsupported SVG command: $cmd")
         }
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Randomness.kt b/packages/EasterEgg/src/com/android/egg/landroid/Randomness.kt
index ebbb2bd..2903534 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/Randomness.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Randomness.kt
@@ -61,6 +61,7 @@
 /** Return a random float in the range [start, end). */
 fun Random.nextFloatInRange(fromUntil: ClosedFloatingPointRange<Float>): Float =
     nextFloatInRange(fromUntil.start, fromUntil.endInclusive)
+
 /** Return a random float in the range [first, second). */
 fun Random.nextFloatInRange(fromUntil: Pair<Float, Float>): Float =
     nextFloatInRange(fromUntil.first, fromUntil.second)
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt b/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt
index 11dce61..1e54569 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt
@@ -155,10 +155,7 @@
                     speed = speed,
                     color = Colors.Eigengrau4
                 )
-            android.util.Log.v(
-                "Landroid",
-                "created planet $p with period $period and vel $speed"
-            )
+            android.util.Log.v("Landroid", "created planet $p with period $period and vel $speed")
             val num = it + 1
             p.description = "TEST PLANET #$num"
             p.atmosphere = "radius=$radius"
@@ -215,10 +212,7 @@
                     speed = speed,
                     color = Colors.Eigengrau4
                 )
-            android.util.Log.v(
-                "Landroid",
-                "created planet $p with period $period and vel $speed"
-            )
+            android.util.Log.v("Landroid", "created planet $p with period $period and vel $speed")
             p.description = namer.describePlanet(rng)
             p.atmosphere = namer.describeAtmo(rng)
             p.flora = namer.describeLife(rng)
@@ -302,7 +296,7 @@
                     //                        &&
                     //                        vDiff < 100f
                     ) {
-                        val landing = Landing(ship, planet, a)
+                        val landing = Landing(ship, planet, a, namer.describeActivity(rng, planet))
                         ship.landing = landing
                         ship.velocity = planet.velocity
                         add(landing)
@@ -370,12 +364,15 @@
     }
 }
 
-class Landing(val ship: Spacecraft, val planet: Planet, val angle: Float) : Constraint {
-    private val landingVector = Vec2.makeWithAngleMag(angle, ship.radius + planet.radius)
+class Landing(var ship: Spacecraft?, val planet: Planet, val angle: Float, val text: String = "") :
+    Constraint {
     override fun solve(sim: Simulator, dt: Float) {
-        val desiredPos = planet.pos + landingVector
-        ship.pos = (ship.pos * 0.5f) + (desiredPos * 0.5f) // @@@ FIXME
-        ship.angle = angle
+        ship?.let { ship ->
+            val landingVector = Vec2.makeWithAngleMag(angle, ship.radius + planet.radius)
+            val desiredPos = planet.pos + landingVector
+            ship.pos = (ship.pos * 0.5f) + (desiredPos * 0.5f) // @@@ FIXME
+            ship.angle = angle
+        }
     }
 }
 
@@ -435,6 +432,7 @@
     val track = Track()
 
     var landing: Landing? = null
+    var autopilot: Autopilot? = null
 
     init {
         mass = SPACECRAFT_MASS
@@ -448,23 +446,19 @@
             var deltaV = MAIN_ENGINE_ACCEL * dt
             if (SCALED_THRUST) deltaV *= thrustMag.coerceIn(0f, 1f)
 
-            if (landing == null) {
-                // we are free in space, so we attempt to pivot toward the desired direction
-                // NOTE: no longer required thanks to FlightStick
-                // angle = thrust.angle()
-            } else
-                landing?.let { landing ->
-                    if (launchClock == 0f) launchClock = sim.now + 1f /* @@@ TODO extract */
+            // check if we are currently attached to a landing
+            landing?.let { landing ->
+                // launch clock is 1 second long
+                if (launchClock == 0f) launchClock = sim.now + 1f /* @@@ TODO extract */
 
-                    if (sim.now > launchClock) {
-                        // first-stage to orbit has 1000x power
-                        //                    deltaV *= 1000f
-                        sim.remove(landing)
-                        this.landing = null
-                    } else {
-                        deltaV = 0f
-                    }
+                if (sim.now > launchClock) {
+                    // detach from landing site
+                    landing.ship = null
+                    this.landing = null
+                } else {
+                    deltaV = 0f
                 }
+            }
 
             // this is it. impart thrust to the ship.
             // note that we always thrust in the forward direction
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt b/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt
index 6baf36e..974784d 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt
@@ -28,11 +28,10 @@
 import androidx.compose.ui.graphics.drawscope.translate
 import androidx.compose.ui.util.lerp
 import androidx.core.math.MathUtils.clamp
+import com.android.egg.flags.Flags.flagFlag
 import java.lang.Float.max
 import kotlin.math.sqrt
 
-import com.android.egg.flags.Flags.flagFlag
-
 const val DRAW_ORBITS = true
 const val DRAW_GRAVITATIONAL_FIELDS = true
 const val DRAW_STAR_GRAVITATIONAL_FIELDS = true
@@ -71,16 +70,6 @@
     with(universe) {
         triggerDraw.value // Please recompose when this value changes.
 
-        //        star.drawZoomed(ds, zoom)
-        //        planets.forEach { p ->
-        //            p.drawZoomed(ds, zoom)
-        //            if (p == follow) {
-        //                drawCircle(Color.Red, 20f / zoom, p.pos)
-        //            }
-        //        }
-        //
-        //        ship.drawZoomed(ds, zoom)
-
         constraints.forEach {
             when (it) {
                 is Landing -> drawLanding(it)
@@ -89,13 +78,14 @@
         }
         drawStar(star)
         entities.forEach {
-            if (it === ship || it === star) return@forEach // draw the ship last
+            if (it === star) return@forEach // don't draw the star as a planet
             when (it) {
-                is Spacecraft -> drawSpacecraft(it)
                 is Spark -> drawSpark(it)
                 is Planet -> drawPlanet(it)
+                else -> Unit // draw these at a different time, or not at all
             }
         }
+        ship.autopilot?.let { drawAutopilot(it) }
         drawSpacecraft(ship)
     }
 }
@@ -111,15 +101,6 @@
                 pathEffect = PathEffect.dashPathEffect(floatArrayOf(8f / zoom, 8f / zoom), 0f)
             )
     )
-    //    val path = Path().apply {
-    //        fillType = PathFillType.EvenOdd
-    //        addOval(Rect(center = Vec2.Zero, radius = container.radius))
-    //        addOval(Rect(center = Vec2.Zero, radius = container.radius + 10_000))
-    //    }
-    //    drawPath(
-    //        path = path,
-    //
-    //    )
 }
 
 fun ZoomedDrawScope.drawGravitationalField(planet: Planet) {
@@ -226,23 +207,47 @@
 """
         )
     }
-val thrustPath = createPolygon(-3f, 3).also { it.translate(Vec2(-4f, 0f)) }
+val spaceshipLegs =
+    Path().apply {
+        parseSvgPathData(
+            """
+M-7   -6.5
+l-3.5  0
+l-1   -2
+l 0    4
+l 1   -2
+Z
+M-7    6.5
+l-3.5  0
+l-1   -2
+l 0    4
+l 1   -2
+Z
+"""
+        )
+    }
+val thrustPath = createPolygon(-3f, 3).also { it.translate(Vec2(-5f, 0f)) }
 
 fun ZoomedDrawScope.drawSpacecraft(ship: Spacecraft) {
     with(ship) {
         rotateRad(angle, pivot = pos) {
             translate(pos.x, pos.y) {
-                //                drawPath(
-                //                    path = createStar(200f, 100f, 3),
-                //                    color = Color.White,
-                //                    style = Stroke(width = 2f / zoom)
-                //                )
+                // new in V: little landing legs
+                ship.landing?.let {
+                    drawPath(
+                        path = spaceshipLegs,
+                        color = Color(0xFFCCCCCC),
+                        style = Stroke(width = 2f / [email protected])
+                    )
+                }
+                // draw the ship
                 drawPath(path = spaceshipPath, color = Colors.Eigengrau) // fauxpaque
                 drawPath(
                     path = spaceshipPath,
                     color = if (transit) Color.Black else Color.White,
                     style = Stroke(width = 2f / [email protected])
                 )
+                // draw thrust
                 if (thrust != Vec2.Zero) {
                     drawPath(
                         path = thrustPath,
@@ -254,27 +259,8 @@
                             )
                     )
                 }
-                //                drawRect(
-                //                    topLeft = Offset(-1f, -1f),
-                //                    size = Size(2f, 2f),
-                //                    color = Color.Cyan,
-                //                    style = Stroke(width = 2f / zoom)
-                //                )
-                //                drawLine(
-                //                    start = Vec2.Zero,
-                //                    end = Vec2(20f, 0f),
-                //                    color = Color.Cyan,
-                //                    strokeWidth = 2f / zoom
-                //                )
             }
         }
-        //        // DEBUG: draw velocity vector
-        //        drawLine(
-        //            start = pos,
-        //            end = pos + velocity,
-        //            color = Color.Red,
-        //            strokeWidth = 3f / zoom
-        //        )
         drawTrack(track)
     }
 }
@@ -287,14 +273,15 @@
         val height = 80f
         rotateRad(landing.angle, pivot = v) {
             translate(v.x, v.y) {
-                drawPath(
+                val flagPath =
                     Path().apply {
                         moveTo(0f, 0f)
                         lineTo(height, 0f)
                         lineTo(height * 0.875f, height * 0.25f)
                         lineTo(height * 0.75f, 0f)
                         close()
-                    }, Color.Yellow, style = Stroke(width = strokeWidth))
+                    }
+                drawPath(flagPath, Colors.Flag, style = Stroke(width = strokeWidth))
             }
         }
     }
@@ -311,10 +298,7 @@
             Spark.Style.DOT -> drawCircle(color, size, pos)
             Spark.Style.DOT_ABSOLUTE -> drawCircle(color, size, pos / zoom)
             Spark.Style.RING -> drawCircle(color, size, pos, style = Stroke(width = 1f / zoom))
-        //                drawPoints(listOf(pos), PointMode.Points, color, strokeWidth = 2f/zoom)
-        //            drawCircle(color, 2f/zoom, pos)
         }
-        //        drawCircle(Color.Gray, center = pos, radius = 1.5f / zoom)
     }
 }
 
@@ -324,19 +308,9 @@
             drawPoints(
                 positions,
                 pointMode = PointMode.Lines,
-                color = Color.Green,
+                color = Colors.Track,
                 strokeWidth = 1f / zoom
             )
-            //            if (positions.size < 2) return
-            //            drawPath(Path()
-            //                .apply {
-            //                    val p = positions[positions.size - 1]
-            //                    moveTo(p.x, p.y)
-            //                    positions.reversed().subList(1, positions.size).forEach { p ->
-            //                        lineTo(p.x, p.y)
-            //                    }
-            //                },
-            //                color = Color.Green, style = Stroke(1f/zoom))
         } else {
             if (positions.size < 2) return
             var prev: Vec2 = positions[positions.size - 1]
@@ -349,3 +323,43 @@
         }
     }
 }
+
+fun ZoomedDrawScope.drawAutopilot(autopilot: Autopilot) {
+    val color = Colors.Autopilot.copy(alpha = 0.5f)
+
+    autopilot.target?.let { target ->
+        val zoom = zoom
+        rotateRad(autopilot.universe.now * PI2f / 10f, target.pos) {
+            translate(target.pos.x, target.pos.y) {
+                drawPath(
+                    path =
+                        createPolygon(
+                            radius = target.radius + autopilot.brakingDistance,
+                            sides = 15 // Autopilot introduced in Android 15
+                        ),
+                    color = color,
+                    style = Stroke(1f / zoom)
+                )
+                drawCircle(
+                    color,
+                    radius = target.radius + autopilot.landingAltitude / 2,
+                    center = Vec2.Zero,
+                    alpha = 0.25f,
+                    style = Stroke(autopilot.landingAltitude)
+                )
+            }
+        }
+        drawLine(
+            color,
+            start = autopilot.ship.pos,
+            end = autopilot.leadingPos,
+            strokeWidth = 1f / zoom
+        )
+        drawCircle(
+            color,
+            radius = 5f / zoom,
+            center = autopilot.leadingPos,
+            style = Stroke(1f / zoom)
+        )
+    }
+}
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_content_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_content_layout.xml
index 72b569f..9848749 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_content_layout.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v31/collapsing_toolbar_content_layout.xml
@@ -32,21 +32,9 @@
             android:id="@+id/collapsing_toolbar"
             android:layout_width="match_parent"
             android:layout_height="@dimen/settingslib_toolbar_layout_height"
-            android:clipToPadding="false"
-            app:forceApplySystemWindowInsetTop="true"
-            app:extraMultilineHeightEnabled="true"
-            app:contentScrim="@color/settingslib_colorSurfaceHeader"
-            app:maxLines="3"
             app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
-            app:scrimAnimationDuration="50"
-            app:scrimVisibleHeightTrigger="@dimen/settingslib_scrim_visible_height_trigger"
-            app:statusBarScrim="@null"
-            app:titleCollapseMode="fade"
-            app:collapsedTitleTextAppearance="@style/CollapsingToolbarTitle.Collapsed"
-            app:expandedTitleTextAppearance="@style/CollapsingToolbarTitle.Expanded"
-            app:expandedTitleMarginStart="@dimen/expanded_title_margin_start"
-            app:expandedTitleMarginEnd="@dimen/expanded_title_margin_end"
-            app:toolbarId="@id/action_bar">
+            app:toolbarId="@id/action_bar"
+            style="@style/CollapsingToolbarLayoutStyle.SettingsLib">
 
             <Toolbar
                 android:id="@+id/action_bar"
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/dimens.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/dimens.xml
index 15c1abb..40b9fcd 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/dimens.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/dimens.xml
@@ -20,4 +20,5 @@
     <dimen name="settingslib_scrim_visible_height_trigger">137dp</dimen>
     <dimen name="expanded_title_margin_start">24dp</dimen>
     <dimen name="expanded_title_margin_end">24dp</dimen>
+    <dimen name="expanded_title_margin_bottom">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml
index d0b6c4d..afd0d76a 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml
@@ -18,11 +18,27 @@
     <style name="CollapsingToolbarTitle.Collapsed" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
         <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
         <item name="android:textSize">20dp</item>
-        <item name="android:textColor">@color/settingslib_text_color_primary_device_default</item>
     </style>
 
     <style name="CollapsingToolbarTitle.Expanded" parent="CollapsingToolbarTitle.Collapsed">
         <item name="android:textSize">36dp</item>
-        <item name="android:textColor">@color/settingslib_text_color_primary_device_default</item>
+    </style>
+
+    <style name="Base.CollapsingToolbarLayoutStyle.SettingsLib" parent="@style/Widget.Material3.CollapsingToolbar">
+        <item name="expandedTitleTextAppearance">@style/CollapsingToolbarTitle.Expanded</item>
+        <item name="collapsedTitleTextAppearance">@style/CollapsingToolbarTitle.Collapsed</item>
+        <item name="expandedTitleMarginStart">@dimen/expanded_title_margin_start</item>
+        <item name="expandedTitleMarginEnd">@dimen/expanded_title_margin_end</item>
+        <item name="expandedTitleMarginBottom">@dimen/expanded_title_margin_bottom</item>
+        <item name="maxLines">3</item>
+        <item name="scrimVisibleHeightTrigger">@dimen/settingslib_scrim_visible_height_trigger</item>
+        <item name="contentScrim">@color/settingslib_colorSurfaceHeader</item>
+        <item name="statusBarScrim">@null</item>
+        <item name="scrimAnimationDuration">50</item>
+    </style>
+
+    <style name="CollapsingToolbarLayoutStyle.SettingsLib" parent="@style/Base.CollapsingToolbarLayoutStyle.SettingsLib">
+        <item name="collapsedTitleTextColor">@color/settingslib_text_color_primary_device_default</item>
+        <item name="expandedTitleTextColor">@color/settingslib_text_color_primary_device_default</item>
     </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles.xml
index 0c20287..0f71a78 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v35/styles.xml
@@ -15,14 +15,8 @@
   limitations under the License.
 -->
 <resources>
-    <style name="CollapsingToolbarTitle.Collapsed" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
-        <item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
-        <item name="android:textSize">20dp</item>
-        <item name="android:textColor">@color/settingslib_materialColorOnSurface</item>
-    </style>
-
-    <style name="CollapsingToolbarTitle.Expanded" parent="CollapsingToolbarTitle.Collapsed">
-        <item name="android:textSize">36dp</item>
-        <item name="android:textColor">@color/settingslib_materialColorOnSurface</item>
+    <style name="CollapsingToolbarLayoutStyle.SettingsLib" parent="@style/Base.CollapsingToolbarLayoutStyle.SettingsLib">
+        <item name="collapsedTitleTextColor">@color/settingslib_materialColorOnSurface</item>
+        <item name="expandedTitleTextColor">@color/settingslib_materialColorOnSurface</item>
     </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Flows.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Flows.kt
index 83cb549..61b8b7f 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Flows.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Flows.kt
@@ -20,6 +20,7 @@
 import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.flow.combine
@@ -61,10 +62,8 @@
     lifecycleOwner: LifecycleOwner,
     minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
     action: suspend (value: T) -> Unit,
-) {
-    lifecycleOwner.lifecycleScope.launch {
-        lifecycleOwner.repeatOnLifecycle(minActiveState) {
-            collectLatest(action)
-        }
+): Job = lifecycleOwner.lifecycleScope.launch {
+    lifecycleOwner.repeatOnLifecycle(minActiveState) {
+        collectLatest(action)
     }
 }
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
index 120b75e..050527e 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
@@ -68,8 +68,7 @@
     open val permissionHasAppOpFlag: Boolean = true
 
     /** These not changeable packages will also be hidden from app list. */
-    private val notChangeablePackages =
-        setOf("android", "com.android.systemui", context.packageName)
+    private val notChangeablePackages = setOf("com.android.systemui")
 
     private fun createAppOpsPermissionController(app: ApplicationInfo) =
         AppOpsPermissionController(context, app, appOps, permission)
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
index 27e00c0..ea6a272 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
@@ -110,7 +110,7 @@
     app: ApplicationInfo,
 ) {
     val record = remember { transformItem(app) }
-    if (!remember { isChangeable(record) }) return
+    if (!remember { isChangeableWithSystemUidCheck(record) }) return
     val context = LocalContext.current
     val internalListModel = remember {
         TogglePermissionInternalAppListModel(
@@ -178,6 +178,6 @@
 private fun <T : AppRecord> TogglePermissionAppListModel<T>.rememberIsChangeable(record: T) =
     remember(record) {
         flow {
-            emit(isChangeable(record))
+            emit(isChangeableWithSystemUidCheck(record))
         }.flowOn(Dispatchers.Default)
     }.collectAsStateWithLifecycle(initialValue = false)
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
index 3f7a852..2a04424 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
@@ -18,6 +18,7 @@
 
 import android.content.Context
 import android.content.pm.ApplicationInfo
+import android.os.Process
 import androidx.compose.runtime.Composable
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
@@ -79,9 +80,26 @@
     fun setAllowed(record: T, newAllowed: Boolean)
 
     @Composable
-    fun InfoPageAdditionalContent(record: T, isAllowed: () -> Boolean?){}
+    fun InfoPageAdditionalContent(record: T, isAllowed: () -> Boolean?) {}
 }
 
+/**
+ * And if the given app has system or root UID.
+ *
+ * If true, the app gets all permissions, so the permission toggle always not changeable.
+ */
+fun AppRecord.isSystemOrRootUid(): Boolean = app.uid in listOf(Process.SYSTEM_UID, Process.ROOT_UID)
+
+/**
+ * Gets whether the permission on / off is changeable for the given app.
+ *
+ * And if the given app has system or root UID, it gets all permissions, so always not changeable.
+ */
+fun <T : AppRecord> TogglePermissionAppListModel<T>.isChangeableWithSystemUidCheck(
+    record: T,
+): Boolean = !record.isSystemOrRootUid() && isChangeable(record)
+
+
 interface TogglePermissionAppListProvider {
     val permissionType: String
 
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
index 2e8b76a..57102ba 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
@@ -33,6 +33,7 @@
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.compose.rememberContext
+import com.android.settingslib.spa.framework.util.filterItem
 import com.android.settingslib.spa.framework.util.getStringArg
 import com.android.settingslib.spa.widget.preference.Preference
 import com.android.settingslib.spa.widget.preference.PreferenceModel
@@ -143,7 +144,7 @@
         listModel.transform(userIdFlow, appListFlow)
 
     override fun filter(userIdFlow: Flow<Int>, option: Int, recordListFlow: Flow<List<T>>) =
-        listModel.filter(userIdFlow, recordListFlow)
+        listModel.filter(userIdFlow, recordListFlow.filterItem { !it.isSystemOrRootUid() })
 
     @Composable
     override fun getSummary(option: Int, record: T) = getSummary(record)
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
index 9d12fc7..60eccd9 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt
@@ -278,7 +278,7 @@
         const val PERMISSION = "PERMISSION"
         const val BROADER_PERMISSION = "BROADER_PERMISSION"
         val APP = ApplicationInfo().apply { packageName = PACKAGE_NAME }
-        val NOT_CHANGEABLE_APP = ApplicationInfo().apply { packageName = "android" }
+        val NOT_CHANGEABLE_APP = ApplicationInfo().apply { packageName = "com.android.systemui" }
     }
 }
 
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
index 270b3fa..d7147b5 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
@@ -228,6 +228,7 @@
         const val PACKAGE_NAME = "package.name"
         val APP = ApplicationInfo().apply {
             packageName = PACKAGE_NAME
+            uid = 11000
         }
         val PACKAGE_INFO = PackageInfo().apply {
             packageName = PACKAGE_NAME
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index 1706a6f..4125a81f 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -101,7 +101,6 @@
         Settings.Global.Wearable.AMBIENT_TILT_TO_WAKE,
         Settings.Global.Wearable.AMBIENT_TOUCH_TO_WAKE,
         Settings.Global.Wearable.GESTURE_TOUCH_AND_HOLD_WATCH_FACE_ENABLED,
-        Settings.Global.Wearable.BATTERY_SAVER_MODE,
         Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_MS,
         Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_SET_BY_USER,
         Settings.Global.Wearable.DYNAMIC_COLOR_THEME_ENABLED,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 4ec170d..c6ae96e 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -595,6 +595,7 @@
                     Settings.Global.Wearable.MOBILE_SIGNAL_DETECTOR,
                     Settings.Global.Wearable.AMBIENT_LOW_BIT_ENABLED_DEV,
                     Settings.Global.Wearable.AMBIENT_TILT_TO_BRIGHT,
+                    Settings.Global.Wearable.BATTERY_SAVER_MODE,
                     Settings.Global.Wearable.DECOMPOSABLE_WATCHFACE,
                     Settings.Global.Wearable.AMBIENT_FORCE_WHEN_DOCKED,
                     Settings.Global.Wearable.AMBIENT_LOW_BIT_ENABLED,
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 919d7f0..f84f627 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -991,6 +991,16 @@
 }
 
 flag {
+  namespace: "systemui"
+  name: "privacy_dot_unfold_wrong_corner_fix"
+  description: "Fixes an issue where the privacy dot is at the wrong corner after unfolding/folding."
+  bug: "339335643"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "validate_keyboard_shortcut_helper_icon_uri"
   namespace: "systemui"
   description: "Adds a check that the caller can access the content URI of an icon in the shortcut helper."
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
index 64ace2f..54f3969 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
@@ -24,6 +24,7 @@
 import androidx.compose.animation.core.animateDpAsState
 import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.animation.core.tween
+import androidx.compose.foundation.focusable
 import androidx.compose.foundation.gestures.detectTapGestures
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.aspectRatio
@@ -41,6 +42,8 @@
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
 import androidx.compose.ui.geometry.CornerRadius
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.graphicsLayer
@@ -284,6 +287,8 @@
         contentAlignment = Alignment.Center,
         modifier =
             modifier
+                .focusRequester(FocusRequester.Default)
+                .focusable()
                 .sizeIn(maxWidth = pinButtonMaxSize, maxHeight = pinButtonMaxSize)
                 .aspectRatio(1f)
                 .drawBehind {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index 33a630c..312890e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -29,7 +29,6 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.WindowInsets
 import androidx.compose.foundation.layout.asPaddingValues
 import androidx.compose.foundation.layout.displayCutoutPadding
@@ -314,7 +313,6 @@
                                     content(Modifier.weight(1f))
                                 }
                             }
-                            Spacer(modifier = Modifier.height(16.dp))
                         }
                     },
                     {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index f0fb9f6..11d3841 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -33,9 +33,9 @@
 import androidx.compose.ui.layout.ApproachLayoutModifierNode
 import androidx.compose.ui.layout.ApproachMeasureScope
 import androidx.compose.ui.layout.LayoutCoordinates
-import androidx.compose.ui.layout.LookaheadScope
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasureResult
+import androidx.compose.ui.layout.MeasureScope
 import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.node.DrawModifierNode
 import androidx.compose.ui.node.ModifierNodeElement
@@ -248,13 +248,34 @@
     }
 
     @ExperimentalComposeUiApi
+    override fun MeasureScope.measure(
+        measurable: Measurable,
+        constraints: Constraints
+    ): MeasureResult {
+        check(isLookingAhead)
+
+        return measurable.measure(constraints).run {
+            // Update the size this element has in this scene when idle.
+            sceneState.targetSize = size()
+
+            layout(width, height) {
+                // Update the offset (relative to the SceneTransitionLayout) this element has in
+                // this scene when idle.
+                coordinates?.let { coords ->
+                    with(layoutImpl.lookaheadScope) {
+                        sceneState.targetOffset =
+                            lookaheadScopeCoordinates.localLookaheadPositionOf(coords)
+                    }
+                }
+                place(0, 0)
+            }
+        }
+    }
+
     override fun ApproachMeasureScope.approachMeasure(
         measurable: Measurable,
         constraints: Constraints,
     ): MeasureResult {
-        // Update the size this element has in this scene when idle.
-        sceneState.targetSize = lookaheadSize
-
         val transitions = currentTransitions
         val transition = elementTransition(element, transitions)
 
@@ -272,15 +293,7 @@
             val placeable = measurable.measure(constraints)
             sceneState.lastSize = placeable.size()
 
-            this as LookaheadScope
-            return layout(placeable.width, placeable.height) {
-                // Update the offset (relative to the SceneTransitionLayout) this element has in
-                // this scene when idle.
-                coordinates?.let { coords ->
-                    sceneState.targetOffset =
-                        lookaheadScopeCoordinates.localLookaheadPositionOf(coords)
-                }
-            }
+            return layout(placeable.width, placeable.height) { /* Do not place */ }
         }
 
         val placeable =
@@ -294,7 +307,6 @@
                 transition,
                 sceneState,
                 placeable,
-                placementScope = this,
             )
         }
     }
@@ -541,8 +553,7 @@
             transition = transition,
             fromSceneZIndex = layoutImpl.scenes.getValue(fromScene).zIndex,
             toSceneZIndex = layoutImpl.scenes.getValue(toScene).zIndex,
-        )
-            ?: return false
+        ) ?: return false
 
     return pickedScene == scene || transition.currentOverscrollSpec?.scene == scene
 }
@@ -797,23 +808,19 @@
 }
 
 @OptIn(ExperimentalComposeUiApi::class)
-private fun ApproachMeasureScope.place(
+private fun Placeable.PlacementScope.place(
     layoutImpl: SceneTransitionLayoutImpl,
     scene: Scene,
     element: Element,
     transition: TransitionState.Transition?,
     sceneState: Element.SceneState,
     placeable: Placeable,
-    placementScope: Placeable.PlacementScope,
 ) {
-    this as LookaheadScope
-
-    with(placementScope) {
+    with(layoutImpl.lookaheadScope) {
         // Update the offset (relative to the SceneTransitionLayout) this element has in this scene
         // when idle.
         val coords = coordinates ?: error("Element ${element.key} does not have any coordinates")
         val targetOffsetInScene = lookaheadScopeCoordinates.localLookaheadPositionOf(coords)
-        sceneState.targetOffset = targetOffsetInScene
 
         // No need to place the element in this scene if we don't want to draw it anyways.
         if (!shouldPlaceElement(layoutImpl, scene, element, transition)) {
@@ -985,10 +992,10 @@
 
     val transformation =
         transformation(transition.transformationSpec.transformations(element.key, scene.key))
-        // If there is no transformation explicitly associated to this element value, let's use
-        // the value given by the system (like the current position and size given by the layout
-        // pass).
-        ?: return currentValue()
+            // If there is no transformation explicitly associated to this element value, let's use
+            // the value given by the system (like the current position and size given by the layout
+            // pass).
+            ?: return currentValue()
 
     // Get the transformed value, i.e. the target value at the beginning (for entering elements) or
     // end (for leaving elements) of the transition.
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index 2946b04..b925130 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -56,7 +56,7 @@
     modifier: Modifier = Modifier,
     swipeSourceDetector: SwipeSourceDetector = DefaultEdgeDetector,
     swipeDetector: SwipeDetector = DefaultSwipeDetector,
-    @FloatRange(from = 0.0, to = 0.5) transitionInterceptionThreshold: Float = 0f,
+    @FloatRange(from = 0.0, to = 0.5) transitionInterceptionThreshold: Float = 0.05f,
     scenes: SceneTransitionLayoutScope.() -> Unit,
 ) {
     SceneTransitionLayoutForTesting(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index 5fa7c87..f32720c 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -107,6 +107,13 @@
                     _userActionDistanceScope = it
                 }
 
+    /**
+     * The [LookaheadScope] of this layout, that can be used to compute offsets relative to the
+     * layout.
+     */
+    internal lateinit var lookaheadScope: LookaheadScope
+        private set
+
     init {
         updateScenes(builder)
 
@@ -195,6 +202,8 @@
                 .then(LayoutElement(layoutImpl = this))
         ) {
             LookaheadScope {
+                lookaheadScope = this
+
                 BackHandler()
 
                 scenesToCompose().fastForEach { scene -> key(scene.key) { scene.Content() } }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt
index 124ec29..b54afae 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredSize.kt
@@ -41,15 +41,20 @@
         value: IntSize,
     ): IntSize {
         fun anchorSizeIn(scene: SceneKey): IntSize {
-            val size = layoutImpl.elements[anchor]?.sceneStates?.get(scene)?.targetSize
-            return if (size != null && size != Element.SizeUnspecified) {
-                IntSize(
-                    width = if (anchorWidth) size.width else value.width,
-                    height = if (anchorHeight) size.height else value.height,
-                )
-            } else {
-                value
-            }
+            val size =
+                layoutImpl.elements[anchor]?.sceneStates?.get(scene)?.targetSize?.takeIf {
+                    it != Element.SizeUnspecified
+                }
+                    ?: throwMissingAnchorException(
+                        transformation = "AnchoredSize",
+                        anchor = anchor,
+                        scene = scene,
+                    )
+
+            return IntSize(
+                width = if (anchorWidth) size.width else value.width,
+                height = if (anchorHeight) size.height else value.height,
+            )
         }
 
         // This simple implementation assumes that the size of [element] is the same as the size of
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt
index 7aa702b..2bab4f8 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/AnchoredTranslate.kt
@@ -39,7 +39,15 @@
         transition: TransitionState.Transition,
         value: Offset,
     ): Offset {
-        val anchor = layoutImpl.elements[anchor] ?: return value
+        fun throwException(scene: SceneKey?): Nothing {
+            throwMissingAnchorException(
+                transformation = "AnchoredTranslate",
+                anchor = anchor,
+                scene = scene,
+            )
+        }
+
+        val anchor = layoutImpl.elements[anchor] ?: throwException(scene = null)
         fun anchorOffsetIn(scene: SceneKey): Offset? {
             return anchor.sceneStates[scene]?.targetOffset?.takeIf { it.isSpecified }
         }
@@ -47,8 +55,10 @@
         // [element] will move the same amount as [anchor] does.
         // TODO(b/290184746): Also support anchors that are not shared but translated because of
         // other transformations, like an edge translation.
-        val anchorFromOffset = anchorOffsetIn(transition.fromScene) ?: return value
-        val anchorToOffset = anchorOffsetIn(transition.toScene) ?: return value
+        val anchorFromOffset =
+            anchorOffsetIn(transition.fromScene) ?: throwException(transition.fromScene)
+        val anchorToOffset =
+            anchorOffsetIn(transition.toScene) ?: throwException(transition.toScene)
         val offset = anchorToOffset - anchorFromOffset
 
         return if (scene.key == transition.toScene) {
@@ -64,3 +74,20 @@
         }
     }
 }
+
+internal fun throwMissingAnchorException(
+    transformation: String,
+    anchor: ElementKey,
+    scene: SceneKey?,
+): Nothing {
+    error(
+        """
+        Anchor ${anchor.debugName} does not have a target state in scene ${scene?.debugName}.
+        This either means that it was not composed at all during the transition or that it was
+        composed too late, for instance during layout/subcomposition. To avoid flickers in
+        $transformation, you should make sure that the composition and layout of anchor is *not*
+        deferred, for instance by moving it out of lazy layouts.
+    """
+            .trimIndent()
+    )
+}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/AnchoredTranslateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/AnchoredTranslateTest.kt
index d1205e7..46075c3 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/AnchoredTranslateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/AnchoredTranslateTest.kt
@@ -27,6 +27,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.compose.animation.scene.TestElements
 import com.android.compose.animation.scene.testTransition
+import com.android.compose.animation.scene.transition
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -83,4 +84,28 @@
             after { onElement(TestElements.Bar).assertPositionInRootIsEqualTo(20.dp, 40.dp) }
         }
     }
+
+    @Test
+    fun anchorPlacedAfterAnchoredElement() {
+        rule.testTransition(
+            fromSceneContent = { Box(Modifier.offset(10.dp, 50.dp).element(TestElements.Foo)) },
+            toSceneContent = {
+                Box(Modifier.offset(20.dp, 40.dp).element(TestElements.Bar))
+                Box(Modifier.offset(30.dp, 10.dp).element(TestElements.Foo))
+            },
+            transition = {
+                spec = tween(16 * 4, easing = LinearEasing)
+                anchoredTranslate(TestElements.Bar, TestElements.Foo)
+            },
+        ) {
+            // No exception is thrown even if Bar is placed before the anchor in toScene.
+            before { onElement(TestElements.Bar).assertDoesNotExist() }
+            at(0) { onElement(TestElements.Bar).assertPositionInRootIsEqualTo(0.dp, 80.dp) }
+            at(16) { onElement(TestElements.Bar).assertPositionInRootIsEqualTo(5.dp, 70.dp) }
+            at(32) { onElement(TestElements.Bar).assertPositionInRootIsEqualTo(10.dp, 60.dp) }
+            at(48) { onElement(TestElements.Bar).assertPositionInRootIsEqualTo(15.dp, 50.dp) }
+            at(64) { onElement(TestElements.Bar).assertPositionInRootIsEqualTo(20.dp, 40.dp) }
+            after { onElement(TestElements.Bar).assertPositionInRootIsEqualTo(20.dp, 40.dp) }
+        }
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index ffa63d8..e42a67b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -295,7 +295,7 @@
             val targets = listOf(target1, target2, target3)
             smartspaceRepository.setCommunalSmartspaceTargets(targets)
 
-            val smartspaceContent by collectLastValue(underTest.ongoingContent)
+            val smartspaceContent by collectLastValue(underTest.getOngoingContent(true))
             assertThat(smartspaceContent?.size).isEqualTo(1)
             assertThat(smartspaceContent?.get(0)?.key)
                 .isEqualTo(CommunalContentModel.KEY.smartspace("target3"))
@@ -393,7 +393,7 @@
 
             smartspaceRepository.setCommunalSmartspaceTargets(targets)
 
-            val smartspaceContent by collectLastValue(underTest.ongoingContent)
+            val smartspaceContent by collectLastValue(underTest.getOngoingContent(true))
             assertThat(smartspaceContent?.size).isEqualTo(totalTargets)
             for (index in 0 until totalTargets) {
                 assertThat(smartspaceContent?.get(index)?.size).isEqualTo(expectedSizes[index])
@@ -409,7 +409,7 @@
             // Media is playing.
             mediaRepository.mediaActive()
 
-            val umoContent by collectLastValue(underTest.ongoingContent)
+            val umoContent by collectLastValue(underTest.getOngoingContent(true))
 
             assertThat(umoContent?.size).isEqualTo(1)
             assertThat(umoContent?.get(0)).isInstanceOf(CommunalContentModel.Umo::class.java)
@@ -417,6 +417,20 @@
         }
 
     @Test
+    fun umo_mediaPlaying_doNotShowUmo() =
+        testScope.run {
+            // Tutorial completed.
+            tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
+
+            // Media is playing.
+            mediaRepository.mediaActive()
+
+            val umoContent by collectLastValue(underTest.getOngoingContent(false))
+
+            assertThat(umoContent?.size).isEqualTo(0)
+        }
+
+    @Test
     fun ongoing_shouldOrderAndSizeByTimestamp() =
         testScope.runTest {
             // Keyguard showing, and tutorial completed.
@@ -439,7 +453,7 @@
             val timer3 = smartspaceTimer("timer3", timestamp = 4L)
             smartspaceRepository.setCommunalSmartspaceTargets(listOf(timer1, timer2, timer3))
 
-            val ongoingContent by collectLastValue(underTest.ongoingContent)
+            val ongoingContent by collectLastValue(underTest.getOngoingContent(true))
             assertThat(ongoingContent?.size).isEqualTo(4)
             assertThat(ongoingContent?.get(0)?.key)
                 .isEqualTo(CommunalContentModel.KEY.smartspace("timer3"))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index 9dcea82..e7a7b15 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -46,6 +46,7 @@
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel.Companion.POPUP_AUTO_HIDE_TIMEOUT_MS
 import com.android.systemui.communal.ui.viewmodel.PopupType
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
 import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
 import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.flags.fakeFeatureFlagsClassic
@@ -61,6 +62,7 @@
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
@@ -142,11 +144,13 @@
             selectedUserIndex = 0,
         )
         whenever(providerInfo.profile).thenReturn(UserHandle(MAIN_USER_INFO.id))
+        whenever(mediaHost.visible).thenReturn(true)
 
         kosmos.powerInteractor.setAwakeForTest()
 
         underTest =
             CommunalViewModel(
+                kosmos.testDispatcher,
                 testScope,
                 context.resources,
                 kosmos.keyguardTransitionInteractor,
@@ -235,6 +239,45 @@
         }
 
     @Test
+    fun communalContent_mediaHostVisible_umoIncluded() =
+        testScope.runTest {
+            // Media playing.
+            mediaRepository.mediaActive()
+
+            val communalContent by collectLastValue(underTest.communalContent)
+            assertThat(communalContent?.size).isEqualTo(2)
+            assertThat(communalContent?.get(0)).isInstanceOf(CommunalContentModel.Umo::class.java)
+        }
+
+    @Test
+    fun communalContent_mediaHostVisible_umoExcluded() =
+        testScope.runTest {
+            whenever(mediaHost.visible).thenReturn(false)
+            mediaHost.updateViewVisibility()
+            // Media playing.
+            mediaRepository.mediaActive()
+
+            val communalContent by collectLastValue(underTest.communalContent)
+            assertThat(communalContent?.size).isEqualTo(1)
+            assertThat(communalContent?.get(0))
+                .isInstanceOf(CommunalContentModel.CtaTileInViewMode::class.java)
+        }
+
+    @Test
+    fun communalContent_mediaHostVisible_umoToggle() =
+        testScope.runTest {
+            mediaHost.updateViewVisibility()
+            mediaRepository.mediaActive()
+
+            val communalContent by collectValues(underTest.communalContent)
+
+            whenever(mediaHost.visible).thenReturn(false)
+            mediaHost.updateViewVisibility()
+
+            assertThat(communalContent.size).isEqualTo(1)
+        }
+
+    @Test
     fun isEmptyState_isTrue_noWidgetButActiveLiveContent() =
         testScope.runTest {
             tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
index 4849e66..c51413a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.qsTileFactory
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.TestScope
@@ -42,7 +41,6 @@
 
     private val kosmos = testKosmos()
     private val vibratorHelper = kosmos.vibratorHelper
-    private val qsTile = kosmos.qsTileFactory.createTile("Test Tile")
 
     private val effectDuration = 400
     private val lowTickDuration = 12
@@ -63,7 +61,6 @@
                 vibratorHelper,
                 kosmos.keyguardInteractor,
             )
-        longPressEffect.qsTile = qsTile
     }
 
     @Test
@@ -94,10 +91,8 @@
         // GIVEN an action down event occurs
         longPressEffect.handleActionDown()
 
-        // THEN the effect moves to the TIMEOUT_WAIT state and starts the wait
-        val action by collectLastValue(longPressEffect.actionType)
+        // THEN the effect moves to the TIMEOUT_WAIT state
         assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.TIMEOUT_WAIT)
-        assertThat(action).isEqualTo(QSLongPressEffect.ActionType.WAIT_TAP_TIMEOUT)
     }
 
     @Test
@@ -112,6 +107,20 @@
         }
 
     @Test
+    fun onActionUp_whileWaiting_performsClick() =
+        testWhileInState(QSLongPressEffect.State.TIMEOUT_WAIT) {
+            // GIVEN an action is being collected
+            val action by collectLastValue(longPressEffect.actionType)
+
+            // GIVEN an action up occurs
+            longPressEffect.handleActionUp()
+
+            // THEN the action to invoke is the click action and the effect does not start
+            assertThat(action).isEqualTo(QSLongPressEffect.ActionType.CLICK)
+            assertEffectDidNotStart()
+        }
+
+    @Test
     fun onWaitComplete_whileWaiting_beginsEffect() =
         testWhileInState(QSLongPressEffect.State.TIMEOUT_WAIT) {
             // GIVEN the pressed timeout is complete
@@ -212,10 +221,8 @@
             // GIVEN that the animator was cancelled
             longPressEffect.handleAnimationCancel()
 
-            // THEN the state goes to the timeout wait and the wait is posted
-            val action by collectLastValue(longPressEffect.actionType)
+            // THEN the state goes to the timeout wait
             assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.TIMEOUT_WAIT)
-            assertThat(action).isEqualTo(QSLongPressEffect.ActionType.WAIT_TAP_TIMEOUT)
         }
 
     @Test
@@ -231,29 +238,6 @@
             assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.IDLE)
         }
 
-    @Test
-    fun onTileClick_whileWaiting_withQSTile_clicks() =
-        testWhileInState(QSLongPressEffect.State.TIMEOUT_WAIT) {
-            // GIVEN that a click was detected
-            val couldClick = longPressEffect.onTileClick()
-
-            // THEN the click is successful
-            assertThat(couldClick).isTrue()
-        }
-
-    @Test
-    fun onTileClick_whileWaiting_withoutQSTile_cannotClick() =
-        testWhileInState(QSLongPressEffect.State.TIMEOUT_WAIT) {
-            // GIVEN that no QSTile has been set
-            longPressEffect.qsTile = null
-
-            // GIVEN that a click was detected
-            val couldClick = longPressEffect.onTileClick()
-
-            // THEN the click is not successful
-            assertThat(couldClick).isFalse()
-        }
-
     private fun testWithScope(initialize: Boolean = true, test: suspend TestScope.() -> Unit) =
         with(kosmos) {
             testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelTest.kt
index bf3231e..79671b8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModelTest.kt
@@ -53,7 +53,7 @@
     @Test
     fun lockscreenAlpha() =
         testScope.runTest {
-            val viewState = ViewStateAccessor()
+            val viewState = ViewStateAccessor(alpha = { 0.6f })
             val alpha by collectValues(underTest.lockscreenAlpha(viewState))
 
             keyguardTransitionRepository.sendTransitionSteps(
@@ -62,9 +62,11 @@
                 testScope
             )
 
-            // Remain at zero throughout
-            assertThat(alpha[0]).isEqualTo(0f)
+            assertThat(alpha[0]).isEqualTo(0.6f)
+            // Fades out just prior to halfway
             assertThat(alpha[1]).isEqualTo(0f)
+            // Must finish at 0
+            assertThat(alpha[2]).isEqualTo(0f)
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/PrivacyDotViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/PrivacyDotViewControllerTest.kt
index 4340971..f126432 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/PrivacyDotViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/events/PrivacyDotViewControllerTest.kt
@@ -18,14 +18,19 @@
 
 import android.graphics.Point
 import android.graphics.Rect
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.testing.TestableLooper.RunWithLooper
 import android.view.Display
 import android.view.DisplayAdjustments
 import android.view.View
 import android.widget.FrameLayout
+import android.widget.FrameLayout.LayoutParams.UNSPECIFIED_GRAVITY
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.FakeStatusBarStateController
 import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
 import com.android.systemui.statusbar.policy.FakeConfigurationController
@@ -291,14 +296,61 @@
         assertThat(controller.currentViewState.designatedCorner).isEqualTo(bottomRightView)
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_PRIVACY_DOT_UNFOLD_WRONG_CORNER_FIX)
+    fun initialize_newViews_fixFlagEnabled_gravityIsUpdated() {
+        val newTopLeftView = initDotView()
+        val newTopRightView = initDotView()
+        val newBottomLeftView = initDotView()
+        val newBottomRightView = initDotView()
+        setRotation(ROTATION_LANDSCAPE) // Bottom right used in landscape
+
+        val controller = createAndInitializeController()
+        // Re-init with different views, but same rotation
+        controller.initialize(
+            newTopLeftView,
+            newTopRightView,
+            newBottomLeftView,
+            newBottomRightView
+        )
+
+        assertThat((newBottomRightView.layoutParams as FrameLayout.LayoutParams).gravity)
+            .isNotEqualTo(UNSPECIFIED_GRAVITY)
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_PRIVACY_DOT_UNFOLD_WRONG_CORNER_FIX)
+    fun initialize_newViews_fixFlagDisabled_gravityIsNotUpdated() {
+        val newTopLeftView = initDotView()
+        val newTopRightView = initDotView()
+        val newBottomLeftView = initDotView()
+        val newBottomRightView = initDotView()
+        setRotation(ROTATION_LANDSCAPE) // Bottom right used in landscape
+
+        val controller = createAndInitializeController()
+        // Re-init with different views, but same rotation
+        controller.initialize(
+            newTopLeftView,
+            newTopRightView,
+            newBottomLeftView,
+            newBottomRightView
+        )
+
+        assertThat((newBottomRightView.layoutParams as FrameLayout.LayoutParams).gravity)
+            .isEqualTo(UNSPECIFIED_GRAVITY)
+    }
+
     private fun setRotation(rotation: Int) {
         whenever(mockDisplay.rotation).thenReturn(rotation)
     }
 
-    private fun initDotView(): View =
-        View(context).also {
+    private fun initDotView(): View {
+        val privacyDot = View(context).also { it.id = R.id.privacy_dot }
+        return FrameLayout(context).also {
             it.layoutParams = FrameLayout.LayoutParams(/* width = */ 0, /* height = */ 0)
+            it.addView(privacyDot)
         }
+    }
 
     private fun enableRtl() {
         configurationController.notifyLayoutDirectionChanged(isRtl = true)
diff --git a/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml b/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml
index 9f4ad0e..ce205ca 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml
@@ -29,10 +29,11 @@
         android:layout_gravity="center_vertical"
         android:layout_marginStart="24dp"
         android:layout_marginBottom="8dp"
-        android:ellipsize="end"
-        android:maxLines="2"
         android:visibility="invisible"
+        app:layout_constrainedWidth="true"
         app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="@id/button_center_guideline"
+        app:layout_constraintHorizontal_bias="0.0"
         app:layout_constraintStart_toStartOf="parent" />
 
     <!-- Cancel Button, replaces negative button when biometric is accepted -->
@@ -46,7 +47,10 @@
         android:layout_marginBottom="8dp"
         android:text="@string/cancel"
         android:visibility="invisible"
+        app:layout_constrainedWidth="true"
         app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="@id/button_center_guideline"
+        app:layout_constraintHorizontal_bias="0.0"
         app:layout_constraintStart_toStartOf="parent" />
 
     <!-- "Use Credential" Button, replaces if device credential is allowed -->
@@ -59,7 +63,10 @@
         android:layout_marginStart="24dp"
         android:layout_marginBottom="8dp"
         android:visibility="invisible"
+        app:layout_constrainedWidth="true"
         app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="@id/button_center_guideline"
+        app:layout_constraintHorizontal_bias="0.0"
         app:layout_constraintStart_toStartOf="parent" />
 
     <!-- Positive Button -->
@@ -71,12 +78,13 @@
         android:layout_gravity="center_vertical"
         android:layout_marginEnd="24dp"
         android:layout_marginBottom="8dp"
-        android:ellipsize="end"
-        android:maxLines="2"
         android:text="@string/biometric_dialog_confirm"
         android:visibility="invisible"
+        app:layout_constrainedWidth="true"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent" />
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="1.0"
+        app:layout_constraintStart_toStartOf="@id/button_center_guideline" />
 
     <!-- Try Again Button -->
     <Button
@@ -87,11 +95,19 @@
         android:layout_gravity="center_vertical"
         android:layout_marginEnd="24dp"
         android:layout_marginBottom="8dp"
-        android:ellipsize="end"
-        android:maxLines="2"
         android:text="@string/biometric_dialog_try_again"
         android:visibility="invisible"
+        app:layout_constrainedWidth="true"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent" />
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="1.0"
+        app:layout_constraintStart_toStartOf="@id/button_center_guideline" />
+
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/button_center_guideline"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintGuide_percent="0.5" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
index 8d50bfa..4670f34 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
@@ -27,7 +27,6 @@
         app:layout_constraintTop_toTopOf="@id/topBarrier"
         app:layout_constraintWidth_max="@dimen/biometric_prompt_panel_max_width" />
 
-
     <include
         android:id="@+id/button_bar"
         layout="@layout/biometric_prompt_button_bar"
@@ -148,9 +147,10 @@
     <TextView
         android:id="@+id/indicator"
         style="@style/TextAppearance.AuthCredential.Indicator"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_marginTop="24dp"
+        android:layout_marginHorizontal="24dp"
         android:accessibilityLiveRegion="assertive"
         android:fadingEdge="horizontal"
         android:gravity="center_horizontal"
diff --git a/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
index 01b9f7e..c599f9e 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
@@ -179,11 +179,13 @@
         android:fadingEdge="horizontal"
         android:gravity="center_horizontal"
         android:scrollHorizontally="true"
+        android:maxLines="2"
         app:layout_constraintBottom_toTopOf="@+id/button_bar"
         app:layout_constraintEnd_toEndOf="@+id/biometric_icon"
         app:layout_constraintStart_toStartOf="@+id/biometric_icon"
         app:layout_constraintTop_toBottomOf="@+id/biometric_icon"
-        app:layout_constraintVertical_bias="0.0" />
+        app:layout_constraintVertical_bias="0.0"
+        app:layout_constraintWidth_max="@dimen/biometric_dialog_indicator_max_width" />
 
     <include
         android:id="@+id/button_bar"
diff --git a/packages/SystemUI/res/raw/widget.rec b/packages/SystemUI/res/raw/widget.rec
deleted file mode 100644
index a38b23b..0000000
--- a/packages/SystemUI/res/raw/widget.rec
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f6ab4c8..d308c3d 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1101,6 +1101,7 @@
     <dimen name="biometric_dialog_button_negative_max_width">160dp</dimen>
     <dimen name="biometric_dialog_button_positive_max_width">136dp</dimen>
     <dimen name="biometric_dialog_corner_size">28dp</dimen>
+    <dimen name="biometric_dialog_indicator_max_width">280dp</dimen>
     <!-- Y translation when showing/dismissing the dialog-->
     <dimen name="biometric_dialog_animation_translation_offset">350dp</dimen>
     <dimen name="biometric_dialog_border_padding">4dp</dimen>
@@ -1117,9 +1118,7 @@
     <dimen name="biometric_prompt_panel_max_width">640dp</dimen>
     <dimen name="biometric_prompt_land_small_horizontal_guideline_padding">344dp</dimen>
     <dimen name="biometric_prompt_two_pane_udfps_horizontal_guideline_padding">114dp</dimen>
-    <dimen name="biometric_prompt_two_pane_udfps_mid_guideline_padding">409dp</dimen>
     <dimen name="biometric_prompt_two_pane_medium_horizontal_guideline_padding">640dp</dimen>
-    <dimen name="biometric_prompt_two_pane_medium_mid_guideline_padding">330dp</dimen>
     <dimen name="biometric_prompt_one_pane_medium_top_guideline_padding">119dp</dimen>
     <dimen name="biometric_prompt_one_pane_medium_horizontal_guideline_padding">0dp</dimen>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index cac2df5b..effaaf2 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -905,6 +905,10 @@
     <!-- Hearing devices -->
     <!-- QuickSettings: Hearing devices [CHAR LIMIT=NONE] -->
     <string name="quick_settings_hearing_devices_label">Hearing devices</string>
+    <!-- QuickSettings: Hearing Devices' secondary label shown when the hearing aids are currently connected. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_hearing_devices_connected">Active</string>
+    <!-- QuickSettings: Hearing devices' secondary label shown when there is no connected hearing aids. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_hearing_devices_disconnected">Disconnected</string>
     <!-- QuickSettings: Quick Settings Hearing devices dialog title [CHAR LIMIT=30] -->
     <string name="quick_settings_hearing_devices_dialog_title">Hearing devices</string>
     <!-- QuickSettings: Hearing devices dialog pair new device [CHAR LIMIT=NONE]-->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.kt
index dcf7754..757760f 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.kt
@@ -70,10 +70,10 @@
 
         @JvmStatic
         fun wrap(taskIds: IntArray?, snapshots: Array<TaskSnapshot>?): HashMap<Int, ThumbnailData> {
-            return if (taskIds == null || snapshots == null || taskIds.size != snapshots.size) {
-                HashMap()
-            } else {
-                HashMap(taskIds.associateWith { taskId -> fromSnapshot(snapshots[taskId]) })
+            return hashMapOf<Int, ThumbnailData>().apply {
+                if (taskIds != null && snapshots != null && taskIds.size == snapshots.size) {
+                    repeat(snapshots.size) { put(taskIds[it], fromSnapshot(snapshots[it])) }
+                }
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 1ee4908..177aad9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -552,8 +552,6 @@
         }
 
         mWakefulnessLifecycle.addObserver(this);
-        mPanelInteractionDetector.enable(
-                () -> animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED));
         if (constraintBp()) {
             // Do nothing on attachment with constraintLayout
         } else if (mPromptViewModel.getPromptKind().getValue().isBiometric()) {
@@ -566,6 +564,8 @@
         }
 
         if (!constraintBp()) {
+            mPanelInteractionDetector.enable(
+                    () -> animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED));
             updatePositionByCapability(false /* invalidate */);
         }
 
@@ -977,7 +977,7 @@
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
+                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                 windowFlags,
                 PixelFormat.TRANSLUCENT);
         lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index fb718d3..85b5faf 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -34,6 +34,7 @@
 import android.content.IntentFilter;
 import android.graphics.Rect;
 import android.hardware.biometrics.BiometricFingerprintConstants;
+import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.SensorProperties;
 import android.hardware.display.DisplayManager;
 import android.hardware.fingerprint.FingerprintManager;
@@ -43,7 +44,9 @@
 import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
 import android.hardware.input.InputManager;
 import android.os.Build;
+import android.os.CancellationSignal;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.PowerManager;
 import android.os.Trace;
 import android.os.VibrationAttributes;
@@ -382,6 +385,26 @@
             UdfpsController.this.mFingerprintManager.onUdfpsUiEvent(
                     FingerprintManager.UDFPS_UI_READY, requestId, sensorId);
         }
+
+        /**
+         * Debug to show biometric prompt
+         */
+        public void debugBiometricPrompt() {
+            final BiometricPrompt.AuthenticationCallback authenticationCallback =
+                    new BiometricPrompt.AuthenticationCallback() {
+                    };
+
+            final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(mContext)
+                    .setTitle("Test")
+                    .setDeviceCredentialAllowed(true)
+                    .setAllowBackgroundAuthentication(true)
+                    .build();
+            final Handler handler = new Handler(Looper.getMainLooper());
+            biometricPrompt.authenticate(
+                    new CancellationSignal(),
+                    handler::post,
+                    authenticationCallback);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
index 88b9e1b..f5e3d29 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
@@ -45,16 +45,13 @@
 private const val MINOR = 10F
 private const val MAJOR = 10F
 
-/**
- * Used to show and hide the UDFPS overlay with statusbar commands.
- */
+/** Used to show and hide the UDFPS overlay with statusbar commands. */
 @SysUISingleton
-class UdfpsShell @Inject constructor(
-    commandRegistry: CommandRegistry
-) : Command {
+class UdfpsShell @Inject constructor(commandRegistry: CommandRegistry) : Command {
 
     /**
      * Set in [UdfpsController.java] constructor, used to show and hide the UDFPS overlay.
+     *
      * TODO: inject after b/229290039 is resolved
      */
     var udfpsOverlayController: UdfpsController.UdfpsOverlayController? = null
@@ -76,6 +73,8 @@
             simFingerDown()
         } else if (args.size == 1 && args[0] == "simFingerUp") {
             simFingerUp()
+        } else if (args.size == 1 && args[0] == "biometricPrompt") {
+            launchBiometricPrompt()
         } else {
             invalidCommand(pw)
         }
@@ -85,8 +84,10 @@
         pw.println("Usage: adb shell cmd statusbar udfps <cmd>")
         pw.println("Supported commands:")
         pw.println("  - show <reason>")
-        pw.println("    -> supported reasons: [enroll-find-sensor, enroll-enrolling, auth-bp, " +
-                            "auth-keyguard, auth-other, auth-settings]")
+        pw.println(
+            "    -> supported reasons: [enroll-find-sensor, enroll-enrolling, auth-bp, " +
+                "auth-keyguard, auth-other, auth-settings]"
+        )
         pw.println("    -> reason otherwise defaults to unknown")
         pw.println("  - hide")
         pw.println("  - onUiReady")
@@ -94,6 +95,8 @@
         pw.println("    -> Simulates onFingerDown on sensor")
         pw.println("  - simFingerUp")
         pw.println("    -> Simulates onFingerUp on sensor")
+        pw.println("  - biometricPrompt")
+        pw.println("    -> Shows Biometric Prompt")
     }
 
     private fun invalidCommand(pw: PrintWriter) {
@@ -115,14 +118,14 @@
 
     private fun showOverlay(reason: Int) {
         udfpsOverlayController?.showUdfpsOverlay(
-                REQUEST_ID,
-                SENSOR_ID,
-                reason,
-                object : IUdfpsOverlayControllerCallback.Stub() {
-                    override fun onUserCanceled() {
-                        Log.e(TAG, "User cancelled")
-                    }
+            REQUEST_ID,
+            SENSOR_ID,
+            reason,
+            object : IUdfpsOverlayControllerCallback.Stub() {
+                override fun onUserCanceled() {
+                    Log.e(TAG, "User cancelled")
                 }
+            }
         )
     }
 
@@ -130,6 +133,9 @@
         udfpsOverlayController?.hideUdfpsOverlay(SENSOR_ID)
     }
 
+    private fun launchBiometricPrompt() {
+        udfpsOverlayController?.debugBiometricPrompt()
+    }
 
     @VisibleForTesting
     fun onUiReady() {
@@ -140,12 +146,24 @@
     fun simFingerDown() {
         val sensorBounds: Rect = udfpsOverlayController!!.sensorBounds
 
-        val downEvent: MotionEvent? = obtainMotionEvent(ACTION_DOWN, sensorBounds.exactCenterX(),
-                sensorBounds.exactCenterY(), MINOR, MAJOR)
+        val downEvent: MotionEvent? =
+            obtainMotionEvent(
+                ACTION_DOWN,
+                sensorBounds.exactCenterX(),
+                sensorBounds.exactCenterY(),
+                MINOR,
+                MAJOR
+            )
         udfpsOverlayController?.debugOnTouch(downEvent)
 
-        val moveEvent: MotionEvent? = obtainMotionEvent(ACTION_MOVE, sensorBounds.exactCenterX(),
-                sensorBounds.exactCenterY(), MINOR, MAJOR)
+        val moveEvent: MotionEvent? =
+            obtainMotionEvent(
+                ACTION_MOVE,
+                sensorBounds.exactCenterX(),
+                sensorBounds.exactCenterY(),
+                MINOR,
+                MAJOR
+            )
         udfpsOverlayController?.debugOnTouch(moveEvent)
 
         downEvent?.recycle()
@@ -156,18 +174,24 @@
     fun simFingerUp() {
         val sensorBounds: Rect = udfpsOverlayController!!.sensorBounds
 
-        val upEvent: MotionEvent? = obtainMotionEvent(ACTION_UP, sensorBounds.exactCenterX(),
-                sensorBounds.exactCenterY(), MINOR, MAJOR)
+        val upEvent: MotionEvent? =
+            obtainMotionEvent(
+                ACTION_UP,
+                sensorBounds.exactCenterX(),
+                sensorBounds.exactCenterY(),
+                MINOR,
+                MAJOR
+            )
         udfpsOverlayController?.debugOnTouch(upEvent)
         upEvent?.recycle()
     }
 
     private fun obtainMotionEvent(
-            action: Int,
-            x: Float,
-            y: Float,
-            minor: Float,
-            major: Float
+        action: Int,
+        x: Float,
+        y: Float,
+        minor: Float,
+        major: Float
     ): MotionEvent? {
         val pp = MotionEvent.PointerProperties()
         pp.id = 1
@@ -176,7 +200,21 @@
         pc.y = y
         pc.touchMinor = minor
         pc.touchMajor = major
-        return MotionEvent.obtain(0, 0, action, 1, arrayOf(pp), arrayOf(pc),
-                0, 0, 1f, 1f, 0, 0, 0, 0)
+        return MotionEvent.obtain(
+            0,
+            0,
+            action,
+            1,
+            arrayOf(pp),
+            arrayOf(pc),
+            0,
+            0,
+            1f,
+            1f,
+            0,
+            0,
+            0,
+            0
+        )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index c836f89..628b533 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -367,21 +367,21 @@
                                 smallConstraintSet.setGuidelineEnd(topGuideline.id, abs(bounds.top))
                             }
 
-                            // Use rect bottom to set mid guideline of two-pane.
                             if (midGuideline != null) {
-                                if (bounds.bottom >= 0) {
-                                    midGuideline.setGuidelineEnd(bounds.bottom)
-                                    mediumConstraintSet.setGuidelineEnd(
-                                        midGuideline.id,
-                                        bounds.bottom
-                                    )
-                                } else if (bounds.bottom < 0) {
-                                    midGuideline.setGuidelineBegin(abs(bounds.bottom))
-                                    mediumConstraintSet.setGuidelineBegin(
-                                        midGuideline.id,
-                                        abs(bounds.bottom)
-                                    )
-                                }
+                                val left =
+                                    if (bounds.left >= 0) {
+                                        bounds.left
+                                    } else {
+                                        view.width - abs(bounds.left)
+                                    }
+                                val right =
+                                    if (bounds.right >= 0) {
+                                        view.width - abs(bounds.right)
+                                    } else {
+                                        bounds.right
+                                    }
+                                val mid = (left + right) / 2
+                                mediumConstraintSet.setGuidelineBegin(midGuideline.id, mid)
                             }
                         }
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index c17b83d..a39a74f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -306,10 +306,6 @@
         context.resources.getDimensionPixelSize(
             R.dimen.biometric_prompt_two_pane_udfps_horizontal_guideline_padding
         )
-    private val udfpsMidGuidelinePadding =
-        context.resources.getDimensionPixelSize(
-            R.dimen.biometric_prompt_two_pane_udfps_mid_guideline_padding
-        )
     private val mediumTopGuidelinePadding =
         context.resources.getDimensionPixelSize(
             R.dimen.biometric_prompt_one_pane_medium_top_guideline_padding
@@ -318,10 +314,6 @@
         context.resources.getDimensionPixelSize(
             R.dimen.biometric_prompt_two_pane_medium_horizontal_guideline_padding
         )
-    private val mediumMidGuidelinePadding =
-        context.resources.getDimensionPixelSize(
-            R.dimen.biometric_prompt_two_pane_medium_mid_guideline_padding
-        )
 
     /** Rect for positioning biometric icon */
     val iconPosition: Flow<Rect> =
@@ -449,7 +441,7 @@
         }
 
     /**
-     * Rect for positioning prompt guidelines (left, top, right, mid)
+     * Rect for positioning prompt guidelines (left, top, right, unused)
      *
      * Negative values are used to signify that guideline measuring should be flipped, measuring
      * from opposite side of the screen
@@ -472,22 +464,17 @@
                         if (size.isSmall) {
                             Rect(-smallHorizontalGuidelinePadding, 0, 0, 0)
                         } else if (modalities.hasUdfps) {
-                            Rect(udfpsHorizontalGuidelinePadding, 0, 0, udfpsMidGuidelinePadding)
+                            Rect(udfpsHorizontalGuidelinePadding, 0, 0, 0)
                         } else {
-                            Rect(-mediumHorizontalGuidelinePadding, 0, 0, mediumMidGuidelinePadding)
+                            Rect(-mediumHorizontalGuidelinePadding, 0, 0, 0)
                         }
                     PromptPosition.Left ->
                         if (size.isSmall) {
                             Rect(0, 0, -smallHorizontalGuidelinePadding, 0)
                         } else if (modalities.hasUdfps) {
-                            Rect(0, 0, udfpsHorizontalGuidelinePadding, -udfpsMidGuidelinePadding)
+                            Rect(0, 0, udfpsHorizontalGuidelinePadding, 0)
                         } else {
-                            Rect(
-                                0,
-                                0,
-                                -mediumHorizontalGuidelinePadding,
-                                -mediumMidGuidelinePadding
-                            )
+                            Rect(0, 0, -mediumHorizontalGuidelinePadding, 0)
                         }
                     PromptPosition.Top -> Rect()
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index 2be28ca..fdb40fb 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -98,7 +98,7 @@
     broadcastDispatcher: BroadcastDispatcher,
     private val widgetRepository: CommunalWidgetRepository,
     private val communalPrefsRepository: CommunalPrefsRepository,
-    mediaRepository: CommunalMediaRepository,
+    private val mediaRepository: CommunalMediaRepository,
     smartspaceRepository: SmartspaceRepository,
     keyguardInteractor: KeyguardInteractor,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
@@ -479,40 +479,41 @@
      * A flow of ongoing content, including smartspace timers and umo, ordered by creation time and
      * sized dynamically.
      */
-    val ongoingContent: Flow<List<CommunalContentModel.Ongoing>> =
+    fun getOngoingContent(mediaHostVisible: Boolean): Flow<List<CommunalContentModel.Ongoing>> =
         combine(smartspaceTargets, mediaRepository.mediaModel) { smartspace, media ->
-            val ongoingContent = mutableListOf<CommunalContentModel.Ongoing>()
+                val ongoingContent = mutableListOf<CommunalContentModel.Ongoing>()
 
-            // Add smartspace
-            ongoingContent.addAll(
-                smartspace.map { target ->
-                    CommunalContentModel.Smartspace(
-                        smartspaceTargetId = target.smartspaceTargetId,
-                        remoteViews = target.remoteViews!!,
-                        createdTimestampMillis = target.creationTimeMillis,
+                // Add smartspace
+                ongoingContent.addAll(
+                    smartspace.map { target ->
+                        CommunalContentModel.Smartspace(
+                            smartspaceTargetId = target.smartspaceTargetId,
+                            remoteViews = target.remoteViews!!,
+                            createdTimestampMillis = target.creationTimeMillis,
+                        )
+                    }
+                )
+
+                // Add UMO
+                if (mediaHostVisible && media.hasActiveMediaOrRecommendation) {
+                    ongoingContent.add(
+                        CommunalContentModel.Umo(
+                            createdTimestampMillis = media.createdTimestampMillis,
+                        )
                     )
                 }
-            )
 
-            // Add UMO
-            if (media.hasActiveMediaOrRecommendation) {
-                ongoingContent.add(
-                    CommunalContentModel.Umo(
-                        createdTimestampMillis = media.createdTimestampMillis,
-                    )
-                )
+                // Order by creation time descending
+                ongoingContent.sortByDescending { it.createdTimestampMillis }
+
+                // Dynamic sizing
+                ongoingContent.forEachIndexed { index, model ->
+                    model.size = dynamicContentSize(ongoingContent.size, index)
+                }
+
+                ongoingContent
             }
-
-            // Order by creation time descending
-            ongoingContent.sortByDescending { it.createdTimestampMillis }
-
-            // Dynamic sizing
-            ongoingContent.forEachIndexed { index, model ->
-                model.size = dynamicContentSize(ongoingContent.size, index)
-            }
-
-            return@combine ongoingContent
-        }
+            .flowOn(bgDispatcher)
 
     /**
      * Filter and retain widgets associated with an existing user, safeguarding against displaying
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index 3e00b04..c6fa5a84 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -42,12 +42,15 @@
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
 import com.android.systemui.util.kotlin.BooleanFlowOperators.not
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
 import javax.inject.Inject
 import javax.inject.Named
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
+import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -56,8 +59,10 @@
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.launch
 
 /** The default view model used for showing the communal hub. */
@@ -66,6 +71,7 @@
 class CommunalViewModel
 @Inject
 constructor(
+    @Main val mainDispatcher: CoroutineDispatcher,
     @Application private val scope: CoroutineScope,
     @Main private val resources: Resources,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
@@ -79,6 +85,18 @@
     @CommunalLog logBuffer: LogBuffer,
 ) : BaseCommunalViewModel(communalSceneInteractor, communalInteractor, mediaHost) {
 
+    private val _isMediaHostVisible =
+        conflatedCallbackFlow<Boolean> {
+                val callback = { visible: Boolean ->
+                    trySend(visible)
+                    Unit
+                }
+                mediaHost.addVisibilityChangeListener(callback)
+                awaitClose { mediaHost.removeVisibilityChangeListener(callback) }
+            }
+            .onStart { emit(mediaHost.visible) }
+            .flowOn(mainDispatcher)
+
     private val logger = Logger(logBuffer, "CommunalViewModel")
 
     /** Communal content saved from the previous emission when the flow is active (not "frozen"). */
@@ -91,8 +109,10 @@
                 if (isTutorialMode) {
                     return@flatMapLatest flowOf(communalInteractor.tutorialContent)
                 }
+                val ongoingContent =
+                    _isMediaHostVisible.flatMapLatest { communalInteractor.getOngoingContent(it) }
                 combine(
-                    communalInteractor.ongoingContent,
+                    ongoingContent,
                     communalInteractor.widgetContent,
                     communalInteractor.ctaTileContent,
                 ) { ongoing, widgets, ctaTile,
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
index 30b9583..ea8d7d7 100644
--- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
+++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
@@ -19,9 +19,7 @@
 import android.os.VibrationEffect
 import android.view.View
 import androidx.annotation.VisibleForTesting
-import com.android.systemui.animation.Expandable
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.statusbar.VibratorHelper
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -53,10 +51,6 @@
     var state = State.IDLE
         private set
 
-    /** The QSTile and Expandable used to perform a long-click and click actions */
-    var qsTile: QSTile? = null
-    var expandable: Expandable? = null
-
     /** Flow for view control and action */
     private val _postedActionType = MutableStateFlow<ActionType?>(null)
     val actionType: Flow<ActionType?> =
@@ -111,7 +105,6 @@
         when (state) {
             State.IDLE -> {
                 setState(State.TIMEOUT_WAIT)
-                _postedActionType.value = ActionType.WAIT_TAP_TIMEOUT
             }
             State.RUNNING_BACKWARDS -> _postedActionType.value = ActionType.CANCEL_ANIMATOR
             else -> {}
@@ -119,9 +112,16 @@
     }
 
     fun handleActionUp() {
-        if (state == State.RUNNING_FORWARD) {
-            _postedActionType.value = ActionType.REVERSE_ANIMATOR
-            setState(State.RUNNING_BACKWARDS)
+        when (state) {
+            State.TIMEOUT_WAIT -> {
+                _postedActionType.value = ActionType.CLICK
+                setState(State.IDLE)
+            }
+            State.RUNNING_FORWARD -> {
+                _postedActionType.value = ActionType.REVERSE_ANIMATOR
+                setState(State.RUNNING_BACKWARDS)
+            }
+            else -> {}
         }
     }
 
@@ -129,7 +129,6 @@
         when (state) {
             State.TIMEOUT_WAIT -> {
                 setState(State.IDLE)
-                clearActionType()
             }
             State.RUNNING_FORWARD -> {
                 _postedActionType.value = ActionType.REVERSE_ANIMATOR
@@ -146,23 +145,18 @@
 
     /** This function is called both when an animator completes or gets cancelled */
     fun handleAnimationComplete() {
-        when (state) {
-            State.RUNNING_FORWARD -> {
-                setState(State.IDLE)
-                vibrate(snapEffect)
-                _postedActionType.value = ActionType.LONG_PRESS
-            }
-            State.RUNNING_BACKWARDS -> {
-                setState(State.IDLE)
-                clearActionType()
-            }
-            else -> {}
+        if (state == State.RUNNING_FORWARD) {
+            vibrate(snapEffect)
+            _postedActionType.value = ActionType.LONG_PRESS
+        }
+        if (state != State.TIMEOUT_WAIT) {
+            // This will happen if the animator did not finish by being cancelled
+            setState(State.IDLE)
         }
     }
 
     fun handleAnimationCancel() {
         setState(State.TIMEOUT_WAIT)
-        _postedActionType.value = ActionType.WAIT_TAP_TIMEOUT
     }
 
     fun handleTimeoutComplete() {
@@ -196,22 +190,9 @@
                 effectDuration
             )
         setState(State.IDLE)
-        clearActionType()
         return true
     }
 
-    fun onTileClick(): Boolean {
-        if (state == State.TIMEOUT_WAIT) {
-            setState(State.IDLE)
-            clearActionType()
-            qsTile?.let {
-                it.click(expandable)
-                return true
-            }
-        }
-        return false
-    }
-
     enum class State {
         IDLE, /* The effect is idle waiting for touch input */
         TIMEOUT_WAIT, /* The effect is waiting for a [PRESSED_TIMEOUT] period */
@@ -221,7 +202,7 @@
 
     /* A type of action to perform on the view depending on the effect's state and logic */
     enum class ActionType {
-        WAIT_TAP_TIMEOUT,
+        CLICK,
         LONG_PRESS,
         RESET_AND_LONG_PRESS,
         START_ANIMATOR,
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt
index 92a55ef..4875f48 100644
--- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt
@@ -17,6 +17,8 @@
 package com.android.systemui.haptics.qs
 
 import android.animation.ValueAnimator
+import android.annotation.SuppressLint
+import android.view.MotionEvent
 import android.view.ViewConfiguration
 import android.view.animation.AccelerateDecelerateInterpolator
 import androidx.core.animation.doOnCancel
@@ -28,7 +30,6 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.qs.tileimpl.QSTileViewImpl
 import kotlinx.coroutines.DisposableHandle
-import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.filterNotNull
 
 object QSLongPressEffectViewBinder {
@@ -40,6 +41,9 @@
     ): DisposableHandle? {
         if (qsLongPressEffect == null) return null
 
+        // Set the touch listener as the long-press effect
+        setTouchListener(tile, qsLongPressEffect)
+
         return tile.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.CREATED) {
                 // Action to perform
@@ -48,18 +52,18 @@
 
                     qsLongPressEffect.actionType.filterNotNull().collect { action ->
                         when (action) {
-                            QSLongPressEffect.ActionType.WAIT_TAP_TIMEOUT -> {
-                                delay(ViewConfiguration.getTapTimeout().toLong())
-                                qsLongPressEffect.handleTimeoutComplete()
+                            QSLongPressEffect.ActionType.CLICK -> {
+                                tile.performClick()
+                                qsLongPressEffect.clearActionType()
                             }
                             QSLongPressEffect.ActionType.LONG_PRESS -> {
                                 tile.prepareForLaunch()
-                                qsLongPressEffect.qsTile?.longClick(qsLongPressEffect.expandable)
+                                tile.performLongClick()
                                 qsLongPressEffect.clearActionType()
                             }
                             QSLongPressEffect.ActionType.RESET_AND_LONG_PRESS -> {
                                 tile.resetLongPressEffectProperties()
-                                qsLongPressEffect.qsTile?.longClick(qsLongPressEffect.expandable)
+                                tile.performLongClick()
                                 qsLongPressEffect.clearActionType()
                             }
                             QSLongPressEffect.ActionType.START_ANIMATOR -> {
@@ -102,4 +106,22 @@
             }
         }
     }
+
+    @SuppressLint("ClickableViewAccessibility")
+    private fun setTouchListener(tile: QSTileViewImpl, longPressEffect: QSLongPressEffect?) {
+        tile.setOnTouchListener { _, event ->
+            when (event.actionMasked) {
+                MotionEvent.ACTION_DOWN -> {
+                    tile.postDelayed(
+                        { longPressEffect?.handleTimeoutComplete() },
+                        ViewConfiguration.getTapTimeout().toLong(),
+                    )
+                    longPressEffect?.handleActionDown()
+                }
+                MotionEvent.ACTION_UP -> longPressEffect?.handleActionUp()
+                MotionEvent.ACTION_CANCEL -> longPressEffect?.handleActionCancel()
+            }
+            true
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index f3692bd..f5e98f1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.util.kotlin.Utils.Companion.sample
-import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineDispatcher
@@ -66,7 +65,6 @@
 
     override fun start() {
         listenForDozingToAny()
-        listenForDozingToGoneViaBiometrics()
         listenForWakeFromDozing()
         listenForTransitionToCamera(scope, keyguardInteractor)
     }
@@ -79,35 +77,6 @@
             isKeyguardDismissible && !isKeyguardShowing
         }
 
-    private fun listenForDozingToGoneViaBiometrics() {
-        if (KeyguardWmStateRefactor.isEnabled) {
-            return
-        }
-
-        // This is separate from `listenForDozingToAny` because any delay on wake and unlock will
-        // cause a noticeable issue with animations
-        scope.launch {
-            powerInteractor.isAwake
-                .filterRelevantKeyguardStateAnd { isAwake -> isAwake }
-                .sample(
-                    keyguardInteractor.biometricUnlockState,
-                    ::Pair,
-                )
-                .collect {
-                    (
-                        _,
-                        biometricUnlockState,
-                    ) ->
-                    if (isWakeAndUnlock(biometricUnlockState.mode)) {
-                        startTransitionTo(
-                            KeyguardState.GONE,
-                            ownerReason = "biometric wake and unlock",
-                        )
-                    }
-                }
-        }
-    }
-
     private fun listenForDozingToAny() {
         if (KeyguardWmStateRefactor.isEnabled) {
             return
@@ -118,6 +87,7 @@
                 .debounce(50L)
                 .filterRelevantKeyguardStateAnd { isAwake -> isAwake }
                 .sample(
+                    keyguardInteractor.biometricUnlockState,
                     keyguardInteractor.isKeyguardOccluded,
                     communalInteractor.isIdleOnCommunal,
                     canTransitionToGoneOnWake,
@@ -126,6 +96,7 @@
                 .collect {
                     (
                         _,
+                        biometricUnlockState,
                         occluded,
                         isIdleOnCommunal,
                         canTransitionToGoneOnWake,
@@ -133,6 +104,8 @@
                     startTransitionTo(
                         if (!deviceEntryRepository.isLockscreenEnabled()) {
                             KeyguardState.GONE
+                        } else if (isWakeAndUnlock(biometricUnlockState.mode)) {
+                            KeyguardState.GONE
                         } else if (canTransitionToGoneOnWake) {
                             KeyguardState.GONE
                         } else if (primaryBouncerShowing) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModel.kt
index 480f948..77ebfce 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGoneTransitionViewModel.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import android.util.MathUtils
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.domain.interactor.FromDozingTransitionInteractor.Companion.TO_GONE_DURATION
 import com.android.systemui.keyguard.shared.model.Edge
@@ -49,10 +50,12 @@
             )
 
     fun lockscreenAlpha(viewState: ViewStateAccessor): Flow<Float> {
+        var startAlpha = 1f
         return transitionAnimation.sharedFlow(
             duration = 200.milliseconds,
-            onStart = { 0f },
-            onStep = { 0f },
+            onStart = { startAlpha = viewState.alpha() },
+            onStep = { MathUtils.lerp(startAlpha, 0f, it) },
+            onFinish = { 0f },
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
index edead51..a70bf91 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
@@ -42,7 +42,6 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.Dumpable
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
@@ -124,7 +123,6 @@
 class MediaCarouselController
 @Inject
 constructor(
-    @Application applicationScope: CoroutineScope,
     private val context: Context,
     private val mediaControlPanelFactory: Provider<MediaControlPanel>,
     private val visualStabilityProvider: VisualStabilityProvider,
@@ -389,12 +387,12 @@
             repeatOnLifecycle(Lifecycle.State.STARTED) {
                 listenForAnyStateToGoneKeyguardTransition(this)
                 listenForAnyStateToLockscreenTransition(this)
+                listenForLockscreenSettingChanges(this)
 
                 if (!mediaFlags.isSceneContainerEnabled()) return@repeatOnLifecycle
                 listenForMediaItemsChanges(this)
             }
         }
-        listenForLockscreenSettingChanges(applicationScope)
 
         // Notifies all active players about animation scale changes.
         globalSettings.registerContentObserverSync(
@@ -884,7 +882,8 @@
                     val previousVisibleIndex =
                         MediaPlayerData.playerKeys().indexOfFirst { key -> it == key }
                     mediaCarouselScrollHandler.scrollToPlayer(previousVisibleIndex, mediaIndex)
-                } ?: mediaCarouselScrollHandler.scrollToPlayer(destIndex = mediaIndex)
+                }
+                    ?: mediaCarouselScrollHandler.scrollToPlayer(destIndex = mediaIndex)
             }
         } else if (isRtl && mediaContent.childCount > 0) {
             // In RTL, Scroll to the first player as it is the rightmost player in media carousel.
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 9e31379..0a880293 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -23,7 +23,6 @@
 import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
 import static android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN;
 import static android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
-import static android.appwidget.flags.Flags.drawDataParcel;
 import static android.appwidget.flags.Flags.generatedPreviews;
 import static android.content.Intent.ACTION_BOOT_COMPLETED;
 import static android.content.Intent.ACTION_PACKAGE_ADDED;
@@ -72,7 +71,6 @@
 import android.content.pm.ShortcutInfo;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -113,8 +111,6 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.wm.shell.bubbles.Bubbles;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -1456,54 +1452,13 @@
         if (DEBUG) {
             Log.d(TAG, "Updating People Space widget preview for user " + user.getIdentifier());
         }
-        if (!drawDataParcel() || (!Build.IS_USERDEBUG && !Build.IS_ENG)) {
-            updateGeneratedPreviewForUserInternal(provider, user,
-                    new RemoteViews(mContext.getPackageName(),
-                        R.layout.people_space_placeholder_layout));
-        } else {
-            mBgExecutor.execute(updateGeneratedPreviewFromDrawInstructionsForUser(provider, user));
-        }
-    }
-
-    private void updateGeneratedPreviewForUserInternal(@NonNull final ComponentName provider,
-            @NonNull final UserHandle user, @NonNull final RemoteViews rv) {
         boolean success = mAppWidgetManager.setWidgetPreview(
                 provider, WIDGET_CATEGORY_HOME_SCREEN | WIDGET_CATEGORY_KEYGUARD,
-                rv);
+                new RemoteViews(mContext.getPackageName(),
+                        R.layout.people_space_placeholder_layout));
         if (DEBUG && !success) {
             Log.d(TAG, "Failed to update generated preview for user " + user.getIdentifier());
         }
         mUpdatedPreviews.put(user.getIdentifier(), success);
     }
-
-    private Runnable updateGeneratedPreviewFromDrawInstructionsForUser(
-            @NonNull final ComponentName provider, @NonNull final UserHandle user) {
-        return () -> {
-            if (DEBUG) {
-                Log.d(TAG, "Parsing People Space widget preview from binary for user "
-                        + user.getIdentifier());
-            }
-            if (!generatedPreviews() || mUpdatedPreviews.get(user.getIdentifier())
-                    || !mUserManager.isUserUnlocked(user)) {
-                // Conditions may have changed given this is called from background thread
-                return;
-            }
-            try (InputStream is = mContext.getResources().openRawResource(R.raw.widget)
-            ) {
-                final byte[] preview = new byte[(int) is.available()];
-                final int result = is.read(preview);
-                if (DEBUG && result == -1) {
-                    Log.d(TAG, "Failed parsing previews from binary for user "
-                            + user.getIdentifier());
-                }
-                updateGeneratedPreviewForUserInternal(provider, user, new RemoteViews(
-                        new RemoteViews.DrawInstructions.Builder(
-                                Collections.singletonList(preview)).build()));
-            } catch (IOException e) {
-                if (DEBUG) {
-                    Log.e(TAG, "Failed to generate preview for people widget", e);
-                }
-            }
-        };
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 762dacd..1143c30 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -19,7 +19,6 @@
 import android.animation.ArgbEvaluator
 import android.animation.PropertyValuesHolder
 import android.animation.ValueAnimator
-import android.annotation.SuppressLint
 import android.content.Context
 import android.content.res.ColorStateList
 import android.content.res.Configuration
@@ -38,7 +37,6 @@
 import android.util.TypedValue
 import android.view.Gravity
 import android.view.LayoutInflater
-import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
 import android.view.accessibility.AccessibilityEvent
@@ -397,22 +395,15 @@
 
     override fun init(tile: QSTile) {
         val expandable = Expandable.fromView(this)
-        if (quickSettingsVisualHapticsLongpress()) {
-            isHapticFeedbackEnabled = false
-            longPressEffect?.qsTile = tile
-            longPressEffect?.expandable = expandable
-            init(
-                { _: View? -> longPressEffect?.onTileClick() },
-                null, // Haptics and long-clicks will be handled by the [QSLongPressEffect]
-            )
-        } else {
-            init(
+        init(
                 { _: View? -> tile.click(expandable) },
                 { _: View? ->
                     tile.longClick(expandable)
                     true
-                },
-            )
+                }
+        )
+        if (quickSettingsVisualHapticsLongpress()) {
+            isHapticFeedbackEnabled = false // Haptics will be handled by the [QSLongPressEffect]
         }
     }
 
@@ -550,20 +541,6 @@
         return sb.toString()
     }
 
-    @SuppressLint("ClickableViewAccessibility")
-    override fun onTouchEvent(event: MotionEvent?): Boolean {
-        // let the View run the onTouch logic for click and long-click detection
-        val result = super.onTouchEvent(event)
-        if (longPressEffect != null) {
-            when (event?.actionMasked) {
-                MotionEvent.ACTION_DOWN -> longPressEffect.handleActionDown()
-                MotionEvent.ACTION_UP -> longPressEffect.handleActionUp()
-                MotionEvent.ACTION_CANCEL -> longPressEffect.handleActionCancel()
-            }
-        }
-        return result
-    }
-
     // HANDLE STATE CHANGES RELATED METHODS
 
     protected open fun handleStateChanged(state: QSTile.State) {
@@ -698,6 +675,7 @@
             // Long-press effects might have been enabled before but the new state does not
             // handle a long-press. In this case, we go back to the behaviour of a regular tile
             // and clean-up the resources
+            setOnTouchListener(null)
             unbindLongPressEffect()
             showRippleEffect = isClickable
             initialLongPressProperties = null
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index c091ac3de..df7430a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -118,8 +118,6 @@
 public class InternetDialogController implements AccessPointController.AccessPointCallback {
 
     private static final String TAG = "InternetDialogController";
-    private static final String ACTION_NETWORK_PROVIDER_SETTINGS =
-            "android.settings.NETWORK_PROVIDER_SETTINGS";
     private static final String ACTION_WIFI_SCANNING_SETTINGS =
             "android.settings.WIFI_SCANNING_SETTINGS";
     /**
@@ -363,7 +361,8 @@
 
     @VisibleForTesting
     protected Intent getSettingsIntent() {
-        return new Intent(ACTION_NETWORK_PROVIDER_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return new Intent(Settings.ACTION_NETWORK_PROVIDER_SETTINGS).addFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK);
     }
 
     @Nullable
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
index 6586259..9eb9ed5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -26,6 +26,7 @@
 import androidx.core.animation.Animator
 import com.android.app.animation.Interpolators
 import com.android.internal.annotations.GuardedBy
+import com.android.systemui.Flags.privacyDotUnfoldWrongCornerFix
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Main
@@ -505,7 +506,9 @@
             return
         }
 
-        if (state.rotation != currentViewState.rotation) {
+        val designatedCornerChanged = state.designatedCorner != currentViewState.designatedCorner
+        val rotationChanged = state.rotation != currentViewState.rotation
+        if (rotationChanged || (designatedCornerChanged && privacyDotUnfoldWrongCornerFix())) {
             // A rotation has started, hide the views to avoid flicker
             updateRotations(state.rotation, state.paddingTop)
         }
@@ -515,7 +518,7 @@
             views.forEach { it.requestLayout() }
         }
 
-        if (state.designatedCorner != currentViewState.designatedCorner) {
+        if (designatedCornerChanged) {
             currentViewState.designatedCorner?.contentDescription = null
             state.designatedCorner?.contentDescription = state.contentDescription
 
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
index 42389f0..4438763 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
@@ -23,16 +23,23 @@
 import android.net.Uri;
 import android.provider.Settings;
 
+import com.android.systemui.dagger.qualifiers.Background;
+
+import kotlinx.coroutines.CoroutineDispatcher;
+
 import javax.inject.Inject;
 
 // use UserHandle.USER_SYSTEM everywhere
 @SuppressLint("StaticSettingsProvider")
 class GlobalSettingsImpl implements GlobalSettings {
     private final ContentResolver mContentResolver;
+    private final CoroutineDispatcher mBgDispatcher;
 
     @Inject
-    GlobalSettingsImpl(ContentResolver contentResolver) {
+    GlobalSettingsImpl(ContentResolver contentResolver,
+            @Background CoroutineDispatcher bgDispatcher) {
         mContentResolver = contentResolver;
+        mBgDispatcher = bgDispatcher;
     }
 
     @Override
@@ -46,6 +53,11 @@
     }
 
     @Override
+    public CoroutineDispatcher getBackgroundDispatcher() {
+        return mBgDispatcher;
+    }
+
+    @Override
     public String getString(String name) {
         return Settings.Global.getString(mContentResolver, name);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
index 6532ce8..38ad5d0 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
@@ -22,18 +22,24 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.settings.UserTracker;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+
 import javax.inject.Inject;
 
 class SecureSettingsImpl implements SecureSettings {
     private final ContentResolver mContentResolver;
     private final UserTracker mUserTracker;
+    private final CoroutineDispatcher mBgDispatcher;
 
     @Inject
-    SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
+    SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker,
+            @Background CoroutineDispatcher bgDispatcher) {
         mContentResolver = contentResolver;
         mUserTracker = userTracker;
+        mBgDispatcher = bgDispatcher;
     }
 
     @Override
@@ -52,6 +58,11 @@
     }
 
     @Override
+    public CoroutineDispatcher getBackgroundDispatcher() {
+        return mBgDispatcher;
+    }
+
+    @Override
     public String getStringForUser(String name, int userHandle) {
         return Settings.Secure.getStringForUser(mContentResolver, name,
                 getRealUserHandle(userHandle));
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
index ed52233..55171ad 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
@@ -19,6 +19,10 @@
 import android.database.ContentObserver
 import android.net.Uri
 import android.provider.Settings.SettingNotFoundException
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 /**
  * Used to interact with mainly with Settings.Global, but can also be used for Settings.System and
@@ -37,6 +41,13 @@
 interface SettingsProxy {
     /** Returns the [ContentResolver] this instance was constructed with. */
     fun getContentResolver(): ContentResolver
+
+    /**
+     * Returns the background [CoroutineDispatcher] that the async APIs will use for a specific
+     * implementation.
+     */
+    fun getBackgroundDispatcher(): CoroutineDispatcher
+
     /**
      * Construct the content URI for a particular name/value pair, useful for monitoring changes
      * with a ContentObserver.
@@ -45,6 +56,7 @@
      * @return the corresponding content URI, or null if not present
      */
     fun getUriFor(name: String): Uri
+
     /**
      * Convenience wrapper around [ContentResolver.registerContentObserver].'
      *
@@ -53,9 +65,55 @@
     fun registerContentObserverSync(name: String, settingsObserver: ContentObserver) {
         registerContentObserverSync(getUriFor(name), settingsObserver)
     }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+     * registration happens on a worker thread. Caller may wrap the API in an async block if they
+     * wish to synchronize execution.
+     */
+    suspend fun registerContentObserver(name: String, settingsObserver: ContentObserver) =
+        withContext(getBackgroundDispatcher()) {
+            registerContentObserverSync(getUriFor(name), settingsObserver)
+        }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserver] for Java usage.
+     */
+    fun registerContentObserverAsync(name: String, settingsObserver: ContentObserver) =
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            registerContentObserverSync(getUriFor(name), settingsObserver)
+        }
+
     /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
     fun registerContentObserverSync(uri: Uri, settingsObserver: ContentObserver) =
         registerContentObserverSync(uri, false, settingsObserver)
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+     * registration happens on a worker thread. Caller may wrap the API in an async block if they
+     * wish to synchronize execution.
+     */
+    suspend fun registerContentObserver(uri: Uri, settingsObserver: ContentObserver) =
+        withContext(getBackgroundDispatcher()) {
+            registerContentObserverSync(uri, settingsObserver)
+        }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserver] for Java usage.
+     */
+    fun registerContentObserverAsync(uri: Uri, settingsObserver: ContentObserver) =
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            registerContentObserverSync(uri, settingsObserver)
+        }
+
     /**
      * Convenience wrapper around [ContentResolver.registerContentObserver].'
      *
@@ -66,15 +124,102 @@
         notifyForDescendants: Boolean,
         settingsObserver: ContentObserver
     ) = registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+     * registration happens on a worker thread. Caller may wrap the API in an async block if they
+     * wish to synchronize execution.
+     */
+    suspend fun registerContentObserver(
+        name: String,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) =
+        withContext(getBackgroundDispatcher()) {
+            registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+        }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserver] for Java usage.
+     */
+    fun registerContentObserverAsync(
+        name: String,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) =
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+        }
+
     /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
     fun registerContentObserverSync(
         uri: Uri,
         notifyForDescendants: Boolean,
         settingsObserver: ContentObserver
-    ) = getContentResolver().registerContentObserver(uri, notifyForDescendants, settingsObserver)
+    ) {
+        getContentResolver().registerContentObserver(uri, notifyForDescendants, settingsObserver)
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+     * registration happens on a worker thread. Caller may wrap the API in an async block if they
+     * wish to synchronize execution.
+     */
+    suspend fun registerContentObserver(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) =
+        withContext(getBackgroundDispatcher()) {
+            registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
+        }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserver] for Java usage.
+     */
+    fun registerContentObserverAsync(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) =
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            getContentResolver()
+                .registerContentObserver(uri, notifyForDescendants, settingsObserver)
+        }
+
     /** See [ContentResolver.unregisterContentObserver]. */
     fun unregisterContentObserverSync(settingsObserver: ContentObserver) =
         getContentResolver().unregisterContentObserver(settingsObserver)
+
+    /**
+     * Convenience wrapper around [ContentResolver.unregisterContentObserver].'
+     *
+     * API corresponding to [unregisterContentObserver] for Java usage to ensure that
+     * [ContentObserver] un-registration happens on a worker thread. Caller may wrap the API in an
+     * async block if they wish to synchronize execution.
+     */
+    suspend fun unregisterContentObserver(settingsObserver: ContentObserver) =
+        withContext(getBackgroundDispatcher()) { unregisterContentObserverSync(settingsObserver) }
+
+    /**
+     * Convenience wrapper around [ContentResolver.unregisterContentObserver].'
+     *
+     * API corresponding to [unregisterContentObserver] for Java usage to ensure that
+     * [ContentObserver] registration happens on a worker thread.
+     */
+    fun unregisterContentObserverAsync(settingsObserver: ContentObserver) =
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            unregisterContentObserver(settingsObserver)
+        }
+
     /**
      * Look up a name in the database.
      *
@@ -82,6 +227,7 @@
      * @return the corresponding value, or null if not present
      */
     fun getString(name: String): String
+
     /**
      * Store a name/value pair into the database.
      *
@@ -90,6 +236,7 @@
      * @return true if the value was set, false on database errors
      */
     fun putString(name: String, value: String): Boolean
+
     /**
      * Store a name/value pair into the database.
      *
@@ -120,6 +267,7 @@
      * @see .resetToDefaults
      */
     fun putString(name: String, value: String, tag: String, makeDefault: Boolean): Boolean
+
     /**
      * Convenience function for retrieving a single secure settings value as an integer. Note that
      * internally setting values are always stored as strings; this function converts the string to
@@ -138,6 +286,7 @@
             def
         }
     }
+
     /**
      * Convenience function for retrieving a single secure settings value as an integer. Note that
      * internally setting values are always stored as strings; this function converts the string to
@@ -160,6 +309,7 @@
             throw SettingNotFoundException(name)
         }
     }
+
     /**
      * Convenience function for updating a single settings value as an integer. This will either
      * create a new entry in the table if the given name does not exist, or modify the value of the
@@ -173,6 +323,7 @@
     fun putInt(name: String, value: Int): Boolean {
         return putString(name, value.toString())
     }
+
     /**
      * Convenience function for retrieving a single secure settings value as a boolean. Note that
      * internally setting values are always stored as strings; this function converts the string to
@@ -186,6 +337,7 @@
     fun getBool(name: String, def: Boolean): Boolean {
         return getInt(name, if (def) 1 else 0) != 0
     }
+
     /**
      * Convenience function for retrieving a single secure settings value as a boolean. Note that
      * internally setting values are always stored as strings; this function converts the string to
@@ -203,6 +355,7 @@
     fun getBool(name: String): Boolean {
         return getInt(name) != 0
     }
+
     /**
      * Convenience function for updating a single settings value as a boolean. This will either
      * create a new entry in the table if the given name does not exist, or modify the value of the
@@ -216,6 +369,7 @@
     fun putBool(name: String, value: Boolean): Boolean {
         return putInt(name, if (value) 1 else 0)
     }
+
     /**
      * Convenience function for retrieving a single secure settings value as a `long`. Note that
      * internally setting values are always stored as strings; this function converts the string to
@@ -230,6 +384,7 @@
         val valString = getString(name)
         return parseLongOrUseDefault(valString, def)
     }
+
     /**
      * Convenience function for retrieving a single secure settings value as a `long`. Note that
      * internally setting values are always stored as strings; this function converts the string to
@@ -248,6 +403,7 @@
         val valString = getString(name)
         return parseLongOrThrow(name, valString)
     }
+
     /**
      * Convenience function for updating a secure settings value as a long integer. This will either
      * create a new entry in the table if the given name does not exist, or modify the value of the
@@ -261,6 +417,7 @@
     fun putLong(name: String, value: Long): Boolean {
         return putString(name, value.toString())
     }
+
     /**
      * Convenience function for retrieving a single secure settings value as a floating point
      * number. Note that internally setting values are always stored as strings; this function
@@ -275,6 +432,7 @@
         val v = getString(name)
         return parseFloat(v, def)
     }
+
     /**
      * Convenience function for retrieving a single secure settings value as a float. Note that
      * internally setting values are always stored as strings; this function converts the string to
@@ -293,6 +451,7 @@
         val v = getString(name)
         return parseFloatOrThrow(name, v)
     }
+
     /**
      * Convenience function for updating a single settings value as a floating point number. This
      * will either create a new entry in the table if the given name does not exist, or modify the
@@ -306,6 +465,7 @@
     fun putFloat(name: String, value: Float): Boolean {
         return putString(name, value.toString())
     }
+
     companion object {
         /** Convert a string to a long, or uses a default if the string is malformed or null */
         @JvmStatic
@@ -319,6 +479,7 @@
                 }
             return value
         }
+
         /** Convert a string to a long, or throws an exception if the string is malformed or null */
         @JvmStatic
         @Throws(SettingNotFoundException::class)
@@ -332,6 +493,7 @@
                 throw SettingNotFoundException(name)
             }
         }
+
         /** Convert a string to a float, or uses a default if the string is malformed or null */
         @JvmStatic
         fun parseFloat(v: String?, def: Float): Float {
@@ -341,6 +503,7 @@
                 def
             }
         }
+
         /**
          * Convert a string to a float, or throws an exception if the string is malformed or null
          */
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
index 658b299..68cc753 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
@@ -22,18 +22,24 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.settings.UserTracker;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+
 import javax.inject.Inject;
 
 class SystemSettingsImpl implements SystemSettings {
     private final ContentResolver mContentResolver;
     private final UserTracker mUserTracker;
+    private final CoroutineDispatcher mBgCoroutineDispatcher;
 
     @Inject
-    SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
+    SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker,
+            @Background CoroutineDispatcher bgDispatcher) {
         mContentResolver = contentResolver;
         mUserTracker = userTracker;
+        mBgCoroutineDispatcher = bgDispatcher;
     }
 
     @Override
@@ -52,6 +58,11 @@
     }
 
     @Override
+    public CoroutineDispatcher getBackgroundDispatcher() {
+        return mBgCoroutineDispatcher;
+    }
+
+    @Override
     public String getStringForUser(String name, int userHandle) {
         return Settings.System.getStringForUser(mContentResolver, name,
                 getRealUserHandle(userHandle));
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt b/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
index ed13943..9133fbb 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.util.settings
 
 import android.annotation.UserIdInt
+import android.content.ContentResolver
 import android.database.ContentObserver
 import android.net.Uri
 import android.os.UserHandle
@@ -26,6 +27,9 @@
 import com.android.systemui.util.settings.SettingsProxy.Companion.parseFloatOrThrow
 import com.android.systemui.util.settings.SettingsProxy.Companion.parseLongOrThrow
 import com.android.systemui.util.settings.SettingsProxy.Companion.parseLongOrUseDefault
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 /**
  * Used to interact with per-user Settings.Secure and Settings.System settings (but not
@@ -51,6 +55,7 @@
                 "userId cannot be set in interface, use setter from an implementation instead."
             )
         }
+
     /**
      * Returns the actual current user handle when querying with the current user. Otherwise,
      * returns the passed in user id.
@@ -60,9 +65,21 @@
             userHandle
         } else userTracker.userId
     }
+
     override fun registerContentObserverSync(uri: Uri, settingsObserver: ContentObserver) {
         registerContentObserverForUserSync(uri, settingsObserver, userId)
     }
+
+    override suspend fun registerContentObserver(uri: Uri, settingsObserver: ContentObserver) =
+        withContext(getBackgroundDispatcher()) {
+            registerContentObserverForUserSync(uri, settingsObserver, userId)
+        }
+
+    override fun registerContentObserverAsync(uri: Uri, settingsObserver: ContentObserver) =
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            registerContentObserverForUserSync(uri, settingsObserver, userId)
+        }
+
     /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
     override fun registerContentObserverSync(
         uri: Uri,
@@ -71,6 +88,30 @@
     ) {
         registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
     }
+
+    override suspend fun registerContentObserver(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) =
+        withContext(getBackgroundDispatcher()) {
+            registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
+        }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserverForUser] for Java usage.
+     */
+    override fun registerContentObserverAsync(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) =
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
+        }
+
     /**
      * Convenience wrapper around [ContentResolver.registerContentObserver]
      *
@@ -83,6 +124,37 @@
     ) {
         registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
     }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserverForUser] to ensure that
+     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+     * async block if they wish to synchronize execution.
+     */
+    suspend fun registerContentObserverForUser(
+        name: String,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) =
+        withContext(getBackgroundDispatcher()) {
+            registerContentObserverForUserSync(name, settingsObserver, userHandle)
+        }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserverForUser] for Java usage.
+     */
+    fun registerContentObserverForUserAsync(
+        name: String,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) =
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
+        }
+
     /** Convenience wrapper around [ContentResolver.registerContentObserver] */
     fun registerContentObserverForUserSync(
         uri: Uri,
@@ -91,6 +163,37 @@
     ) {
         registerContentObserverForUserSync(uri, false, settingsObserver, userHandle)
     }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserverForUser] to ensure that
+     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+     * async block if they wish to synchronize execution.
+     */
+    suspend fun registerContentObserverForUser(
+        uri: Uri,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) =
+        withContext(getBackgroundDispatcher()) {
+            registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+        }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserverForUser] for Java usage.
+     */
+    fun registerContentObserverForUserAsync(
+        uri: Uri,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) =
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+        }
+
     /**
      * Convenience wrapper around [ContentResolver.registerContentObserver]
      *
@@ -109,6 +212,50 @@
             userHandle
         )
     }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserverForUser] to ensure that
+     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+     * async block if they wish to synchronize execution.
+     */
+    suspend fun registerContentObserverForUser(
+        name: String,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) =
+        withContext(getBackgroundDispatcher()) {
+            registerContentObserverForUserSync(
+                name,
+                notifyForDescendants,
+                settingsObserver,
+                userHandle
+            )
+        }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserverForUser] for Java usage.
+     */
+    fun registerContentObserverForUserAsync(
+        name: String,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) {
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            registerContentObserverForUserSync(
+                getUriFor(name),
+                notifyForDescendants,
+                settingsObserver,
+                userHandle
+            )
+        }
+    }
+
     /** Convenience wrapper around [ContentResolver.registerContentObserver] */
     fun registerContentObserverForUserSync(
         uri: Uri,
@@ -127,6 +274,49 @@
             Unit
         }
     }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserverForUser] to ensure that
+     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+     * async block if they wish to synchronize execution.
+     */
+    suspend fun registerContentObserverForUser(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) =
+        withContext(getBackgroundDispatcher()) {
+            registerContentObserverForUserSync(
+                uri,
+                notifyForDescendants,
+                settingsObserver,
+                getRealUserHandle(userHandle)
+            )
+        }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserverForUser] for Java usage.
+     */
+    fun registerContentObserverForUserAsync(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) =
+        CoroutineScope(getBackgroundDispatcher()).launch {
+            registerContentObserverForUserSync(
+                uri,
+                notifyForDescendants,
+                settingsObserver,
+                userHandle
+            )
+        }
+
     /**
      * Look up a name in the database.
      *
@@ -136,8 +326,10 @@
     override fun getString(name: String): String {
         return getStringForUser(name, userId)
     }
+
     /** See [getString]. */
     fun getStringForUser(name: String, userHandle: Int): String
+
     /**
      * Store a name/value pair into the database. Values written by this method will be overridden
      * if a restore happens in the future.
@@ -147,11 +339,14 @@
      * @return true if the value was set, false on database errors
      */
     fun putString(name: String, value: String, overrideableByRestore: Boolean): Boolean
+
     override fun putString(name: String, value: String): Boolean {
         return putStringForUser(name, value, userId)
     }
+
     /** Similar implementation to [putString] for the specified [userHandle]. */
     fun putStringForUser(name: String, value: String, userHandle: Int): Boolean
+
     /** Similar implementation to [putString] for the specified [userHandle]. */
     fun putStringForUser(
         name: String,
@@ -161,9 +356,11 @@
         @UserIdInt userHandle: Int,
         overrideableByRestore: Boolean
     ): Boolean
+
     override fun getInt(name: String, def: Int): Int {
         return getIntForUser(name, def, userId)
     }
+
     /** Similar implementation to [getInt] for the specified [userHandle]. */
     fun getIntForUser(name: String, def: Int, userHandle: Int): Int {
         val v = getStringForUser(name, userHandle)
@@ -173,8 +370,10 @@
             def
         }
     }
+
     @Throws(SettingNotFoundException::class)
     override fun getInt(name: String) = getIntForUser(name, userId)
+
     /** Similar implementation to [getInt] for the specified [userHandle]. */
     @Throws(SettingNotFoundException::class)
     fun getIntForUser(name: String, userHandle: Int): Int {
@@ -185,52 +384,66 @@
             throw SettingNotFoundException(name)
         }
     }
+
     override fun putInt(name: String, value: Int) = putIntForUser(name, value, userId)
+
     /** Similar implementation to [getInt] for the specified [userHandle]. */
     fun putIntForUser(name: String, value: Int, userHandle: Int) =
         putStringForUser(name, value.toString(), userHandle)
+
     override fun getBool(name: String, def: Boolean) = getBoolForUser(name, def, userId)
+
     /** Similar implementation to [getBool] for the specified [userHandle]. */
     fun getBoolForUser(name: String, def: Boolean, userHandle: Int) =
         getIntForUser(name, if (def) 1 else 0, userHandle) != 0
+
     @Throws(SettingNotFoundException::class)
     override fun getBool(name: String) = getBoolForUser(name, userId)
+
     /** Similar implementation to [getBool] for the specified [userHandle]. */
     @Throws(SettingNotFoundException::class)
     fun getBoolForUser(name: String, userHandle: Int): Boolean {
         return getIntForUser(name, userHandle) != 0
     }
+
     override fun putBool(name: String, value: Boolean): Boolean {
         return putBoolForUser(name, value, userId)
     }
+
     /** Similar implementation to [putBool] for the specified [userHandle]. */
     fun putBoolForUser(name: String, value: Boolean, userHandle: Int) =
         putIntForUser(name, if (value) 1 else 0, userHandle)
+
     /** Similar implementation to [getLong] for the specified [userHandle]. */
     fun getLongForUser(name: String, def: Long, userHandle: Int): Long {
         val valString = getStringForUser(name, userHandle)
         return parseLongOrUseDefault(valString, def)
     }
+
     /** Similar implementation to [getLong] for the specified [userHandle]. */
     @Throws(SettingNotFoundException::class)
     fun getLongForUser(name: String, userHandle: Int): Long {
         val valString = getStringForUser(name, userHandle)
         return parseLongOrThrow(name, valString)
     }
+
     /** Similar implementation to [putLong] for the specified [userHandle]. */
     fun putLongForUser(name: String, value: Long, userHandle: Int) =
         putStringForUser(name, value.toString(), userHandle)
+
     /** Similar implementation to [getFloat] for the specified [userHandle]. */
     fun getFloatForUser(name: String, def: Float, userHandle: Int): Float {
         val v = getStringForUser(name, userHandle)
         return parseFloat(v, def)
     }
+
     /** Similar implementation to [getFloat] for the specified [userHandle]. */
     @Throws(SettingNotFoundException::class)
     fun getFloatForUser(name: String, userHandle: Int): Float {
         val v = getStringForUser(name, userHandle)
         return parseFloatOrThrow(name, v)
     }
+
     /** Similar implementation to [putFloat] for the specified [userHandle]. */
     fun putFloatForUser(name: String, value: Float, userHandle: Int) =
         putStringForUser(name, value.toString(), userHandle)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index 86a976f..e02fb29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -570,13 +570,13 @@
             // WHEN biometrics succeeds with wake and unlock mode
             powerInteractor.setAwakeForTest()
             keyguardRepository.setBiometricUnlockState(BiometricUnlockMode.WAKE_AND_UNLOCK)
-            runCurrent()
+            advanceTimeBy(60L)
 
             assertThat(transitionRepository)
                 .startedTransition(
                     to = KeyguardState.GONE,
                     from = KeyguardState.DOZING,
-                    ownerName = "FromDozingTransitionInteractor(biometric wake and unlock)",
+                    ownerName = "FromDozingTransitionInteractor",
                     animatorAssertion = { it.isNotNull() }
                 )
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
index f7b3f2e..6a2637d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
@@ -40,7 +40,6 @@
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.controls.MediaTestUtils
@@ -159,7 +158,6 @@
         testDispatcher = UnconfinedTestDispatcher()
         mediaCarouselController =
             MediaCarouselController(
-                applicationScope = kosmos.applicationCoroutineScope,
                 context = context,
                 mediaControlPanelFactory = mediaControlPanelFactory,
                 visualStabilityProvider = visualStabilityProvider,
@@ -895,10 +893,7 @@
             mediaCarouselController.updateHostVisibility = { updatedVisibility = true }
             mediaCarouselController.mediaCarousel = mediaCarousel
 
-            val settingsJob =
-                mediaCarouselController.listenForLockscreenSettingChanges(
-                    kosmos.applicationCoroutineScope
-                )
+            val settingsJob = mediaCarouselController.listenForLockscreenSettingChanges(this)
             secureSettings.putBool(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, false)
 
             val keyguardJob = mediaCarouselController.listenForAnyStateToLockscreenTransition(this)
@@ -925,10 +920,7 @@
             mediaCarouselController.updateHostVisibility = { updatedVisibility = true }
             mediaCarouselController.mediaCarousel = mediaCarousel
 
-            val settingsJob =
-                mediaCarouselController.listenForLockscreenSettingChanges(
-                    kosmos.applicationCoroutineScope
-                )
+            val settingsJob = mediaCarouselController.listenForLockscreenSettingChanges(this)
             secureSettings.putBool(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, true)
 
             val keyguardJob = mediaCarouselController.listenForAnyStateToLockscreenTransition(this)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index 56a2adc..16a022f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -140,8 +140,6 @@
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 @SmallTest
@@ -1620,60 +1618,6 @@
         verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any());
     }
 
-    @Test
-    @EnableFlags({
-        android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS,
-        android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL
-    })
-    public void testUpdateGeneratedPreviewWithDataParcel_userLocked() throws InterruptedException {
-        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(false);
-
-        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
-        assertThat(waitForBackgroundJob()).isTrue();
-        verify(mAppWidgetManager, times(0)).setWidgetPreview(any(), anyInt(), any());
-    }
-
-    @Test
-    @EnableFlags({
-        android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS,
-        android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL
-    })
-    public void testUpdateGeneratedPreviewWithDataParcel_userUnlocked()
-            throws InterruptedException {
-        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true);
-        when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true);
-
-        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
-        assertThat(waitForBackgroundJob()).isTrue();
-        verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any());
-    }
-
-    @Test
-    @EnableFlags({
-        android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS,
-        android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL
-    })
-    public void testUpdateGeneratedPreviewWithDataParcel_doesNotSetTwice()
-            throws InterruptedException {
-        when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true);
-        when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true);
-
-        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
-        mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
-        assertThat(waitForBackgroundJob()).isTrue();
-        verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any());
-    }
-
-    private boolean waitForBackgroundJob() throws InterruptedException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        mFakeExecutor.execute(latch::countDown);
-        mFakeExecutor.runAllReady();
-        mFakeExecutor.advanceClockToNext();
-        mFakeExecutor.runAllReady();
-        return latch.await(30000, TimeUnit.MILLISECONDS);
-
-    }
-
     private void setFinalField(String fieldName, int value) {
         try {
             Field field = NotificationManager.Policy.class.getDeclaredField(fieldName);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
index 6618308..130aafb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
@@ -19,8 +19,6 @@
 import android.content.Context
 import android.graphics.Rect
 import android.graphics.drawable.Drawable
-import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
 import android.service.quicksettings.Tile
 import android.testing.TestableLooper
 import android.text.TextUtils
@@ -30,13 +28,11 @@
 import android.widget.TextView
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.Flags.FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.haptics.qs.QSLongPressEffect
 import com.android.systemui.haptics.qs.qsLongPressEffect
 import com.android.systemui.plugins.qs.QSTile
-import com.android.systemui.qs.qsTileFactory
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
@@ -540,30 +536,10 @@
         assertThat(tileView.haveLongPressPropertiesBeenReset).isTrue()
     }
 
-    @Test
-    @EnableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS)
-    fun onInit_withLongPressEffect_longPressEffectHasTileAndExpandable() {
-        val tile = kosmos.qsTileFactory.createTile("Test Tile")
-        tileView.init(tile)
-
-        assertThat(tileView.isTileAddedToLongPress).isTrue()
-        assertThat(tileView.isExpandableAddedToLongPress).isTrue()
-    }
-
-    @Test
-    @DisableFlags(FLAG_QUICK_SETTINGS_VISUAL_HAPTICS_LONGPRESS)
-    fun onInit_withoutLongPressEffect_longPressEffectDoesNotHaveTileAndExpandable() {
-        val tile = kosmos.qsTileFactory.createTile("Test Tile")
-        tileView.init(tile)
-
-        assertThat(tileView.isTileAddedToLongPress).isFalse()
-        assertThat(tileView.isExpandableAddedToLongPress).isFalse()
-    }
-
     class FakeTileView(
         context: Context,
         collapsed: Boolean,
-        private val longPressEffect: QSLongPressEffect?,
+        longPressEffect: QSLongPressEffect?,
     ) : QSTileViewImpl(
             ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings),
             collapsed,
@@ -571,11 +547,6 @@
     ) {
         var constantLongPressEffectDuration = 500
 
-        val isTileAddedToLongPress: Boolean
-            get() = longPressEffect?.qsTile != null
-        val isExpandableAddedToLongPress: Boolean
-            get() = longPressEffect?.expandable != null
-
         override fun getLongPressEffectDuration(): Int = constantLongPressEffectDuration
         fun changeState(state: QSTile.State) {
             handleStateChanged(state)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
index eb11e38..92dd391 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
@@ -27,6 +27,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.setMain
 import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Test
@@ -41,11 +47,16 @@
 @TestableLooper.RunWithLooper
 class SettingsProxyTest : SysuiTestCase() {
 
+    private val testDispatcher = StandardTestDispatcher()
+
     private lateinit var mSettings: SettingsProxy
     private lateinit var mContentObserver: ContentObserver
+    private lateinit var testScope: TestScope
 
     @Before
     fun setUp() {
+        testScope = TestScope(testDispatcher)
+        Dispatchers.setMain(testDispatcher)
         mSettings = FakeSettingsProxy()
         mContentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {}
     }
@@ -58,6 +69,23 @@
     }
 
     @Test
+    fun registerContentObserverSuspend_inputString_success() =
+        testScope.runTest {
+            mSettings.registerContentObserver(TEST_SETTING, mContentObserver)
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputString_success() {
+        mSettings.registerContentObserverAsync(TEST_SETTING, mContentObserver)
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+        }
+    }
+
+    @Test
     fun registerContentObserver_inputString_notifyForDescendants_true() {
         mSettings.registerContentObserverSync(
             TEST_SETTING,
@@ -69,6 +97,31 @@
     }
 
     @Test
+    fun registerContentObserverSuspend_inputString_notifyForDescendants_true() =
+        testScope.runTest {
+            mSettings.registerContentObserver(
+                TEST_SETTING,
+                notifyForDescendants = true,
+                mContentObserver
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputString_notifyForDescendants_true() {
+        mSettings.registerContentObserverAsync(
+            TEST_SETTING,
+            notifyForDescendants = true,
+            mContentObserver
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+        }
+    }
+
+    @Test
     fun registerContentObserver_inputUri_success() {
         mSettings.registerContentObserverSync(TEST_SETTING_URI, mContentObserver)
         verify(mSettings.getContentResolver())
@@ -76,6 +129,23 @@
     }
 
     @Test
+    fun registerContentObserverSuspend_inputUri_success() =
+        testScope.runTest {
+            mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputUri_success() {
+        mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+        }
+    }
+
+    @Test
     fun registerContentObserver_inputUri_notifyForDescendants_true() {
         mSettings.registerContentObserverSync(
             TEST_SETTING_URI,
@@ -87,12 +157,52 @@
     }
 
     @Test
-    fun unregisterContentObserver() {
+    fun registerContentObserverSuspend_inputUri_notifyForDescendants_true() =
+        testScope.runTest {
+            mSettings.registerContentObserver(
+                TEST_SETTING_URI,
+                notifyForDescendants = true,
+                mContentObserver
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputUri_notifyForDescendants_true() {
+        mSettings.registerContentObserverAsync(
+            TEST_SETTING_URI,
+            notifyForDescendants = true,
+            mContentObserver
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+        }
+    }
+
+    @Test
+    fun unregisterContentObserverSync() {
         mSettings.unregisterContentObserverSync(mContentObserver)
         verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
     }
 
     @Test
+    fun unregisterContentObserverSuspend_inputString_success() =
+        testScope.runTest {
+            mSettings.unregisterContentObserver(mContentObserver)
+            verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
+        }
+
+    @Test
+    fun unregisterContentObserverAsync_inputString_success() {
+        mSettings.unregisterContentObserverAsync(mContentObserver)
+        testScope.launch {
+            verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
+        }
+    }
+
+    @Test
     fun getString_keyPresent_returnValidValue() {
         mSettings.putString(TEST_SETTING, "test")
         assertThat(mSettings.getString(TEST_SETTING)).isEqualTo("test")
@@ -203,12 +313,15 @@
 
         private val mContentResolver = mock(ContentResolver::class.java)
         private val settingToValueMap: MutableMap<String, String> = mutableMapOf()
+        private val testDispatcher = StandardTestDispatcher()
 
         override fun getContentResolver() = mContentResolver
 
         override fun getUriFor(name: String) =
             Uri.parse(StringBuilder().append("content://settings/").append(name).toString())
 
+        override fun getBackgroundDispatcher() = testDispatcher
+
         override fun getString(name: String): String {
             return settingToValueMap[name] ?: ""
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
index 38469ee..4cb5fa9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
@@ -30,6 +30,12 @@
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.settings.UserTracker
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.setMain
 import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Test
@@ -47,6 +53,7 @@
     private var mUserTracker = FakeUserTracker()
     private var mSettings: UserSettingsProxy = FakeUserSettingsProxy(mUserTracker)
     private var mContentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {}
+    private lateinit var testScope: TestScope
 
     @Before
     fun setUp() {
@@ -54,6 +61,9 @@
             listOf(UserInfo(MAIN_USER_ID, "main", UserInfo.FLAG_MAIN)),
             selectedUserIndex = 0
         )
+        val testDispatcher = StandardTestDispatcher()
+        testScope = TestScope(testDispatcher)
+        Dispatchers.setMain(testDispatcher)
     }
 
     @Test
@@ -73,6 +83,41 @@
     }
 
     @Test
+    fun registerContentObserverForUserSuspend_inputString_success() =
+        testScope.runTest {
+            mSettings.registerContentObserverForUser(
+                TEST_SETTING,
+                mContentObserver,
+                mUserTracker.userId
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+
+    @Test
+    fun registerContentObserverForUserAsync_inputString_success() {
+        mSettings.registerContentObserverForUserAsync(
+            TEST_SETTING,
+            mContentObserver,
+            mUserTracker.userId
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+    }
+
+    @Test
     fun registerContentObserverForUser_inputString_notifyForDescendants_true() {
         mSettings.registerContentObserverForUserSync(
             TEST_SETTING,
@@ -90,6 +135,45 @@
     }
 
     @Test
+    fun registerContentObserverForUserSuspend_inputString_notifyForDescendants_true() =
+        testScope.runTest {
+            mSettings.registerContentObserverForUser(
+                TEST_SETTING,
+                notifyForDescendants = true,
+                mContentObserver,
+                mUserTracker.userId
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(
+                        true,
+                    ),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+
+    @Test
+    fun registerContentObserverForUserAsync_inputString_notifyForDescendants_true() {
+        mSettings.registerContentObserverForUserAsync(
+            TEST_SETTING,
+            notifyForDescendants = true,
+            mContentObserver,
+            mUserTracker.userId
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(true),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+    }
+
+    @Test
     fun registerContentObserverForUser_inputUri_success() {
         mSettings.registerContentObserverForUserSync(
             TEST_SETTING_URI,
@@ -106,6 +190,41 @@
     }
 
     @Test
+    fun registerContentObserverForUserSuspend_inputUri_success() =
+        testScope.runTest {
+            mSettings.registerContentObserverForUser(
+                TEST_SETTING_URI,
+                mContentObserver,
+                mUserTracker.userId
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+
+    @Test
+    fun registerContentObserverForUserAsync_inputUri_success() {
+        mSettings.registerContentObserverForUserAsync(
+            TEST_SETTING_URI,
+            mContentObserver,
+            mUserTracker.userId
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+    }
+
+    @Test
     fun registerContentObserverForUser_inputUri_notifyForDescendants_true() {
         mSettings.registerContentObserverForUserSync(
             TEST_SETTING_URI,
@@ -123,6 +242,45 @@
     }
 
     @Test
+    fun registerContentObserverForUserSuspend_inputUri_notifyForDescendants_true() =
+        testScope.runTest {
+            mSettings.registerContentObserverForUser(
+                TEST_SETTING_URI,
+                notifyForDescendants = true,
+                mContentObserver,
+                mUserTracker.userId
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(
+                        true,
+                    ),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+
+    @Test
+    fun registerContentObserverForUserAsync_inputUri_notifyForDescendants_true() {
+        mSettings.registerContentObserverForUserAsync(
+            TEST_SETTING_URI,
+            notifyForDescendants = true,
+            mContentObserver,
+            mUserTracker.userId
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(true),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+    }
+
+    @Test
     fun registerContentObserver_inputUri_success() {
         mSettings.registerContentObserverSync(TEST_SETTING_URI, mContentObserver)
         verify(mSettings.getContentResolver())
@@ -130,6 +288,33 @@
     }
 
     @Test
+    fun registerContentObserverSuspend_inputUri_success() =
+        testScope.runTest {
+            mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(0)
+                )
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputUri_success() {
+        mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(0)
+                )
+        }
+    }
+
+    @Test
     fun registerContentObserver_inputUri_notifyForDescendants_true() {
         mSettings.registerContentObserverSync(
             TEST_SETTING_URI,
@@ -141,6 +326,33 @@
     }
 
     @Test
+    fun registerContentObserverSuspend_inputUri_notifyForDescendants_true() =
+        testScope.runTest {
+            mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(0)
+                )
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputUri_notifyForDescendants_true() {
+        mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(0)
+                )
+        }
+    }
+
+    @Test
     fun getString_keyPresent_returnValidValue() {
         mSettings.putString(TEST_SETTING, "test")
         assertThat(mSettings.getString(TEST_SETTING)).isEqualTo("test")
@@ -305,12 +517,15 @@
         private val mContentResolver = mock(ContentResolver::class.java)
         private val userIdToSettingsValueMap: MutableMap<Int, MutableMap<String, String>> =
             mutableMapOf()
+        private val testDispatcher = StandardTestDispatcher()
 
         override fun getContentResolver() = mContentResolver
 
         override fun getUriFor(name: String) =
             Uri.parse(StringBuilder().append(URI_PREFIX).append(name).toString())
 
+        override fun getBackgroundDispatcher() = testDispatcher
+
         override fun getStringForUser(name: String, userHandle: Int) =
             userIdToSettingsValueMap[userHandle]?.get(name) ?: ""
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
index 3a70cdf..136b129 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
@@ -22,6 +22,8 @@
 import android.database.ContentObserver;
 import android.net.Uri;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -44,6 +46,13 @@
     }
 
     @Override
+    public CoroutineDispatcher getBackgroundDispatcher() {
+        throw new UnsupportedOperationException(
+                "GlobalSettings.getBackgroundDispatcher is not implemented, but you may find "
+                        + "GlobalSettings.getBackgroundDispatcher helpful instead.");
+    }
+
+    @Override
     public void registerContentObserverSync(Uri uri, boolean notifyDescendants,
             ContentObserver settingsObserver) {
         List<ContentObserver> observers;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
index cd219ec..6cefa34 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
@@ -27,6 +27,8 @@
 
 import com.android.systemui.settings.UserTracker;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -66,6 +68,11 @@
     }
 
     @Override
+    public CoroutineDispatcher getBackgroundDispatcher() {
+        return null;
+    }
+
+    @Override
     public void registerContentObserverForUserSync(Uri uri, boolean notifyDescendants,
             ContentObserver settingsObserver, int userHandle) {
         List<ContentObserver> observers;
diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
index f289115..aa76200 100644
--- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -62,6 +62,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.os.SystemClock;
 import android.provider.Settings;
 import android.service.autofill.Dataset;
 import android.text.TextUtils;
@@ -211,17 +212,21 @@
             AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_AUTOFILL_PROVIDER;
     public static final int DETECTION_PREFER_PCC =
             AUTOFILL_FILL_RESPONSE_REPORTED__DETECTION_PREFERENCE__DETECTION_PREFER_PCC;
-    private final int mSessionId;
 
+    private static final int DEFAULT_VALUE_INT = -1;
+
+    private final int mSessionId;
     /**
      * For app_package_uid.
      */
     private final int mCallingAppUid;
     private Optional<PresentationStatsEventInternal> mEventInternal;
+    private final long mSessionStartTimestamp;
 
-    private PresentationStatsEventLogger(int sessionId, int callingAppUid) {
+    private PresentationStatsEventLogger(int sessionId, int callingAppUid, long timestamp) {
         mSessionId = sessionId;
         mCallingAppUid = callingAppUid;
+        mSessionStartTimestamp = timestamp;
         mEventInternal = Optional.empty();
     }
 
@@ -229,8 +234,8 @@
      * Create PresentationStatsEventLogger, populated with sessionId and the callingAppUid
      */
     public static PresentationStatsEventLogger createPresentationLog(
-            int sessionId, int callingAppUid) {
-        return new PresentationStatsEventLogger(sessionId, callingAppUid);
+            int sessionId, int callingAppUid, long timestamp) {
+        return new PresentationStatsEventLogger(sessionId, callingAppUid, timestamp);
     }
 
     public void startNewEvent() {
@@ -370,28 +375,50 @@
         });
     }
 
+    public void maybeSetFillRequestSentTimestampMs() {
+        maybeSetFillRequestSentTimestampMs(getElapsedTime());
+    }
+
     public void maybeSetFillResponseReceivedTimestampMs(int timestamp) {
         mEventInternal.ifPresent(event -> {
             event.mFillResponseReceivedTimestampMs = timestamp;
         });
     }
 
+    public void maybeSetFillResponseReceivedTimestampMs() {
+        maybeSetFillResponseReceivedTimestampMs(getElapsedTime());
+    }
+
     public void maybeSetSuggestionSentTimestampMs(int timestamp) {
         mEventInternal.ifPresent(event -> {
             event.mSuggestionSentTimestampMs = timestamp;
         });
     }
 
+    public void maybeSetSuggestionSentTimestampMs() {
+        maybeSetSuggestionSentTimestampMs(getElapsedTime());
+    }
+
     public void maybeSetSuggestionPresentedTimestampMs(int timestamp) {
         mEventInternal.ifPresent(event -> {
-            event.mSuggestionPresentedTimestampMs = timestamp;
+            // mSuggestionPresentedTimestampMs only tracks the first suggested timestamp.
+            if (event.mSuggestionPresentedTimestampMs == DEFAULT_VALUE_INT) {
+                event.mSuggestionPresentedTimestampMs = timestamp;
+            }
+
+            event.mSuggestionPresentedLastTimestampMs = timestamp;
         });
     }
 
+    public void maybeSetSuggestionPresentedTimestampMs() {
+        maybeSetSuggestionPresentedTimestampMs(getElapsedTime());
+    }
+
     public void maybeSetSelectedDatasetId(int selectedDatasetId) {
         mEventInternal.ifPresent(event -> {
             event.mSelectedDatasetId = selectedDatasetId;
         });
+        setPresentationSelectedTimestamp();
     }
 
     public void maybeSetDialogDismissed(boolean dialogDismissed) {
@@ -479,6 +506,11 @@
         });
     }
 
+    /** Set latency_authentication_ui_display_millis as long as mEventInternal presents. */
+    public void maybeSetLatencyAuthenticationUiDisplayMillis() {
+        maybeSetLatencyAuthenticationUiDisplayMillis(getElapsedTime());
+    }
+
     /**
      * Set latency_dataset_display_millis as long as mEventInternal presents.
      */
@@ -488,6 +520,11 @@
         });
     }
 
+    /** Set latency_dataset_display_millis as long as mEventInternal presents. */
+    public void maybeSetLatencyDatasetDisplayMillis() {
+        maybeSetLatencyDatasetDisplayMillis(getElapsedTime());
+    }
+
     /**
      * Set available_pcc_count.
      */
@@ -524,6 +561,53 @@
         });
     }
 
+    /**
+     * Set various timestamps whenever the ViewState is modified
+     *
+     * <p>If the ViewState contains ViewState.STATE_AUTOFILLED, sets field_autofilled_timestamp_ms
+     * else, set field_first_modified_timestamp_ms (if unset) and field_last_modified_timestamp_ms
+     */
+    public void onFieldTextUpdated(ViewState state) {
+        mEventInternal.ifPresent(
+                event -> {
+                    int timestamp = getElapsedTime();
+                    // Focused id should be set before this is called
+                    if (state.id != null && state.id.getViewId() != event.mFocusedId) {
+                        // if these don't match, the currently field different than before
+                        Slog.w(
+                                TAG,
+                                "current id: "
+                                        + state.id.getViewId()
+                                        + " is different than focused id: "
+                                        + event.mFocusedId);
+                        return;
+                    }
+
+                    if ((state.getState() & ViewState.STATE_AUTOFILLED) != 0) {
+                        event.mAutofilledTimestampMs = timestamp;
+                    } else {
+                        if (event.mFieldModifiedFirstTimestampMs == DEFAULT_VALUE_INT) {
+                            event.mFieldModifiedFirstTimestampMs = timestamp;
+                        }
+                        event.mFieldModifiedLastTimestampMs = timestamp;
+                    }
+                });
+    }
+
+    public void setPresentationSelectedTimestamp() {
+        mEventInternal.ifPresent(event -> {
+            event.mSelectionTimestamp = getElapsedTime();
+        });
+    }
+
+    /**
+     * Returns timestamp (relative to mSessionStartTimestamp)
+     */
+    private int getElapsedTime() {
+        return (int)(SystemClock.elapsedRealtime() - mSessionStartTimestamp);
+    }
+
+
     private int convertDatasetPickReason(@Dataset.DatasetEligibleReason int val) {
         switch (val) {
             case 0:
@@ -648,7 +732,17 @@
                     + " mViewFillFailureCount=" + event.mViewFillFailureCount
                     + " mFocusedId=" + event.mFocusedId
                     + " mViewFillSuccessCount=" + event.mViewFillSuccessCount
-                    + " mViewFilledButUnexpectedCount=" + event.mViewFilledButUnexpectedCount);
+                    + " mViewFilledButUnexpectedCount=" + event.mViewFilledButUnexpectedCount
+                    + " event.mSelectionTimestamp=" + event.mSelectionTimestamp
+                    + " event.mAutofilledTimestampMs=" + event.mAutofilledTimestampMs
+                    + " event.mFieldModifiedFirstTimestampMs="
+                    + event.mFieldModifiedFirstTimestampMs
+                    + " event.mFieldModifiedLastTimestampMs=" + event.mFieldModifiedLastTimestampMs
+                    + " event.mSuggestionPresentedLastTimestampMs="
+                    + event.mSuggestionPresentedLastTimestampMs
+                    + " event.mFocusedVirtualAutofillId=" + event.mFocusedVirtualAutofillId
+                    + " event.mFieldFirstLength=" + event.mFieldFirstLength
+                    + " event.mFieldLastLength=" + event.mFieldLastLength);
         }
 
         // TODO(b/234185326): Distinguish empty responses from other no presentation reasons.
@@ -694,7 +788,15 @@
                 event.mViewFillFailureCount,
                 event.mFocusedId,
                 event.mViewFillSuccessCount,
-                event.mViewFilledButUnexpectedCount);
+                event.mViewFilledButUnexpectedCount,
+                event.mSelectionTimestamp,
+                event.mAutofilledTimestampMs,
+                event.mFieldModifiedFirstTimestampMs,
+                event.mFieldModifiedLastTimestampMs,
+                event.mSuggestionPresentedLastTimestampMs,
+                event.mFocusedVirtualAutofillId,
+                event.mFieldFirstLength,
+                event.mFieldLastLength);
         mEventInternal = Optional.empty();
     }
 
@@ -708,31 +810,39 @@
         int mCountNotShownImePresentationNotDrawn;
         int mCountNotShownImeUserNotSeen;
         int mDisplayPresentationType = AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__UNKNOWN_AUTOFILL_DISPLAY_PRESENTATION_TYPE;
-        int mAutofillServiceUid = -1;
-        int mInlineSuggestionHostUid = -1;
+        int mAutofillServiceUid = DEFAULT_VALUE_INT;
+        int mInlineSuggestionHostUid = DEFAULT_VALUE_INT;
         boolean mIsRequestTriggered;
-        int mFillRequestSentTimestampMs;
-        int mFillResponseReceivedTimestampMs;
-        int mSuggestionSentTimestampMs;
-        int mSuggestionPresentedTimestampMs;
-        int mSelectedDatasetId = -1;
+        int mFillRequestSentTimestampMs = DEFAULT_VALUE_INT;
+        int mFillResponseReceivedTimestampMs = DEFAULT_VALUE_INT;
+        int mSuggestionSentTimestampMs = DEFAULT_VALUE_INT;
+        int mSuggestionPresentedTimestampMs = DEFAULT_VALUE_INT;
+        int mSelectedDatasetId = DEFAULT_VALUE_INT;
         boolean mDialogDismissed = false;
         boolean mNegativeCtaButtonClicked = false;
         boolean mPositiveCtaButtonClicked = false;
         int mAuthenticationType = AUTHENTICATION_TYPE_UNKNOWN;
         int mAuthenticationResult = AUTHENTICATION_RESULT_UNKNOWN;
-        int mLatencyAuthenticationUiDisplayMillis = -1;
-        int mLatencyDatasetDisplayMillis = -1;
-        int mAvailablePccCount = -1;
-        int mAvailablePccOnlyCount = -1;
+        int mLatencyAuthenticationUiDisplayMillis = DEFAULT_VALUE_INT;
+        int mLatencyDatasetDisplayMillis = DEFAULT_VALUE_INT;
+        int mAvailablePccCount = DEFAULT_VALUE_INT;
+        int mAvailablePccOnlyCount = DEFAULT_VALUE_INT;
         @DatasetPickedReason int mSelectedDatasetPickedReason = PICK_REASON_UNKNOWN;
         @DetectionPreference int mDetectionPreference = DETECTION_PREFER_UNKNOWN;
-        int mFieldClassificationRequestId = -1;
+        int mFieldClassificationRequestId = DEFAULT_VALUE_INT;
         boolean mIsCredentialRequest = false;
         boolean mWebviewRequestedCredential = false;
-        int mViewFillableTotalCount = -1;
-        int mViewFillFailureCount = -1;
-        int mFocusedId = -1;
+        int mViewFillableTotalCount = DEFAULT_VALUE_INT;
+        int mViewFillFailureCount = DEFAULT_VALUE_INT;
+        int mFocusedId = DEFAULT_VALUE_INT;
+        int mSelectionTimestamp = DEFAULT_VALUE_INT;
+        int mAutofilledTimestampMs = DEFAULT_VALUE_INT;
+        int mFieldModifiedFirstTimestampMs = DEFAULT_VALUE_INT;
+        int mFieldModifiedLastTimestampMs = DEFAULT_VALUE_INT;
+        int mSuggestionPresentedLastTimestampMs = DEFAULT_VALUE_INT;
+        int mFocusedVirtualAutofillId = DEFAULT_VALUE_INT;
+        int mFieldFirstLength = DEFAULT_VALUE_INT;
+        int mFieldLastLength = DEFAULT_VALUE_INT;
 
         // Default value for success count is set to 0 explicitly. Setting it to -1 for
         // uninitialized doesn't help much, as this would be non-zero only if callback is received.
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index c46464b..aa67ffe 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1553,7 +1553,7 @@
         mLatencyBaseTime = mStartTime;
         mRequestCount = 0;
         mPresentationStatsEventLogger = PresentationStatsEventLogger.createPresentationLog(
-                sessionId, uid);
+                sessionId, uid, mLatencyBaseTime);
         mFillRequestEventLogger = FillRequestEventLogger.forSessionId(sessionId);
         mFillResponseEventLogger = FillResponseEventLogger.forSessionId(sessionId);
         mSessionCommittedEventLogger = SessionCommittedEventLogger.forSessionId(sessionId);
@@ -1575,14 +1575,6 @@
                     @Override
                     public void notifyInlineUiShown(AutofillId autofillId) {
                         notifyFillUiShown(autofillId);
-
-                        synchronized (mLock) {
-                            // TODO(b/262448552): Log when chip inflates instead of here
-                            final long inlineUiShownRelativeTimestamp =
-                                    SystemClock.elapsedRealtime() - mLatencyBaseTime;
-                            mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs(
-                                    (int) (inlineUiShownRelativeTimestamp));
-                        }
                     }
 
                     @Override
@@ -2678,6 +2670,7 @@
                 mLoggedInlineDatasetShown = true;
             }
             mService.logDatasetShown(this.id, mClientState, uiType);
+            mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs();
             Slog.d(TAG, "onShown(): " + uiType);
         }
     }
@@ -4788,7 +4781,6 @@
         updateFilteringStateOnValueChangedLocked(textValue, viewState);
 
         viewState.setCurrentValue(value);
-
         final String filterText = textValue;
 
         final AutofillValue filledValue = viewState.getAutofilledValue();
@@ -4815,6 +4807,7 @@
                 currentView.maybeCallOnFillReady(flags);
             }
         }
+        mPresentationStatsEventLogger.onFieldTextUpdated(viewState);
 
         if (viewState.id.equals(this.mCurrentViewId)
                 && (viewState.getState() & ViewState.STATE_INLINE_SHOWN) != 0) {
@@ -4902,10 +4895,7 @@
 
         synchronized (mLock) {
             // Time passed since Session was created
-            final long suggestionSentRelativeTimestamp =
-                    SystemClock.elapsedRealtime() - mLatencyBaseTime;
-            mPresentationStatsEventLogger.maybeSetSuggestionSentTimestampMs(
-                    (int) (suggestionSentRelativeTimestamp));
+            mPresentationStatsEventLogger.maybeSetSuggestionSentTimestampMs();
         }
 
         final AutofillId[] ids = response.getFillDialogTriggerIds();
@@ -4922,13 +4912,6 @@
                 // Note: Cannot disable before requestShowFillDialog() because the method
                 //       need to check whether fill dialog enabled.
                 setFillDialogDisabled();
-                synchronized (mLock) {
-                    // Logs when fill dialog ui is shown; time since Session was created
-                    final long fillDialogUiShownRelativeTimestamp =
-                            SystemClock.elapsedRealtime() - mLatencyBaseTime;
-                    mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs(
-                            (int) (fillDialogUiShownRelativeTimestamp));
-                }
                 return;
             } else {
                 setFillDialogDisabled();
@@ -4970,10 +4953,6 @@
                 // Log first time UI is shown.
                 mUiShownTime = SystemClock.elapsedRealtime();
                 final long duration = mUiShownTime - mStartTime;
-                // This logs when dropdown ui was shown. Timestamp is relative to
-                // when the session was created
-                mPresentationStatsEventLogger.maybeSetSuggestionPresentedTimestampMs(
-                        (int) (mUiShownTime - mLatencyBaseTime));
 
                 if (sDebug) {
                     final StringBuilder msg = new StringBuilder("1st UI for ")
diff --git a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
index f5db6e9..bc35fea 100644
--- a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
+++ b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
@@ -20,6 +20,7 @@
 import static android.app.AppOpsManager.OP_ASSIST_SCREENSHOT;
 import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
 import static android.content.Context.CONTEXTUAL_SEARCH_SERVICE;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
 import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
@@ -245,7 +246,7 @@
 
         if (DEBUG_USER) Log.d(TAG, "Launch component: " + launchIntent.getComponent());
         launchIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION
-                | FLAG_ACTIVITY_NO_USER_ACTION);
+                | FLAG_ACTIVITY_NO_USER_ACTION | FLAG_ACTIVITY_CLEAR_TASK);
         launchIntent.putExtra(
                 ContextualSearchManager.EXTRA_INVOCATION_TIME_MS,
                 SystemClock.uptimeMillis());
diff --git a/services/core/Android.bp b/services/core/Android.bp
index f1339e9..167c384 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -93,38 +93,6 @@
 }
 
 genrule {
-    name: "checked-protolog.json",
-    srcs: [
-        ":generate-protolog.json",
-        ":services.core.protolog.json",
-    ],
-    cmd: "cp $(location :generate-protolog.json) $(out) && " +
-        "{ ! (diff $(out) $(location :services.core.protolog.json) | grep -q '^<') || " +
-        "{ echo -e '\\n\\n################################################################\\n#\\n" +
-        "#  ERROR: ProtoLog viewer config is stale.  To update it, run:\\n#\\n" +
-        "#  cp $${ANDROID_BUILD_TOP}/$(location :generate-protolog.json) " +
-        "$${ANDROID_BUILD_TOP}/$(location :services.core.protolog.json)\\n#\\n" +
-        "################################################################\\n\\n' >&2 && false; } }",
-    out: ["services.core.protolog.json"],
-}
-
-genrule {
-    name: "checked-core.protolog.pb",
-    srcs: [
-        ":gen-core.protolog.pb",
-        ":file-core.protolog.pb",
-    ],
-    cmd: "cp $(location :gen-core.protolog.pb) $(out) && " +
-        "{ ! (diff $(out) $(location :file-core.protolog.pb) | grep -q '^<') || " +
-        "{ echo -e '\\n\\n################################################################\\n#\\n" +
-        "#  ERROR: ProtoLog viewer config is stale.  To update it, run:\\n#\\n" +
-        "#  cp $${ANDROID_BUILD_TOP}/$(location :gen-core.protolog.pb) " +
-        "$${ANDROID_BUILD_TOP}/$(location :file-core.protolog.pb)\\n#\\n" +
-        "################################################################\\n\\n' >&2 && false; } }",
-    out: ["core.protolog.pb"],
-}
-
-genrule {
     name: "statslog-art-java-gen",
     tools: ["stats-log-api-gen"],
     cmd: "$(location stats-log-api-gen) --java $(out) --module art" +
@@ -303,7 +271,7 @@
 
 genrule {
     name: "services.core.json.gz",
-    srcs: [":checked-protolog.json"],
+    srcs: [":generate-protolog.json"],
     out: ["services.core.protolog.json.gz"],
     cmd: "gzip -c < $(in) > $(out)",
 }
@@ -315,5 +283,5 @@
 
 prebuilt_etc {
     name: "core.protolog.pb",
-    src: ":checked-core.protolog.pb",
+    src: ":gen-core.protolog.pb",
 }
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index e64a87f..43774bbc 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -368,17 +368,17 @@
             Intent intent, @Nullable String resolvedType,
             @PackageManager.ResolveInfoFlagsBits long flags, int filterCallingUid, int userId);
 
-
     /**
      * Retrieve all receivers that can handle a broadcast of the given intent.
+     *
      * @param filterCallingUid The results will be filtered in the context of this UID instead
      *                         of the calling UID.
-     * @param forSend true if the invocation is intended for sending broadcasts. The value
-     *                of this parameter affects how packages are filtered.
+     * @param forSend          true if the invocation is intended for sending broadcasts. The value
+     *                         of this parameter affects how packages are filtered.
      */
-    public abstract List<ResolveInfo> queryIntentReceivers(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
-            int filterCallingUid, int userId, boolean forSend);
+    public abstract List<ResolveInfo> queryIntentReceivers(
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
+            int filterCallingUid, int callingPid, int userId, boolean forSend);
 
     /**
      * Retrieve all services that can be performed for the given intent.
@@ -611,17 +611,9 @@
             @NonNull Set<String> outInvalidPackageNames);
 
     /**
-     * Resolves an activity intent, allowing instant apps to be resolved.
-     */
-    public abstract ResolveInfo resolveIntent(Intent intent, String resolvedType,
-            @PackageManager.ResolveInfoFlagsBits long flags,
-            @PrivateResolveFlags long privateResolveFlags, int userId, boolean resolveForStart,
-            int filterCallingUid);
-
-    /**
      * Resolves an exported activity intent, allowing instant apps to be resolved.
      */
-    public abstract ResolveInfo resolveIntentExported(Intent intent, String resolvedType,
+    public abstract ResolveInfo resolveIntent(Intent intent, String resolvedType,
             @PackageManager.ResolveInfoFlagsBits long flags,
             @PrivateResolveFlags long privateResolveFlags, int userId, boolean resolveForStart,
             int filterCallingUid, int callingPid);
@@ -632,6 +624,15 @@
     public abstract ResolveInfo resolveService(Intent intent, String resolvedType,
             @PackageManager.ResolveInfoFlagsBits long flags, int userId, int callingUid);
 
+
+    /**
+     * Resolves a service intent for start.
+     */
+    public abstract ResolveInfo resolveService(
+            Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlagsBits long flags, int userId,
+            int callingUid, int callingPid);
+
     /**
     * Resolves a content provider intent.
     */
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 8c1bb3b..6285015 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -352,7 +352,7 @@
     @NonNull private final Set<String> mInitialNonStoppedSystemPackages = new ArraySet<>();
 
     // Which packages (key) are allowed to join particular SharedUid (value).
-    @NonNull private final Map<String, String> mPackageToSharedUidAllowList = new ArrayMap<>();
+    @NonNull private final ArrayMap<String, String> mPackageToSharedUidAllowList = new ArrayMap<>();
 
     // A map of preloaded package names and the path to its app metadata file path.
     private final ArrayMap<String, String> mAppMetadataFilePaths = new ArrayMap<>();
@@ -574,7 +574,7 @@
     }
 
     @NonNull
-    public Map<String, String> getPackageToSharedUidAllowList() {
+    public ArrayMap<String, String> getPackageToSharedUidAllowList() {
         return mPackageToSharedUidAllowList;
     }
 
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 59ebc6e..0c1d0fb 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -830,7 +830,8 @@
             for (int i = 0; i < smap.mServicesByInstanceName.size(); i++) {
                 final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i);
                 if (sr.appInfo.packageName.equals(pkg) && sr.isForeground) {
-                    if (Objects.equals(sr.foregroundNoti.getChannelId(), channelId)) {
+                    if (sr.foregroundNoti != null
+                            && Objects.equals(sr.foregroundNoti.getChannelId(), channelId)) {
                         if (DEBUG_FOREGROUND_SERVICE) {
                             Slog.d(TAG_SERVICE, "Channel u" + userId + "/pkg=" + pkg
                                     + "/channelId=" + channelId
@@ -4862,7 +4863,7 @@
                 }
                 // TODO: come back and remove this assumption to triage all services
                 ResolveInfo rInfo = mAm.getPackageManagerInternal().resolveService(service,
-                        resolvedType, flags, userId, callingUid);
+                        resolvedType, flags, userId, callingUid, callingPid);
                 ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
                 if (sInfo == null) {
                     Slog.w(TAG_SERVICE, "Unable to start service " + service + " U=" + userId +
@@ -4982,7 +4983,7 @@
                         try {
                             ResolveInfo rInfoForUserId0 =
                                     mAm.getPackageManagerInternal().resolveService(service,
-                                            resolvedType, flags, userId, callingUid);
+                                            resolvedType, flags, userId, callingUid, callingPid);
                             if (rInfoForUserId0 == null) {
                                 Slog.w(TAG_SERVICE,
                                         "Unable to resolve service " + service + " U=" + userId
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f7278e9..2600f10 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -137,7 +137,6 @@
 import static android.view.Display.INVALID_DISPLAY;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
-import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH;
 import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NEW_MUTABLE_IMPLICIT_PENDING_INTENT_RETRIEVED;
 import static com.android.sdksandbox.flags.Flags.sdkSandboxInstrumentationInfo;
 import static com.android.server.am.ActiveServices.FGS_SAW_RESTRICTIONS;
@@ -268,9 +267,7 @@
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetManagerInternal;
 import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledAfter;
 import android.compat.annotation.EnabledSince;
-import android.compat.annotation.Overridable;
 import android.content.AttributionSource;
 import android.content.AutofillOptions;
 import android.content.BroadcastReceiver;
@@ -467,7 +464,7 @@
 import com.android.server.os.NativeTombstoneManager;
 import com.android.server.pm.Computer;
 import com.android.server.pm.Installer;
-import com.android.server.pm.PackageManagerServiceUtils;
+import com.android.server.pm.SaferIntentUtils;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.pm.pkg.AndroidPackage;
@@ -666,18 +663,6 @@
     private static final long DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED = 161145287L;
 
     /**
-     * Apps targeting Android U and above will need to export components in order to invoke them
-     * through implicit intents.
-     *
-     * If a component is not exported and invoked, it will be removed from the list of receivers.
-     * This applies specifically to activities and broadcasts.
-     */
-    @ChangeId
-    @Overridable
-    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
-    public static final long IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS = 229362273;
-
-    /**
      * The maximum number of bytes that {@link #setProcessStateSummary} accepts.
      *
      * @see {@link android.app.ActivityManager#setProcessStateSummary(byte[])}
@@ -5551,9 +5536,10 @@
                                         packageName, UserHandle.of(userId));
                         String resolvedType = resolvedTypes == null
                                 || i >= resolvedTypes.length ? null : resolvedTypes[i];
-                        ActivityManagerUtils.logUnsafeIntentEvent(
+                        SaferIntentUtils.reportUnsafeIntentEvent(
                                 UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NEW_MUTABLE_IMPLICIT_PENDING_INTENT_RETRIEVED,
-                                owningUid, intent, resolvedType, isChangeEnabled);
+                                owningUid, Process.INVALID_PID,
+                                intent, resolvedType, isChangeEnabled);
                         if (isChangeEnabled) {
                             String msg = packageName + ": Targeting U+ (version "
                                     + Build.VERSION_CODES.UPSIDE_DOWN_CAKE + " and above) disallows"
@@ -5813,7 +5799,7 @@
                         intent, matchFlags, uid, userId));
             case ActivityManager.INTENT_SENDER_BROADCAST:
                 return new ParceledListSlice<>(mPackageManagerInt.queryIntentReceivers(
-                        intent, resolvedType, matchFlags, uid, userId, false));
+                        intent, resolvedType, matchFlags, uid, Process.INVALID_PID, userId, false));
             default: // ActivityManager.INTENT_SENDER_ACTIVITY_RESULT
                 throw new IllegalStateException("Unsupported intent sender type: " + res.key.type);
         }
@@ -9521,14 +9507,13 @@
      * @param callback The binder used to communicate the violations.
      */
     @Override
-    public void registerStrictModeCallback(IBinder callback) {
+    public synchronized void registerStrictModeCallback(IBinder callback) {
         int callingPid = Binder.getCallingPid();
         mStrictModeCallbacks.put(callingPid,
                 IUnsafeIntentStrictModeCallback.Stub.asInterface(callback));
         try {
-            callback.linkToDeath(new DeathRecipient() {
-                @Override
-                public void binderDied() {
+            callback.linkToDeath(() -> {
+                synchronized (ActivityManagerService.this) {
                     mStrictModeCallbacks.remove(callingPid);
                 }
             }, 0);
@@ -13731,64 +13716,6 @@
     }
 
     /**
-     * Filters out non-exported components in a given list of broadcast filters
-     * @param intent the original intent
-     * @param callingUid the calling UID
-     * @param query the list of broadcast filters
-     * @param platformCompat the instance of platform compat
-     */
-    private void filterNonExportedComponents(Intent intent, int callingUid, int callingPid,
-            List query, PlatformCompat platformCompat, String callerPackage, String resolvedType) {
-        if (query == null
-                || intent.getPackage() != null
-                || intent.getComponent() != null
-                || ActivityManager.canAccessUnexportedComponents(callingUid)) {
-            return;
-        }
-        IUnsafeIntentStrictModeCallback callback = mStrictModeCallbacks.get(callingPid);
-        for (int i = query.size() - 1; i >= 0; i--) {
-            String componentInfo;
-            ResolveInfo resolveInfo;
-            BroadcastFilter broadcastFilter;
-            if (query.get(i) instanceof ResolveInfo) {
-                resolveInfo = (ResolveInfo) query.get(i);
-                if (resolveInfo.getComponentInfo().exported) {
-                    continue;
-                }
-                componentInfo = resolveInfo.getComponentInfo()
-                        .getComponentName().flattenToShortString();
-            } else if (query.get(i) instanceof BroadcastFilter) {
-                broadcastFilter = (BroadcastFilter) query.get(i);
-                if (broadcastFilter.exported) {
-                    continue;
-                }
-                componentInfo = broadcastFilter.packageName;
-            } else {
-                continue;
-            }
-            if (callback != null) {
-                mHandler.post(() -> {
-                    try {
-                        callback.onImplicitIntentMatchedInternalComponent(intent.cloneFilter());
-                    } catch (RemoteException e) {
-                        mStrictModeCallbacks.remove(callingPid);
-                    }
-                });
-            }
-            boolean hasToBeExportedToMatch = platformCompat.isChangeEnabledByUid(
-                    ActivityManagerService.IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS,
-                    callingUid);
-            ActivityManagerUtils.logUnsafeIntentEvent(
-                    UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH,
-                    callingUid, intent, resolvedType, hasToBeExportedToMatch);
-            if (!hasToBeExportedToMatch) {
-                return;
-            }
-            query.remove(i);
-        }
-    }
-
-    /**
      * Main code for cleaning up a process when it has gone away.  This is
      * called both as a result of the process dying, or directly when stopping
      * a process when running in single process mode.
@@ -15101,8 +15028,9 @@
         mProcessList.sendPackageBroadcastLocked(cmd, packages, userId);
     }
 
-    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
-            int callingUid, int[] users, int[] broadcastAllowList) {
+    private List<ResolveInfo> collectReceiverComponents(
+            Intent intent, String resolvedType, int callingUid, int callingPid,
+            int[] users, int[] broadcastAllowList) {
         // TODO: come back and remove this assumption to triage all broadcasts
         long pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
 
@@ -15117,7 +15045,7 @@
                 continue;
             }
             List<ResolveInfo> newReceivers = mPackageManagerInt.queryIntentReceivers(
-                    intent, resolvedType, pmFlags, callingUid, user, true /* forSend */);
+                    intent, resolvedType, pmFlags, callingUid, callingPid, user, /* forSend */true);
             if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
                 // If this is not the system user, we need to check for
                 // any receivers that should be filtered out.
@@ -15135,7 +15063,7 @@
                     final ResolveInfo ri = newReceivers.get(i);
                     final Resolution<ResolveInfo> resolution =
                             mComponentAliasResolver.resolveReceiver(intent, ri, resolvedType,
-                                    pmFlags, user, callingUid, true /* forSend */);
+                                    pmFlags, user, callingUid, callingPid);
                     if (resolution == null) {
                         // It was an alias, but the target was not found.
                         newReceivers.remove(i);
@@ -15977,6 +15905,10 @@
             users = new int[] {userId};
         }
 
+        var args = new SaferIntentUtils.IntentArgs(intent, resolvedType,
+                true /* isReceiver */, true /* resolveForStart */, callingUid, callingPid);
+        args.platformCompat = mPlatformCompat;
+
         // Figure out who all will receive this broadcast.
         final int cookie = BroadcastQueue.traceBegin("queryReceivers");
         List receivers = null;
@@ -15984,7 +15916,7 @@
         // Need to resolve the intent to interested receivers...
         if ((intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
             receivers = collectReceiverComponents(
-                    intent, resolvedType, callingUid, users, broadcastAllowList);
+                    intent, resolvedType, callingUid, callingPid, users, broadcastAllowList);
         }
         if (intent.getComponent() == null) {
             final PackageDataSnapshot snapshot = getPackageManagerInternal().snapshot();
@@ -16009,9 +15941,7 @@
                         resolvedType, false /*defaultOnly*/, userId);
             }
             if (registeredReceivers != null) {
-                PackageManagerServiceUtils.applyNullActionBlocking(
-                        mPlatformCompat, snapshot, registeredReceivers,
-                        true, intent, callingUid);
+                SaferIntentUtils.blockNullAction(args, registeredReceivers);
             }
         }
         BroadcastQueue.traceEnd(cookie);
@@ -16033,8 +15963,6 @@
             }
         }
 
-        filterNonExportedComponents(intent, callingUid, callingPid, registeredReceivers,
-                mPlatformCompat, callerPackage, resolvedType);
         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
 
         // Merge into one list.
@@ -16117,8 +16045,7 @@
         if ((receivers != null && receivers.size() > 0)
                 || resultTo != null) {
             BroadcastQueue queue = mBroadcastQueue;
-            filterNonExportedComponents(intent, callingUid, callingPid, receivers,
-                    mPlatformCompat, callerPackage, resolvedType);
+            SaferIntentUtils.filterNonExportedComponents(args, receivers);
             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
                     callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
                     requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions,
@@ -19926,13 +19853,23 @@
         }
 
         @Override
-        public IUnsafeIntentStrictModeCallback getRegisteredStrictModeCallback(int callingPid) {
-            return mStrictModeCallbacks.get(callingPid);
-        }
-
-        @Override
-        public void unregisterStrictModeCallback(int callingPid) {
-            mStrictModeCallbacks.remove(callingPid);
+        public void triggerUnsafeIntentStrictMode(int callingPid, int type, Intent intent) {
+            final IUnsafeIntentStrictModeCallback callback;
+            final Intent i = intent.cloneFilter();
+            synchronized (ActivityManagerService.this) {
+                callback = mStrictModeCallbacks.get(callingPid);
+            }
+            if (callback != null) {
+                BackgroundThread.getExecutor().execute(() -> {
+                    try {
+                        callback.onUnsafeIntent(type, i);
+                    } catch (RemoteException e) {
+                        synchronized (ActivityManagerService.this) {
+                            mStrictModeCallbacks.remove(callingPid);
+                        }
+                    }
+                });
+            }
         }
 
         @Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerUtils.java b/services/core/java/com/android/server/am/ActivityManagerUtils.java
index 78a2ecb..3e43a82 100644
--- a/services/core/java/com/android/server/am/ActivityManagerUtils.java
+++ b/services/core/java/com/android/server/am/ActivityManagerUtils.java
@@ -17,13 +17,11 @@
 
 import android.app.ActivityThread;
 import android.content.ContentResolver;
-import android.content.Intent;
 import android.provider.Settings;
 import android.util.ArrayMap;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FrameworkStatsLog;
 
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -127,25 +125,4 @@
 
         return (((double) hash) / Integer.MAX_VALUE) <= rate;
     }
-
-    /**
-     * Helper method to log an unsafe intent event.
-     */
-    public static void logUnsafeIntentEvent(int event, int callingUid,
-            Intent intent, String resolvedType, boolean blocked) {
-        String[] categories = intent.getCategories() == null ? new String[0]
-                : intent.getCategories().toArray(String[]::new);
-        String component = intent.getComponent() == null ? null
-                : intent.getComponent().flattenToString();
-        FrameworkStatsLog.write(FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED,
-                event,
-                callingUid,
-                component,
-                intent.getPackage(),
-                intent.getAction(),
-                categories,
-                resolvedType,
-                intent.getScheme(),
-                blocked);
-    }
 }
diff --git a/services/core/java/com/android/server/am/BroadcastFilter.java b/services/core/java/com/android/server/am/BroadcastFilter.java
index 7494277..adb2392 100644
--- a/services/core/java/com/android/server/am/BroadcastFilter.java
+++ b/services/core/java/com/android/server/am/BroadcastFilter.java
@@ -26,7 +26,7 @@
 
 import java.io.PrintWriter;
 
-final class BroadcastFilter extends IntentFilter {
+public final class BroadcastFilter extends IntentFilter {
     // Back-pointer to the list this filter is in.
     final ReceiverList receiverList;
     final String packageName;
@@ -37,7 +37,7 @@
     final int owningUserId;
     final boolean instantApp;
     final boolean visibleToInstantApp;
-    final boolean exported;
+    public final boolean exported;
 
     BroadcastFilter(IntentFilter _filter, ReceiverList _receiverList,
             String _packageName, String _featureId, String _receiverId, String _requiredPermission,
diff --git a/services/core/java/com/android/server/am/ComponentAliasResolver.java b/services/core/java/com/android/server/am/ComponentAliasResolver.java
index 3fa6102..5d84fd9 100644
--- a/services/core/java/com/android/server/am/ComponentAliasResolver.java
+++ b/services/core/java/com/android/server/am/ComponentAliasResolver.java
@@ -455,9 +455,9 @@
     }
 
     @Nullable
-    public Resolution<ResolveInfo> resolveReceiver(@NonNull Intent intent,
-            @NonNull ResolveInfo receiver, @Nullable String resolvedType,
-            long packageFlags, int userId, int callingUid, boolean forSend) {
+    public Resolution<ResolveInfo> resolveReceiver(
+            @NonNull Intent intent, @NonNull ResolveInfo receiver, @Nullable String resolvedType,
+            long packageFlags, int userId, int callingUid, int callingPid) {
         // Resolve this alias.
         final Resolution<ComponentName> resolution = resolveComponentAlias(() ->
                 receiver.activityInfo.getComponentName());
@@ -481,7 +481,7 @@
         i.setComponent(resolution.getTarget());
 
         List<ResolveInfo> resolved = pmi.queryIntentReceivers(
-                i, resolvedType, packageFlags, callingUid, userId, forSend);
+                i, resolvedType, packageFlags, callingUid, callingPid, userId, /*forSend*/ true);
         if (resolved == null || resolved.size() == 0) {
             // Target component not found.
             Slog.w(TAG, "Alias target " + target.flattenToShortString() + " not found");
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 8d71c70..60d0353 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1361,7 +1361,7 @@
         state = mPowerState.getScreenState();
 
         DisplayBrightnessState displayBrightnessState = mDisplayBrightnessController
-                .updateBrightness(mPowerRequest, state);
+                .updateBrightness(mPowerRequest, state, mDisplayOffloadSession);
         float brightnessState = displayBrightnessState.getBrightness();
         float rawBrightnessState = displayBrightnessState.getBrightness();
         mBrightnessReasonTemp.set(displayBrightnessState.getBrightnessReason());
@@ -1374,6 +1374,10 @@
         if (displayBrightnessState.getBrightnessEvent() != null) {
             mTempBrightnessEvent.copyFrom(displayBrightnessState.getBrightnessEvent());
         }
+
+        boolean allowAutoBrightnessWhileDozing =
+                mDisplayBrightnessController.isAllowAutoBrightnessWhileDozing();
+
         if (!mFlags.isRefactorDisplayPowerControllerEnabled()) {
             // Set up the ScreenOff controller used when coming out of SCREEN_OFF and the ALS sensor
             // doesn't yet have a valid lux value to use with auto-brightness.
@@ -1381,8 +1385,7 @@
                 mScreenOffBrightnessSensorController
                         .setLightSensorEnabled(displayBrightnessState.getShouldUseAutoBrightness()
                         && mIsEnabled && (state == Display.STATE_OFF
-                        || (state == Display.STATE_DOZE
-                        && !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig()))
+                        || (state == Display.STATE_DOZE && !allowAutoBrightnessWhileDozing))
                         && mLeadDisplayId == Layout.NO_LEAD_DISPLAY);
             }
         }
@@ -1392,12 +1395,7 @@
         final boolean wasShortTermModelActive =
                 mAutomaticBrightnessStrategy.isShortTermModelActive();
         boolean userInitiatedChange = displayBrightnessState.isUserInitiatedChange();
-        boolean allowAutoBrightnessWhileDozing =
-                mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig();
-        if (mFlags.offloadControlsDozeAutoBrightness() && mFlags.isDisplayOffloadEnabled()
-                && mDisplayOffloadSession != null) {
-            allowAutoBrightnessWhileDozing &= mDisplayOffloadSession.allowAutoBrightnessInDoze();
-        }
+
         if (!mFlags.isRefactorDisplayPowerControllerEnabled()) {
             // Switch to doze auto-brightness mode if needed
             if (mFlags.areAutoBrightnessModesEnabled() && mAutomaticBrightnessController != null
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
index d567331..4982a0b0 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
@@ -146,11 +146,13 @@
      */
     public DisplayBrightnessState updateBrightness(
             DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
-            int targetDisplayState) {
+            int targetDisplayState,
+            DisplayManagerInternal.DisplayOffloadSession displayOffloadSession) {
         DisplayBrightnessState state;
         synchronized (mLock) {
             mDisplayBrightnessStrategy = mDisplayBrightnessStrategySelector.selectStrategy(
-                    constructStrategySelectionRequest(displayPowerRequest, targetDisplayState));
+                    constructStrategySelectionRequest(displayPowerRequest, targetDisplayState,
+                            displayOffloadSession));
             state = mDisplayBrightnessStrategy
                         .updateBrightness(constructStrategyExecutionRequest(displayPowerRequest));
         }
@@ -204,6 +206,16 @@
      * Returns a boolean flag indicating if the light sensor is to be used to decide the screen
      * brightness when dozing
      */
+    public boolean isAllowAutoBrightnessWhileDozing() {
+        synchronized (mLock) {
+            return mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozing();
+        }
+    }
+
+    /**
+     * Returns the config value indicating the auto brightness while dozing is to be
+     * allowed ot not. Note that this is a config value, but the actual status can differ from this.
+     */
     public boolean isAllowAutoBrightnessWhileDozingConfig() {
         synchronized (mLock) {
             return mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozingConfig();
@@ -587,14 +599,15 @@
 
     private StrategySelectionRequest constructStrategySelectionRequest(
             DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
-            int targetDisplayState) {
+            int targetDisplayState,
+            DisplayManagerInternal.DisplayOffloadSession displayOffloadSession) {
         boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
         float lastUserSetScreenBrightness;
         synchronized (mLock) {
             lastUserSetScreenBrightness = mLastUserSetScreenBrightness;
         }
         return new StrategySelectionRequest(displayPowerRequest, targetDisplayState,
-                lastUserSetScreenBrightness, userSetBrightnessChanged);
+                lastUserSetScreenBrightness, userSetBrightnessChanged, displayOffloadSession);
     }
 
     private StrategyExecutionRequest constructStrategyExecutionRequest(
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
index feec4e6..7835220 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
@@ -48,9 +48,14 @@
  */
 public class DisplayBrightnessStrategySelector {
     private static final String TAG = "DisplayBrightnessStrategySelector";
-    // True if light sensor is to be used to automatically determine doze screen brightness.
+    // True if the config to use the light sensor to automatically determine doze screen brightness
+    // is enabled. Note that the actual value representing if the auto-brightness is to be kept
+    // enabled while dozing can differ, but is dependent on this
     private final boolean mAllowAutoBrightnessWhileDozingConfig;
 
+    // True if light sensor is to be used to automatically determine doze screen brightness.
+    private boolean mAllowAutoBrightnessWhileDozing;
+
     // The brightness strategy used to manage the brightness state when the display is dozing.
     private final DozeBrightnessStrategy mDozeBrightnessStrategy;
     // The brightness strategy used to manage the brightness state when the display is in
@@ -149,6 +154,7 @@
                 mAutoBrightnessFallbackStrategy, mFallbackBrightnessStrategy};
         mAllowAutoBrightnessWhileDozingConfig = context.getResources().getBoolean(
                 R.bool.config_allowAutoBrightnessWhileDozing);
+        mAllowAutoBrightnessWhileDozing = mAllowAutoBrightnessWhileDozingConfig;
         mOldBrightnessStrategyName = mInvalidBrightnessStrategy.getName();
     }
 
@@ -163,6 +169,7 @@
         int targetDisplayState = strategySelectionRequest.getTargetDisplayState();
         DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = strategySelectionRequest
                 .getDisplayPowerRequest();
+        setAllowAutoBrightnessWhileDozing(strategySelectionRequest.getDisplayOffloadSession());
         if (targetDisplayState == Display.STATE_OFF) {
             displayBrightnessStrategy = mScreenOffBrightnessStrategy;
         } else if (shouldUseDozeBrightnessStrategy(displayPowerRequest)) {
@@ -231,6 +238,14 @@
      * Returns a boolean flag indicating if the light sensor is to be used to decide the screen
      * brightness when dozing
      */
+    public boolean isAllowAutoBrightnessWhileDozing() {
+        return mAllowAutoBrightnessWhileDozing;
+    }
+
+    /**
+     * Returns the config value indicating whether auto brightness while dozing is to be
+     * allowed ot not
+     */
     public boolean isAllowAutoBrightnessWhileDozingConfig() {
         return mAllowAutoBrightnessWhileDozingConfig;
     }
@@ -251,6 +266,8 @@
         writer.println(
                 "  mAllowAutoBrightnessWhileDozingConfig= "
                         + mAllowAutoBrightnessWhileDozingConfig);
+        writer.println(
+                "  mAllowAutoBrightnessWhileDozing= " + mAllowAutoBrightnessWhileDozing);
         IndentingPrintWriter ipw = new IndentingPrintWriter(writer, " ");
         for (DisplayBrightnessStrategy displayBrightnessStrategy : mDisplayBrightnessStrategies) {
             if (displayBrightnessStrategy != null) {
@@ -259,6 +276,17 @@
         }
     }
 
+    @VisibleForTesting
+    void setAllowAutoBrightnessWhileDozing(
+            DisplayManagerInternal.DisplayOffloadSession displayOffloadSession) {
+        mAllowAutoBrightnessWhileDozing = mAllowAutoBrightnessWhileDozingConfig;
+        if (mDisplayManagerFlags.offloadControlsDozeAutoBrightness()
+                && mDisplayManagerFlags.isDisplayOffloadEnabled()
+                && displayOffloadSession != null) {
+            mAllowAutoBrightnessWhileDozing &= displayOffloadSession.allowAutoBrightnessInDoze();
+        }
+    }
+
     private boolean isAutoBrightnessFallbackStrategyValid() {
         return mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()
                 && mAutoBrightnessFallbackStrategy != null
@@ -270,7 +298,7 @@
             StrategySelectionRequest strategySelectionRequest) {
         mAutomaticBrightnessStrategy1.setAutoBrightnessState(
                 strategySelectionRequest.getTargetDisplayState(),
-                mAllowAutoBrightnessWhileDozingConfig,
+                mAllowAutoBrightnessWhileDozing,
                 BrightnessReason.REASON_UNKNOWN,
                 strategySelectionRequest.getDisplayPowerRequest().policy,
                 strategySelectionRequest.getLastUserSetScreenBrightness(),
@@ -287,7 +315,7 @@
                 selectedDisplayBrightnessStrategy,
                 strategySelectionRequest.getLastUserSetScreenBrightness(),
                 strategySelectionRequest.isUserSetBrightnessChanged(),
-                isAllowAutoBrightnessWhileDozingConfig(),
+                mAllowAutoBrightnessWhileDozing,
                 getAutomaticBrightnessStrategy().shouldUseAutoBrightness());
     }
 
@@ -309,7 +337,7 @@
         // a user can define a different display state(displayPowerRequest.dozeScreenState) too
         // in the request with the Doze policy
         return displayPowerRequest.policy == DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE
-                && !mAllowAutoBrightnessWhileDozingConfig
+                && !mAllowAutoBrightnessWhileDozing
                 && BrightnessUtils.isValidBrightnessValue(displayPowerRequest.dozeScreenBrightness);
     }
 
diff --git a/services/core/java/com/android/server/display/brightness/StrategySelectionRequest.java b/services/core/java/com/android/server/display/brightness/StrategySelectionRequest.java
index ae745efc..aa2f23e 100644
--- a/services/core/java/com/android/server/display/brightness/StrategySelectionRequest.java
+++ b/services/core/java/com/android/server/display/brightness/StrategySelectionRequest.java
@@ -38,13 +38,17 @@
     // Represents if the user set screen brightness was changed or not.
     private boolean mUserSetBrightnessChanged;
 
+    private DisplayManagerInternal.DisplayOffloadSession mDisplayOffloadSession;
+
     public StrategySelectionRequest(DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
             int targetDisplayState, float lastUserSetScreenBrightness,
-            boolean userSetBrightnessChanged) {
+            boolean userSetBrightnessChanged,
+            DisplayManagerInternal.DisplayOffloadSession displayOffloadSession) {
         mDisplayPowerRequest = displayPowerRequest;
         mTargetDisplayState = targetDisplayState;
         mLastUserSetScreenBrightness = lastUserSetScreenBrightness;
         mUserSetBrightnessChanged = userSetBrightnessChanged;
+        mDisplayOffloadSession = displayOffloadSession;
     }
 
     public DisplayManagerInternal.DisplayPowerRequest getDisplayPowerRequest() {
@@ -64,6 +68,10 @@
         return mUserSetBrightnessChanged;
     }
 
+    public DisplayManagerInternal.DisplayOffloadSession getDisplayOffloadSession() {
+        return mDisplayOffloadSession;
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (!(obj instanceof StrategySelectionRequest)) {
@@ -73,12 +81,13 @@
         return Objects.equals(mDisplayPowerRequest, other.getDisplayPowerRequest())
                 && mTargetDisplayState == other.getTargetDisplayState()
                 && mLastUserSetScreenBrightness == other.getLastUserSetScreenBrightness()
-                && mUserSetBrightnessChanged == other.isUserSetBrightnessChanged();
+                && mUserSetBrightnessChanged == other.isUserSetBrightnessChanged()
+                && mDisplayOffloadSession.equals(other.getDisplayOffloadSession());
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mDisplayPowerRequest, mTargetDisplayState,
-                mLastUserSetScreenBrightness, mUserSetBrightnessChanged);
+                mLastUserSetScreenBrightness, mUserSetBrightnessChanged, mDisplayOffloadSession);
     }
 }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 962520b..fb5f5ae 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2327,10 +2327,12 @@
             @NonNull InputMethodBindingController bindingController, @NonNull ClientState cs) {
         if (bindingController.hasMainConnection()) {
             if (getCurMethodLocked() != null) {
-                // Return to client, and we will get back with it when
-                // we have had a session made for it.
-                requestClientSessionLocked(cs);
-                requestClientSessionForAccessibilityLocked(cs);
+                if (!Flags.useZeroJankProxy()) {
+                    // Return to client, and we will get back with it when
+                    // we have had a session made for it.
+                    requestClientSessionLocked(cs);
+                    requestClientSessionForAccessibilityLocked(cs);
+                }
                 return new InputBindResult(
                         InputBindResult.ResultCode.SUCCESS_WAITING_IME_SESSION,
                         null, null, null,
@@ -2942,8 +2944,6 @@
             id = imi.getId();
             settings.putSelectedInputMethod(id);
         }
-        final var bindingController = getInputMethodBindingController(userId);
-        bindingController.setSelectedMethodId(id);
     }
 
     @GuardedBy("ImfLock.class")
diff --git a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
index 189c1a7..757c07c 100644
--- a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
+++ b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
@@ -248,6 +248,17 @@
                     unverifiedTargetSdkVersion,
                     userId, imeDispatcher);
             sendOnStartInputResult(client, result, startInputSeq);
+            // For first-time client bind, MSG_BIND should arrive after MSG_START_INPUT_RESULT.
+            if (result.result == InputBindResult.ResultCode.SUCCESS_WAITING_IME_SESSION) {
+                InputMethodManagerService imms = ((InputMethodManagerService) mInner);
+                synchronized (ImfLock.class) {
+                    ClientState cs = imms.getClientStateLocked(client);
+                    if (cs != null) {
+                        imms.requestClientSessionLocked(cs);
+                        imms.requestClientSessionForAccessibilityLocked(cs);
+                    }
+                }
+            }
         });
     }
 
diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java
index fe774aa..8b72138 100644
--- a/services/core/java/com/android/server/pm/AppDataHelper.java
+++ b/services/core/java/com/android/server/pm/AppDataHelper.java
@@ -345,7 +345,7 @@
         final StorageManager storage = mInjector.getSystemService(StorageManager.class);
         for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
             final String volumeUuid = vol.getFsUuid();
-            synchronized (mPm.mInstallLock) {
+            try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
                 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
             }
         }
@@ -505,8 +505,8 @@
             storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
         }
         final List<String> deferPackages;
-        synchronized (mPm.mInstallLock) {
-           deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
+            deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
                     UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
                     true /* onlyCoreApps */);
         }
@@ -541,7 +541,7 @@
                     count++;
                 }
             }
-            synchronized (mPm.mInstallLock) {
+            try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
                 executeBatchLI(batch);
             }
             traceLog.traceEnd();
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index 482807c..3528d3d 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -108,16 +108,20 @@
     default int getUsed() {
         return 0;
     }
-    @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
+    @NonNull List<ResolveInfo> queryIntentActivitiesInternal(
+            Intent intent, String resolvedType,
             @PackageManager.ResolveInfoFlagsBits long flags,
             @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags,
-            int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits);
+            int filterCallingUid, int callingPid, int userId,
+            boolean resolveForStart, boolean allowDynamicSplits);
     @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
             long flags, int filterCallingUid, int userId);
     @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
             long flags, int userId);
-    @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, String resolvedType,
-            long flags, int userId, int callingUid, boolean includeInstantApps);
+    @NonNull List<ResolveInfo> queryIntentServicesInternal(
+            Intent intent, String resolvedType, long flags,
+            int userId, int callingUid, int callingPid,
+            boolean includeInstantApps, boolean resolveForStart);
     @NonNull QueryIntentActivitiesResult queryIntentActivitiesInternalBody(Intent intent,
             String resolvedType, long flags, int filterCallingUid, int userId,
             boolean resolveForStart, boolean allowDynamicSplits, String pkgName,
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 6a25f64..e2a6b81 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -500,10 +500,10 @@
         return mUsed;
     }
 
-    public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
+    public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
             @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags,
-            int filterCallingUid, int userId, boolean resolveForStart,
+            int filterCallingUid, int callingPid, int userId, boolean resolveForStart,
             boolean allowDynamicSplits) {
         if (!mUserManager.exists(userId)) return Collections.emptyList();
 
@@ -530,6 +530,11 @@
                 isImplicitImageCaptureIntentAndNotSetByDpc(intent, userId, resolvedType,
                         flags));
 
+        var args = new SaferIntentUtils.IntentArgs(intent, resolvedType,
+                false /* isReceiver */, resolveForStart, filterCallingUid, callingPid);
+        args.platformCompat = mInjector.getCompatibility();
+        args.snapshot = this;
+
         List<ResolveInfo> list = Collections.emptyList();
         boolean skipPostResolution = false;
         if (comp != null) {
@@ -583,9 +588,7 @@
                     ri.userHandle = UserHandle.of(userId);
                     list = new ArrayList<>(1);
                     list.add(ri);
-                    PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
-                            mInjector.getCompatibility(), this, list, false, intent,
-                            resolvedType, filterCallingUid);
+                    SaferIntentUtils.enforceIntentFilterMatching(args, list);
                 }
             }
         } else {
@@ -609,15 +612,13 @@
                 }
                 list = lockedResult.result;
             }
-            PackageManagerServiceUtils.applyNullActionBlocking(
-                    mInjector.getCompatibility(), this, list, false, intent, filterCallingUid);
+            SaferIntentUtils.blockNullAction(args, list);
         }
 
         if (originalIntent != null) {
             // We also have to ensure all components match the original intent
-            PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
-                    mInjector.getCompatibility(), this, list, false, originalIntent,
-                    resolvedType, filterCallingUid);
+            args.intent = originalIntent;
+            SaferIntentUtils.enforceIntentFilterMatching(args, list);
         }
 
         return skipPostResolution ? list : applyPostResolutionFilter(
@@ -631,19 +632,22 @@
             @PackageManager.ResolveInfoFlagsBits long flags, int filterCallingUid, int userId) {
         return queryIntentActivitiesInternal(
                 intent, resolvedType, flags, 0 /*privateResolveFlags*/, filterCallingUid,
-                userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
+                Process.INVALID_PID, userId,
+                /*resolveForStart*/ false, /*allowDynamicSplits*/ true);
     }
 
     public final @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
             String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
         return queryIntentActivitiesInternal(
-                intent, resolvedType, flags, 0 /*privateResolveFlags*/, Binder.getCallingUid(),
-                userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
+                intent, resolvedType, flags, 0 /*privateResolveFlags*/,
+                Binder.getCallingUid(), Process.INVALID_PID, userId,
+                /*resolveForStart*/ false, /*allowDynamicSplits*/ true);
     }
 
-    public final @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId,
-            int callingUid, boolean includeInstantApps) {
+    public final @NonNull List<ResolveInfo> queryIntentServicesInternal(
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
+            int userId, int callingUid, int callingPid,
+            boolean includeInstantApps, boolean resolveForStart) {
         if (!mUserManager.exists(userId)) return Collections.emptyList();
         enforceCrossUserOrProfilePermission(callingUid,
                 userId,
@@ -654,6 +658,11 @@
         flags = updateFlagsForResolve(flags, userId, callingUid, includeInstantApps,
                 false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
 
+        var args = new SaferIntentUtils.IntentArgs(intent, resolvedType,
+                false /* isReceiver */, resolveForStart, callingUid, callingPid);
+        args.platformCompat = mInjector.getCompatibility();
+        args.snapshot = this;
+
         Intent originalIntent = null;
         ComponentName comp = intent.getComponent();
         if (comp == null) {
@@ -699,23 +708,19 @@
                     ri.serviceInfo = si;
                     list = new ArrayList<>(1);
                     list.add(ri);
-                    PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
-                            mInjector.getCompatibility(), this, list, false, intent,
-                            resolvedType, callingUid);
+                    SaferIntentUtils.enforceIntentFilterMatching(args, list);
                 }
             }
         } else {
             list = queryIntentServicesInternalBody(intent, resolvedType, flags,
                     userId, callingUid, instantAppPkgName);
-            PackageManagerServiceUtils.applyNullActionBlocking(
-                    mInjector.getCompatibility(), this, list, false, intent, callingUid);
+            SaferIntentUtils.blockNullAction(args, list);
         }
 
         if (originalIntent != null) {
             // We also have to ensure all components match the original intent
-            PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
-                    mInjector.getCompatibility(), this, list, false, originalIntent,
-                    resolvedType, callingUid);
+            args.intent = originalIntent;
+            SaferIntentUtils.enforceIntentFilterMatching(args, list);
         }
 
         return list;
@@ -847,8 +852,8 @@
         // IMPORTANT: disallow dynamic splits to avoid an infinite loop
         final List<ResolveInfo> result = queryIntentActivitiesInternal(
                 failureActivityIntent, null /*resolvedType*/, 0 /*flags*/,
-                0 /*privateResolveFlags*/, filterCallingUid, userId, false /*resolveForStart*/,
-                false /*allowDynamicSplits*/);
+                0 /*privateResolveFlags*/, filterCallingUid, Process.INVALID_PID, userId,
+                /*resolveForStart*/ false, /*allowDynamicSplits*/ false);
         final int numResults = result.size();
         if (numResults > 0) {
             for (int i = 0; i < numResults; i++) {
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 47ee1d0..b56e119 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -241,7 +241,7 @@
             isInstallerPackage = mPm.mSettings.isInstallerPackage(packageName);
         }
 
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
             try (PackageFreezer freezer = mPm.freezePackageForDelete(packageName, freezeUser,
                     deleteFlags, "deletePackageX", ApplicationExitInfo.REASON_OTHER)) {
@@ -280,7 +280,7 @@
 
         // Delete the resources here after sending the broadcast to let
         // other processes clean up before deleting resources.
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             if (info.mArgs != null) {
                 mRemovePackageHelper.cleanUpResources(info.mArgs.getPackageName(),
                         info.mArgs.getCodeFile(), info.mArgs.getInstructionSets());
@@ -435,7 +435,7 @@
     public void executeDeletePackage(DeletePackageAction action, String packageName,
             boolean deleteCodeAndResources, @NonNull int[] allUserHandles, boolean writeSettings)
             throws SystemDeleteException {
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             executeDeletePackageLIF(action, packageName, deleteCodeAndResources, allUserHandles,
                     writeSettings);
         }
@@ -681,7 +681,7 @@
             // Preserve data by setting flag
             flags |= PackageManager.DELETE_KEEP_DATA;
         }
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             deleteInstalledPackageLIF(deletedPs, UserHandle.USER_ALL, true, flags, allUserHandles,
                     outInfo, writeSettings);
         }
diff --git a/services/core/java/com/android/server/pm/FreeStorageHelper.java b/services/core/java/com/android/server/pm/FreeStorageHelper.java
index 66ec80f..6e84a5b 100644
--- a/services/core/java/com/android/server/pm/FreeStorageHelper.java
+++ b/services/core/java/com/android/server/pm/FreeStorageHelper.java
@@ -107,11 +107,9 @@
             }
 
             // 4. Consider cached app data (above quotas)
-            synchronized (mPm.mInstallLock) {
-                try {
-                    mPm.mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
-                } catch (Installer.InstallerException ignored) {
-                }
+            try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
+                mPm.mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
+            } catch (Installer.InstallerException ignored) {
             }
             if (file.getUsableSpace() >= bytes) return;
 
@@ -141,12 +139,10 @@
             }
 
             // 8. Consider cached app data (below quotas)
-            synchronized (mPm.mInstallLock) {
-                try {
-                    mPm.mInstaller.freeCache(volumeUuid, bytes,
-                            Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
-                } catch (Installer.InstallerException ignored) {
-                }
+            try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
+                mPm.mInstaller.freeCache(volumeUuid, bytes,
+                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
+            } catch (Installer.InstallerException ignored) {
             }
             if (file.getUsableSpace() >= bytes) return;
 
@@ -176,11 +172,9 @@
             // 12. Clear temp install session files
             mPm.mInstallerService.freeStageDirs(volumeUuid);
         } else {
-            synchronized (mPm.mInstallLock) {
-                try {
-                    mPm.mInstaller.freeCache(volumeUuid, bytes, 0);
-                } catch (Installer.InstallerException ignored) {
-                }
+            try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
+                mPm.mInstaller.freeCache(volumeUuid, bytes, 0);
+            } catch (Installer.InstallerException ignored) {
             }
         }
         if (file.getUsableSpace() >= bytes) return;
@@ -197,22 +191,20 @@
         final long sizeBytes = PackageManagerServiceUtils.calculateInstalledSize(resolvedPath,
                 mPackageAbiOverride);
         if (sizeBytes >= 0) {
-            synchronized (mPm.mInstallLock) {
-                try {
-                    mPm.mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
-                    PackageInfoLite pkgInfoLite = PackageManagerServiceUtils.getMinimalPackageInfo(
-                            mContext, pkgLite, resolvedPath, installFlags,
-                            mPackageAbiOverride);
-                    // The cache free must have deleted the file we downloaded to install.
-                    if (pkgInfoLite.recommendedInstallLocation
-                            == InstallLocationUtils.RECOMMEND_FAILED_INVALID_URI) {
-                        pkgInfoLite.recommendedInstallLocation =
-                                InstallLocationUtils.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
-                    }
-                    return pkgInfoLite.recommendedInstallLocation;
-                } catch (Installer.InstallerException e) {
-                    Slog.w(TAG, "Failed to free cache", e);
+            try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
+                mPm.mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
+                PackageInfoLite pkgInfoLite = PackageManagerServiceUtils.getMinimalPackageInfo(
+                        mContext, pkgLite, resolvedPath, installFlags,
+                        mPackageAbiOverride);
+                // The cache free must have deleted the file we downloaded to install.
+                if (pkgInfoLite.recommendedInstallLocation
+                        == InstallLocationUtils.RECOMMEND_FAILED_INVALID_URI) {
+                    pkgInfoLite.recommendedInstallLocation =
+                            InstallLocationUtils.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
                 }
+                return pkgInfoLite.recommendedInstallLocation;
+            } catch (Installer.InstallerException e) {
+                Slog.w(TAG, "Failed to free cache", e);
             }
         }
         return recommendedInstallLocation;
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index f987d4a..f05c54d 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -1095,7 +1095,8 @@
             String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
         final int callingUid = Binder.getCallingUid();
         return new ParceledListSlice<>(snapshot().queryIntentServicesInternal(
-                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
+                intent, resolvedType, flags, userId, callingUid, Process.INVALID_PID,
+                /*includeInstantApps*/ false, /*resolveForStart*/ false));
     }
 
     @Override
@@ -1139,7 +1140,7 @@
             @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
         return mResolveIntentHelper.resolveIntentInternal(snapshot(), intent,
                 resolvedType, flags, 0 /*privateResolveFlags*/, userId, false,
-                Binder.getCallingUid());
+                Binder.getCallingUid(), Binder.getCallingPid());
     }
 
     @Override
@@ -1148,7 +1149,8 @@
             @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
         final int callingUid = Binder.getCallingUid();
         return mResolveIntentHelper.resolveServiceInternal(snapshot(), intent,
-                resolvedType, flags, userId, callingUid);
+                resolvedType, flags, userId, callingUid, Process.INVALID_PID,
+                /*resolveForStart*/ false);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 6cfa09f..6eac72d 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -756,7 +756,7 @@
                             Process.INVALID_UID /* previousAppId */,
                             permissionParamsBuilder.build(), userId);
 
-                    synchronized (mPm.mInstallLock) {
+                    try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
                         // We don't need to freeze for a brand new install
                         mAppDataHelper.prepareAppDataPostCommitLIF(
                                 pkgSetting, /* previousAppId= */0, new int[] { userId });
@@ -985,13 +985,11 @@
     }
 
     void installPackagesTraced(List<InstallRequest> requests) {
-        mPm.mInstallLock.lock();
-        try {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
             installPackagesLI(requests);
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-            mPm.mInstallLock.unlock();
         }
     }
 
@@ -2592,7 +2590,8 @@
             if (performDexopt) {
                 // dexopt can take long, and ArtService doesn't require installd, so we release
                 // the lock here and re-acquire the lock after dexopt is finished.
-                mPm.mInstallLock.unlock();
+                PackageManagerTracedLock.RawLock installLock = mPm.mInstallLock.getRawLock();
+                installLock.unlock();
                 try {
                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
 
@@ -2612,7 +2611,7 @@
                     installRequest.onDexoptFinished(dexOptResult);
                     Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                 } finally {
-                    mPm.mInstallLock.lock();
+                    installLock.lock();
                 }
             }
         }
@@ -2921,7 +2920,7 @@
                     // propagated to all application threads.
                     mPm.scheduleDeferredNoKillPostDelete(args);
                     if (Flags.improveInstallDontKill()) {
-                        synchronized (mPm.mInstallLock) {
+                        try (var installLock = mPm.mInstallLock.acquireLock()) {
                             PackageManagerServiceUtils.linkFilesToOldDirs(mPm.mInstaller,
                                     packageName, pkgSetting.getPath(), pkgSetting.getOldPaths());
                         }
@@ -3068,7 +3067,7 @@
             @NonNull PackageSetting stubPkgSetting) {
         final int parseFlags = mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_CHATTY
                 | ParsingPackageUtils.PARSE_ENFORCE_CODE;
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             final AndroidPackage pkg;
             try (PackageFreezer freezer =
                          mPm.freezePackage(stubPkg.getPackageName(), UserHandle.USER_ALL,
@@ -3231,12 +3230,10 @@
         }
         // Install the system package
         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
-        try {
-            synchronized (mPm.mInstallLock) {
-                final int[] origUsers = outInfo == null ? null : outInfo.mOrigUsers;
-                installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles,
-                        origUsers, writeSettings);
-            }
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
+            final int[] origUsers = outInfo == null ? null : outInfo.mOrigUsers;
+            installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles,
+                    origUsers, writeSettings);
         } catch (PackageManagerException e) {
             Slog.w(TAG, "Failed to restore system package:" + deletedPs.getPackageName() + ": "
                     + e.getMessage());
@@ -3466,12 +3463,9 @@
                 if (ps != null) {
                     ps.getPkgState().setUpdatedSystemApp(false);
                 }
-
-                try {
-                    final File codePath = new File(pkg.getPath());
-                    synchronized (mPm.mInstallLock) {
-                        initPackageTracedLI(codePath, 0, scanFlags);
-                    }
+                final File codePath = new File(pkg.getPath());
+                try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
+                    initPackageTracedLI(codePath, 0, scanFlags);
                 } catch (PackageManagerException e) {
                     Slog.e(TAG, "Failed to parse updated, ex-system package: "
                             + e.getMessage());
@@ -3679,14 +3673,12 @@
             }
             mPm.mSettings.enableSystemPackageLPw(packageName);
 
-            try {
-                synchronized (mPm.mInstallLock) {
-                    final AndroidPackage newPkg = initPackageTracedLI(
-                            scanFile, reparseFlags, rescanFlags);
-                    // We rescanned a stub, add it to the list of stubbed system packages
-                    if (newPkg.isStub()) {
-                        stubSystemApps.add(packageName);
-                    }
+            try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
+                final AndroidPackage newPkg = initPackageTracedLI(
+                         scanFile, reparseFlags, rescanFlags);
+                 // We rescanned a stub, add it to the list of stubbed system packages
+                if (newPkg.isStub()) {
+                    stubSystemApps.add(packageName);
                 }
             } catch (PackageManagerException e) {
                 Slog.e(TAG, "Failed to parse original system package: "
diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java
index b06c7cb..d3a18f9 100644
--- a/services/core/java/com/android/server/pm/InstallingSession.java
+++ b/services/core/java/com/android/server/pm/InstallingSession.java
@@ -370,18 +370,16 @@
             Slog.d(TAG, "Moving " + mMoveInfo.mPackageName + " from "
                     + mMoveInfo.mFromUuid + " to " + mMoveInfo.mToUuid);
         }
-        synchronized (mPm.mInstallLock) {
-            try {
-                mPm.mInstaller.moveCompleteApp(mMoveInfo.mFromUuid, mMoveInfo.mToUuid,
-                        mMoveInfo.mPackageName, mMoveInfo.mAppId, mMoveInfo.mSeInfo,
-                        mMoveInfo.mTargetSdkVersion, mMoveInfo.mFromCodePath);
-            } catch (Installer.InstallerException e) {
-                final String errorMessage = "Failed to move app";
-                request.setError(PackageManagerException.ofInternalError(errorMessage,
-                        PackageManagerException.INTERNAL_ERROR_MOVE));
-                Slog.w(TAG, errorMessage, e);
-                return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
-            }
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
+            mPm.mInstaller.moveCompleteApp(mMoveInfo.mFromUuid, mMoveInfo.mToUuid,
+                    mMoveInfo.mPackageName, mMoveInfo.mAppId, mMoveInfo.mSeInfo,
+                    mMoveInfo.mTargetSdkVersion, mMoveInfo.mFromCodePath);
+        } catch (Installer.InstallerException e) {
+            final String errorMessage = "Failed to move app";
+            request.setError(PackageManagerException.ofInternalError(errorMessage,
+                    PackageManagerException.INTERNAL_ERROR_MOVE));
+            Slog.w(TAG, errorMessage, e);
+            return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
         }
 
         final String toPathName = new File(mMoveInfo.mFromCodePath).getName();
diff --git a/services/core/java/com/android/server/pm/MovePackageHelper.java b/services/core/java/com/android/server/pm/MovePackageHelper.java
index f5f55773..f01b508 100644
--- a/services/core/java/com/android/server/pm/MovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/MovePackageHelper.java
@@ -206,7 +206,7 @@
         }
 
         final PackageStats stats = new PackageStats(null, -1);
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             for (int userId : installedUserIds) {
                 if (!getPackageSizeInfoLI(packageName, userId, stats)) {
                     freezer.close();
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 85aee86..c10dfcb 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -34,6 +34,7 @@
 per-file PackageKeySetData.java = [email protected], [email protected]
 per-file PackageSignatures.java = [email protected], [email protected]
 per-file SELinuxMMAC* = [email protected], [email protected], [email protected]
+per-file SaferIntentUtils.java = [email protected]
 
 # shortcuts
 per-file LauncherAppsService.java = [email protected], [email protected], [email protected], [email protected], [email protected]
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 5b326fd..087b17a 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -506,8 +506,8 @@
 
     private static class OTADexoptPackageDexOptimizer extends
             PackageDexOptimizer.ForcedUpdatePackageDexOptimizer {
-        public OTADexoptPackageDexOptimizer(Installer installer, Object installLock,
-                Context context) {
+        OTADexoptPackageDexOptimizer(Installer installer,
+                PackageManagerTracedLock installLock, Context context) {
             super(installer, installLock, context, "*otadexopt*");
         }
     }
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 396fa22..72bacfd 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -123,7 +123,7 @@
     // One minute over PM WATCHDOG_TIMEOUT
     private static final long WAKELOCK_TIMEOUT_MS = WATCHDOG_TIMEOUT + 1000 * 60;
 
-    private final Object mInstallLock;
+    private final PackageManagerTracedLock mInstallLock;
 
     /**
      * This should be accessed only through {@link #getInstallerLI()} with
@@ -142,7 +142,7 @@
     private final Context mContext;
     private static final Random sRandom = new Random();
 
-    PackageDexOptimizer(Installer installer, Object installLock, Context context,
+    PackageDexOptimizer(Installer installer, PackageManagerTracedLock installLock, Context context,
             String wakeLockTag) {
         this(new Injector() {
             @Override
@@ -167,8 +167,8 @@
     }
 
     @VisibleForTesting
-    PackageDexOptimizer(@NonNull Injector injector, Installer installer, Object installLock,
-            Context context, String wakeLockTag) {
+    PackageDexOptimizer(@NonNull Injector injector, Installer installer,
+            PackageManagerTracedLock installLock, Context context, String wakeLockTag) {
         this.mContext = context;
         this.mInstaller = installer;
         this.mInstallLock = installLock;
@@ -231,7 +231,7 @@
         if (!canOptimizePackage(pkg)) {
             return DEX_OPT_SKIPPED;
         }
-        synchronized (mInstallLock) {
+        try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
             final long acquireTime = acquireWakeLockLI(pkg.getUid());
             try {
                 return performDexOptLI(pkg, pkgSetting, instructionSets,
@@ -868,8 +868,8 @@
      */
     public static class ForcedUpdatePackageDexOptimizer extends PackageDexOptimizer {
 
-        public ForcedUpdatePackageDexOptimizer(Installer installer, Object installLock,
-                Context context, String wakeLockTag) {
+        public ForcedUpdatePackageDexOptimizer(Installer installer,
+                PackageManagerTracedLock installLock, Context context, String wakeLockTag) {
             super(installer, installLock, context, wakeLockTag);
         }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
index d2b60a4..ed568b8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
+++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
@@ -327,11 +327,11 @@
 
     @Override
     @Deprecated
-    public final List<ResolveInfo> queryIntentReceivers(Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
-            int filterCallingUid, int userId, boolean forSend) {
+    public final List<ResolveInfo> queryIntentReceivers(
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
+            int filterCallingUid, int callingPid, int userId, boolean forSend) {
         return getResolveIntentHelper().queryIntentReceiversInternal(snapshot(), intent,
-                resolvedType, flags, userId, filterCallingUid, forSend);
+                resolvedType, flags, userId, filterCallingUid, callingPid, forSend);
     }
 
     @Override
@@ -341,7 +341,7 @@
             int userId) {
         final String resolvedType = intent.resolveTypeIfNeeded(getContext().getContentResolver());
         return snapshot().queryIntentServicesInternal(intent, resolvedType, flags, userId,
-                callingUid, false);
+                callingUid, Process.INVALID_PID, false, /*resolveForStart*/ false);
     }
 
     @Override
@@ -472,24 +472,10 @@
     public final ResolveInfo resolveIntent(Intent intent, String resolvedType,
             @PackageManager.ResolveInfoFlagsBits long flags,
             @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
-            boolean resolveForStart, int filterCallingUid) {
-        return getResolveIntentHelper().resolveIntentInternal(snapshot(),
-                intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
-                filterCallingUid);
-    }
-
-    /**
-     * @deprecated similar to {@link resolveIntent} but limits the matches to exported components.
-     */
-    @Override
-    @Deprecated
-    public final ResolveInfo resolveIntentExported(Intent intent, String resolvedType,
-            @PackageManager.ResolveInfoFlagsBits long flags,
-            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
             boolean resolveForStart, int filterCallingUid, int callingPid) {
         return getResolveIntentHelper().resolveIntentInternal(snapshot(),
                 intent, resolvedType, flags, privateResolveFlags, userId, resolveForStart,
-                filterCallingUid, true, callingPid);
+                filterCallingUid, callingPid);
     }
 
     @Override
@@ -497,7 +483,18 @@
     public final ResolveInfo resolveService(Intent intent, String resolvedType,
             @PackageManager.ResolveInfoFlagsBits long flags, int userId, int callingUid) {
         return getResolveIntentHelper().resolveServiceInternal(snapshot(), intent,
-                resolvedType, flags, userId, callingUid);
+                resolvedType, flags, userId, callingUid, Process.INVALID_PID,
+                /*resolveForStart*/ false);
+    }
+
+    @Override
+    @Deprecated
+    public final ResolveInfo resolveService(
+            Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlagsBits long flags, int userId,
+            int callingUid, int callingPid) {
+        return getResolveIntentHelper().resolveServiceInternal(snapshot(), intent,
+                resolvedType, flags, userId, callingUid, callingPid, /*resolveForStart*/ true);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 679ab65..2b0e62c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1630,16 +1630,17 @@
 
     private boolean tryUnderLock(boolean sync, long timeoutMs, Runnable runnable) {
         try {
+            PackageManagerTracedLock.RawLock lock = mLock.getRawLock();
             if (sync) {
-                mLock.lock();
-            } else if (!mLock.tryLock(timeoutMs, TimeUnit.MILLISECONDS)) {
+                lock.lock();
+            } else if (!lock.tryLock(timeoutMs, TimeUnit.MILLISECONDS)) {
                 return false;
             }
             try {
                 runnable.run();
                 return true;
             } finally {
-                mLock.unlock();
+                lock.unlock();
             }
         } catch (InterruptedException e) {
             Slog.e(TAG, "Failed to obtain mLock", e);
@@ -1723,7 +1724,7 @@
                 (i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),
                         i.getContext(), "*dexopt*"),
                 (i, pm) -> new DexManager(i.getContext(), i.getPackageDexOptimizer(),
-                        i.getInstaller(), i.getInstallLock(), i.getDynamicCodeLogger()),
+                        i.getDynamicCodeLogger()),
                 (i, pm) -> new DynamicCodeLogger(i.getInstaller()),
                 (i, pm) -> new ArtManagerService(i.getContext(), i.getInstaller(),
                         i.getInstallLock()),
@@ -2139,8 +2140,7 @@
         mPreferredActivityHelper = new PreferredActivityHelper(this, mBroadcastHelper);
         mResolveIntentHelper = new ResolveIntentHelper(mContext, mPreferredActivityHelper,
                 injector.getCompatibility(), mUserManager, mDomainVerificationManager,
-                mUserNeedsBadging, () -> mResolveInfo, () -> mInstantAppInstallerActivity,
-                injector.getBackgroundHandler());
+                mUserNeedsBadging, () -> mResolveInfo, () -> mInstantAppInstallerActivity);
         mDexOptHelper = new DexOptHelper(this);
         mSuspendPackageHelper = new SuspendPackageHelper(this, mInjector, mBroadcastHelper,
                 mProtectedPackages);
@@ -2161,7 +2161,7 @@
 
         Computer computer = mLiveComputer;
         // CHECKSTYLE:OFF IndentationCheck
-        synchronized (mInstallLock) {
+        try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
         // writer
         synchronized (mLock) {
             mHandler = injector.getHandler();
@@ -2695,7 +2695,8 @@
 
         final ResolveInfo resolveInfo = mResolveIntentHelper.resolveIntentInternal(computer, intent,
                 null, MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
-                0 /*privateResolveFlags*/, UserHandle.USER_SYSTEM, false, Binder.getCallingUid());
+                0 /*privateResolveFlags*/, UserHandle.USER_SYSTEM, false,
+                Binder.getCallingUid(), Binder.getCallingPid());
         if (resolveInfo == null ||
                 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
             throw new RuntimeException("There must be exactly one uninstaller; found "
@@ -2810,7 +2811,8 @@
                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
         final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE);
         List<ResolveInfo> resolvers = snapshot.queryIntentServicesInternal(resolverIntent, null,
-                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
+                resolveFlags, UserHandle.USER_SYSTEM, callingUid, Process.INVALID_PID,
+                /*includeInstantApps*/ false, /*resolveForStart*/ false);
         final int N = resolvers.size();
         if (N == 0) {
             if (DEBUG_INSTANT) {
@@ -2924,17 +2926,14 @@
      * Blocking call to clear all cached app data above quota.
      */
     public void freeAllAppCacheAboveQuota(String volumeUuid) throws IOException {
-        synchronized (mInstallLock) {
+        try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
             // To avoid refactoring Installer.freeCache() and InstalldNativeService.freeCache(),
             // Long.MAX_VALUE is passed as an argument which is used in neither of two methods
             // when FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES is set
-            try {
-                mInstaller.freeCache(volumeUuid, Long.MAX_VALUE, Installer.FLAG_FREE_CACHE_V2
-                        | Installer.FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES);
-            } catch (InstallerException ignored) {
-            }
+            mInstaller.freeCache(volumeUuid, Long.MAX_VALUE, Installer.FLAG_FREE_CACHE_V2
+                    | Installer.FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES);
+        } catch (InstallerException ignored) {
         }
-        return;
     }
 
     /**
@@ -3671,7 +3670,9 @@
                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                 UserHandle.USER_SYSTEM,
                 /* callingUid= */ Process.myUid(),
-                /* includeInstantApps= */ false);
+                Process.INVALID_PID,
+                /* includeInstantApps= */ false,
+                /* resolveForStart */ false);
         if (matches.size() == 1) {
             return matches.get(0).getComponentInfo().packageName;
         } else {
@@ -4425,7 +4426,7 @@
      */
     void createNewUser(int userId, @Nullable Set<String> userTypeInstallablePackages,
             String[] disallowedPackages) {
-        synchronized (mInstallLock) {
+        try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
             mSettings.createNewUserLI(this, mInstaller, userId,
                     userTypeInstallablePackages, disallowedPackages);
         }
@@ -4751,7 +4752,7 @@
                             freezePackage(packageName, UserHandle.USER_ALL,
                                     "clearApplicationProfileData",
                                     ApplicationExitInfo.REASON_OTHER, null /* request */)) {
-                synchronized (mInstallLock) {
+                try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
                     mAppDataHelper.clearAppProfilesLIF(pkg);
                 }
             }
@@ -4797,7 +4798,7 @@
                     try (PackageFreezer freezer = freezePackage(packageName, UserHandle.USER_ALL,
                             "clearApplicationUserData",
                             ApplicationExitInfo.REASON_USER_REQUESTED, null /* request */)) {
-                        synchronized (mInstallLock) {
+                        try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
                             succeeded = clearApplicationUserDataLIF(snapshotComputer(), packageName,
                                     userId);
                         }
@@ -4940,7 +4941,7 @@
                             || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
                 }
                 if (doClearData) {
-                    synchronized (mInstallLock) {
+                    try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
                         final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
                         // Snapshot again after mInstallLock?
                         final AndroidPackage pkg = snapshotComputer().getPackage(packageName);
@@ -8055,16 +8056,14 @@
     public void reconcileSdkData(@Nullable String volumeUuid, @NonNull String packageName,
             @NonNull List<String> subDirNames, int userId, int appId, int previousAppId,
             @NonNull String seInfo, int flags) throws IOException {
-        synchronized (mInstallLock) {
-            ReconcileSdkDataArgs args = mInstaller.buildReconcileSdkDataArgs(volumeUuid,
-                    packageName, subDirNames, userId, appId, seInfo,
-                    flags);
-            args.previousAppId = previousAppId;
-            try {
-                mInstaller.reconcileSdkData(args);
-            } catch (InstallerException e) {
-                throw new IOException(e.getMessage());
-            }
+        ReconcileSdkDataArgs args = mInstaller.buildReconcileSdkDataArgs(volumeUuid,
+                packageName, subDirNames, userId, appId, seInfo,
+                flags);
+        args.previousAppId = previousAppId;
+        try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
+            mInstaller.reconcileSdkData(args);
+        } catch (InstallerException e) {
+            throw new IOException(e.getMessage());
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 6700f00..ff8abf8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -26,14 +26,11 @@
 
 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
-import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH;
-import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH;
 import static com.android.server.LocalManagerRegistry.ManagerNotFoundException;
 import static com.android.server.pm.PackageInstallerSession.APP_METADATA_FILE_ACCESS_MODE;
 import static com.android.server.pm.PackageInstallerSession.getAppMetadataSizeLimit;
 import static com.android.server.pm.PackageManagerService.COMPRESSED_EXTENSION;
 import static com.android.server.pm.PackageManagerService.DEBUG_COMPRESSION;
-import static com.android.server.pm.PackageManagerService.DEBUG_INTENT_MATCHING;
 import static com.android.server.pm.PackageManagerService.DEBUG_PREFERRED;
 import static com.android.server.pm.PackageManagerService.DEFAULT_FILE_ACCESS_MODE;
 import static com.android.server.pm.PackageManagerService.DEFAULT_NATIVE_LIBRARY_FILE_ACCESS_MODE;
@@ -48,23 +45,15 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.app.ActivityManager;
-import android.compat.annotation.ChangeId;
-import android.compat.annotation.Disabled;
-import android.compat.annotation.Overridable;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.ComponentInfo;
 import android.content.pm.PackageInfoLite;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.Property;
 import android.content.pm.PackagePartitions;
 import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
 import android.content.pm.Signature;
 import android.content.pm.SigningDetails;
 import android.content.pm.parsing.ApkLiteParseUtils;
@@ -83,7 +72,6 @@
 import android.os.Process;
 import android.os.SELinux;
 import android.os.SystemProperties;
-import android.os.UserHandle;
 import android.os.incremental.IncrementalManager;
 import android.os.incremental.IncrementalStorage;
 import android.os.incremental.V4Signature;
@@ -99,29 +87,21 @@
 import android.util.Base64;
 import android.util.DisplayMetrics;
 import android.util.Log;
-import android.util.LogPrinter;
-import android.util.Printer;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.content.InstallLocationUtils;
 import com.android.internal.content.NativeLibraryHelper;
-import com.android.internal.pm.pkg.component.ParsedMainComponent;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.HexDump;
 import com.android.server.EventLogTags;
-import com.android.server.IntentResolver;
 import com.android.server.LocalManagerRegistry;
 import com.android.server.Watchdog;
-import com.android.server.am.ActivityManagerUtils;
-import com.android.server.compat.PlatformCompat;
 import com.android.server.pm.dex.PackageDexUsage;
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.AndroidPackageSplit;
 import com.android.server.pm.pkg.PackageStateInternal;
-import com.android.server.pm.resolution.ComponentResolverApi;
-import com.android.server.pm.snapshot.PackageDataSnapshot;
 import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
 
 import dalvik.system.VMRuntime;
@@ -173,11 +153,6 @@
     public static final Predicate<PackageStateInternal> REMOVE_IF_NULL_PKG =
             pkgSetting -> pkgSetting.getPkg() == null;
 
-    // This is a horrible hack to workaround b/240373119, specifically for fixing the T branch.
-    // A proper fix should be implemented in master instead.
-    public static final ThreadLocal<Boolean> DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS =
-            ThreadLocal.withInitial(() -> false);
-
     /**
      * Type used with {@link #canJoinSharedUserId(String, SigningDetails, SharedUserSetting, int)}
      * when the package attempting to join the sharedUserId is a new install.
@@ -202,22 +177,6 @@
     public @interface SharedUserIdJoinType {}
 
     /**
-     * Intents sent from apps targeting Android V and above will stop resolving to components with
-     * non matching intent filters, even when explicitly setting a component name, unless the
-     * target components are in the same app as the calling app.
-     *
-     * When an app registers an exported component in its manifest and adds an <intent-filter>,
-     * the component can be started by any intent - even those that do not match the intent filter.
-     * This has proven to be something that many developers find counterintuitive.
-     * Without checking the intent when the component is started, in some circumstances this can
-     * allow 3P apps to trigger internal-only functionality.
-     */
-    @Overridable
-    @ChangeId
-    @Disabled
-    private static final long ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS = 161252188;
-
-    /**
      * The initial enabled state of the cache before other checks are done.
      */
     private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
@@ -1204,166 +1163,6 @@
         return (ps.getFlags() & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
     }
 
-    private static ParsedMainComponent componentInfoToComponent(
-            ComponentInfo info, ComponentResolverApi resolver, boolean isReceiver) {
-        if (info instanceof ActivityInfo) {
-            if (isReceiver) {
-                return resolver.getReceiver(info.getComponentName());
-            } else {
-                return resolver.getActivity(info.getComponentName());
-            }
-        } else if (info instanceof ServiceInfo) {
-            return resolver.getService(info.getComponentName());
-        } else {
-            // This shall never happen
-            throw new IllegalArgumentException("Unsupported component type");
-        }
-    }
-
-    /**
-     * Under the correct conditions, remove components if the intent has null action.
-     *
-     * `compat` and `snapshot` may be null when this method is called in ActivityManagerService
-     * CTS tests. The code in this method will properly avoid control flows using these arguments.
-     */
-    public static void applyNullActionBlocking(
-            @Nullable PlatformCompat compat, @Nullable PackageDataSnapshot snapshot,
-            List componentList, boolean isReceiver, Intent intent, int filterCallingUid) {
-        if (ActivityManager.canAccessUnexportedComponents(filterCallingUid)) return;
-
-        final Computer computer = (Computer) snapshot;
-        ComponentResolverApi resolver = null;
-
-        final boolean enforce = android.security.Flags.blockNullActionIntents()
-                && (compat == null || compat.isChangeEnabledByUidInternal(
-                        IntentFilter.BLOCK_NULL_ACTION_INTENTS, filterCallingUid));
-
-        for (int i = componentList.size() - 1; i >= 0; --i) {
-            boolean match = true;
-
-            Object c = componentList.get(i);
-            if (c instanceof ResolveInfo resolveInfo) {
-                if (computer == null) {
-                    // PackageManagerService is not started
-                    return;
-                }
-                if (resolver == null) {
-                    resolver = computer.getComponentResolver();
-                }
-                final ParsedMainComponent comp = componentInfoToComponent(
-                        resolveInfo.getComponentInfo(), resolver, isReceiver);
-                if (comp != null && !comp.getIntents().isEmpty() && intent.getAction() == null) {
-                    match = false;
-                }
-            } else if (c instanceof IntentFilter) {
-                if (intent.getAction() == null) {
-                    match = false;
-                }
-            }
-
-            if (!match) {
-                ActivityManagerUtils.logUnsafeIntentEvent(
-                        UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH,
-                        filterCallingUid, intent, null, enforce);
-                if (enforce) {
-                    Slog.w(TAG, "Blocking intent with null action: " + intent);
-                    componentList.remove(i);
-                }
-            }
-        }
-    }
-
-    public static void applyEnforceIntentFilterMatching(
-            PlatformCompat compat, PackageDataSnapshot snapshot,
-            List<ResolveInfo> resolveInfos, boolean isReceiver,
-            Intent intent, String resolvedType, int filterCallingUid) {
-        if (DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.get()) return;
-
-        // Do not enforce filter matching when the caller is system or root
-        if (ActivityManager.canAccessUnexportedComponents(filterCallingUid)) return;
-
-        final Computer computer = (Computer) snapshot;
-        final ComponentResolverApi resolver = computer.getComponentResolver();
-
-        final Printer logPrinter = DEBUG_INTENT_MATCHING
-                ? new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM)
-                : null;
-
-        final boolean enforceMatch = android.security.Flags.enforceIntentFilterMatch()
-                && compat.isChangeEnabledByUidInternal(
-                        ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS, filterCallingUid);
-        final boolean blockNullAction = android.security.Flags.blockNullActionIntents()
-                && compat.isChangeEnabledByUidInternal(
-                        IntentFilter.BLOCK_NULL_ACTION_INTENTS, filterCallingUid);
-
-        for (int i = resolveInfos.size() - 1; i >= 0; --i) {
-            final ComponentInfo info = resolveInfos.get(i).getComponentInfo();
-
-            // Skip filter matching when the caller is targeting the same app
-            if (UserHandle.isSameApp(filterCallingUid, info.applicationInfo.uid)) {
-                continue;
-            }
-
-            final ParsedMainComponent comp = componentInfoToComponent(info, resolver, isReceiver);
-
-            if (comp == null || comp.getIntents().isEmpty()) {
-                continue;
-            }
-
-            Boolean match = null;
-
-            if (intent.getAction() == null) {
-                ActivityManagerUtils.logUnsafeIntentEvent(
-                        UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH,
-                        filterCallingUid, intent, resolvedType, enforceMatch && blockNullAction);
-                if (blockNullAction) {
-                    // Skip intent filter matching if blocking null action
-                    match = false;
-                }
-            }
-
-            if (match == null) {
-                // Check if any intent filter matches
-                for (int j = 0, size = comp.getIntents().size(); j < size; ++j) {
-                    IntentFilter intentFilter = comp.getIntents().get(j).getIntentFilter();
-                    if (IntentResolver.intentMatchesFilter(intentFilter, intent, resolvedType)) {
-                        match = true;
-                        break;
-                    }
-                }
-            }
-
-            // At this point, the value `match` has the following states:
-            // null : Intent does not match any intent filter
-            // false: Null action intent detected AND blockNullAction == true
-            // true : The intent matches at least one intent filter
-
-            if (match == null) {
-                ActivityManagerUtils.logUnsafeIntentEvent(
-                        UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH,
-                        filterCallingUid, intent, resolvedType, enforceMatch);
-                match = false;
-            }
-
-            if (!match) {
-                // All non-matching intents has to be marked accordingly
-                if (android.security.Flags.enforceIntentFilterMatch()) {
-                    intent.addExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
-                }
-                if (enforceMatch) {
-                    Slog.w(TAG, "Intent does not match component's intent filter: " + intent);
-                    Slog.w(TAG, "Access blocked: " + comp.getComponentName());
-                    if (DEBUG_INTENT_MATCHING) {
-                        Slog.v(TAG, "Component intent filters:");
-                        comp.getIntents().forEach(f -> f.getIntentFilter().dump(logPrinter, "  "));
-                        Slog.v(TAG, "-----------------------------");
-                    }
-                    resolveInfos.remove(i);
-                }
-            }
-        }
-    }
-
     /**
      * Do NOT use for intent resolution filtering. That should be done with
      * {@link DomainVerificationManagerInternal#filterToApprovedApp(Intent, List, int, Function)}.
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index c40563f..0410764 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -330,6 +330,8 @@
                     return runGetOemPermissions();
                 case "get-signature-permission-allowlist":
                     return runGetSignaturePermissionAllowlist();
+                case "get-shared-uid-allowlist":
+                    return runGetSharedUidAllowlist();
                 case "trim-caches":
                     return runTrimCaches();
                 case "create-user":
@@ -2970,6 +2972,20 @@
         return 0;
     }
 
+    private int runGetSharedUidAllowlist() {
+        final var allowlist = SystemConfig.getInstance().getPackageToSharedUidAllowList();
+        final var pw = getOutPrintWriter();
+        final var allowlistSize = allowlist.size();
+        for (var allowlistIndex = 0; allowlistIndex < allowlistSize; allowlistIndex++) {
+            final var packageName = allowlist.keyAt(allowlistIndex);
+            final var sharedUserName = allowlist.valueAt(allowlistIndex);
+            pw.print(packageName);
+            pw.print(" ");
+            pw.println(sharedUserName);
+        }
+        return 0;
+    }
+
     private int runTrimCaches() throws RemoteException {
         String size = getNextArg();
         if (size == null) {
@@ -4909,6 +4925,9 @@
         pw.println("    Prints the signature permission allowlist for a partition.");
         pw.println("    PARTITION is one of system, vendor, product and system-ext");
         pw.println("");
+        pw.println("  get-shared-uid-allowlist");
+        pw.println("    Prints the shared UID allowlist.");
+        pw.println("");
         pw.println("  trim-caches DESIRED_FREE_SPACE [internal|UUID]");
         pw.println("    Trim cache files to reach the given free space.");
         pw.println("");
diff --git a/services/core/java/com/android/server/pm/PackageManagerTracedLock.java b/services/core/java/com/android/server/pm/PackageManagerTracedLock.java
index 303b8b9..d9604b3c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerTracedLock.java
+++ b/services/core/java/com/android/server/pm/PackageManagerTracedLock.java
@@ -16,6 +16,7 @@
 
 package com.android.server.pm;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.util.Slog;
 
@@ -25,32 +26,77 @@
  * This is a unique class that is used as the PackageManager lock.  It can be targeted for lock
  * injection, similar to {@link ActivityManagerGlobalLock}.
  */
-public class PackageManagerTracedLock extends ReentrantLock {
+public class PackageManagerTracedLock implements AutoCloseable {
     private static final String TAG = "PackageManagerTracedLock";
     private static final boolean DEBUG = false;
-    @Nullable private final String mLockName;
+    private @NonNull final RawLock mLock;
 
     public PackageManagerTracedLock(@Nullable String lockName) {
-        mLockName = lockName;
+        mLock = new RawLock(lockName);
     }
 
     public PackageManagerTracedLock() {
         this(null);
     }
 
-    @Override
-    public void lock() {
-        super.lock();
-        if (DEBUG && mLockName != null) {
-            Slog.i(TAG, "locked " + mLockName);
-        }
+    /**
+     * Use this method to acquire the lock. Use it with try-with-resources to make sure the lock is
+     * released afterwards. Example usage:
+     * <pre>
+     * PackageManagerTracedLock myInstallLock = new PackageManagerTracedLock();
+     * try (PackageManagerTracedLock installLock = myInstallLock.acquireLock()) {
+     *     // do stuff under lock
+     * }
+     * </pre>
+     */
+    public PackageManagerTracedLock acquireLock() {
+        mLock.lock();
+        return this;
     }
 
+    /**
+     * Obtain the raw lock for fine control of lock state. Example usage:
+     * <pre>
+     * PackageManagerTracedLock myInstallLock = new PackageManagerTracedLock();
+     * PackageManagerTracedLock.RawLock rawLock = myInstallLock.getRawLock();
+     * rawLock.lock();
+     * // do stuff under lock
+     * rawLock.unlock();
+     * </pre>
+     */
+    public RawLock getRawLock() {
+        return mLock;
+    }
+
+    /**
+     * Release the lock if it's held by the current thread.
+     * If you use {@link #acquireLock()} using try-with-resources, there's no need to call this
+     * method explicitly.
+     */
     @Override
-    public void unlock() {
-        super.unlock();
-        if (DEBUG && mLockName != null) {
-            Slog.i(TAG, "unlocked " + mLockName);
+    public void close() {
+        mLock.unlock();
+    }
+
+    public static class RawLock extends ReentrantLock {
+        @Nullable private final String mLockName;
+        RawLock(@Nullable String lockName) {
+            mLockName = lockName;
+        }
+        @Override
+        public void lock() {
+            super.lock();
+            if (DEBUG && mLockName != null) {
+                Slog.i(TAG, "locked " + mLockName);
+            }
+        }
+
+        @Override
+        public void unlock() {
+            super.unlock();
+            if (DEBUG && mLockName != null) {
+                Slog.i(TAG, "unlocked " + mLockName);
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 02bd3cc..2f2c451 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -83,7 +83,7 @@
     }
 
     public void removeCodePath(File codePath) {
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             removeCodePathLI(codePath);
         }
     }
@@ -133,7 +133,7 @@
 
     // Used for system apps only
     public void removePackage(AndroidPackage pkg, boolean chatty) {
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             removePackageLI(pkg, chatty);
         }
     }
@@ -356,7 +356,7 @@
 
     // Called to clean up disabled system packages
     public void removePackageData(final PackageSetting deletedPs, @NonNull int[] allUserHandles) {
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             removePackageDataLIF(deletedPs, UserHandle.USER_ALL, allUserHandles,
                     new PackageRemovedInfo(), /* flags= */ 0, /* writeSettings= */ false);
         }
@@ -488,7 +488,7 @@
 
     void cleanUpResources(@Nullable String packageName, @Nullable File codeFile,
                           @Nullable String[] instructionSets) {
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             cleanUpResourcesLI(codeFile, instructionSets);
         }
         if (packageName == null) {
@@ -528,7 +528,7 @@
         final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), toPathName);
         Slog.d(TAG, "Cleaning up " + packageName + " on " + volumeUuid);
         final int[] userIds = mPm.mUserManager.getUserIds();
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             // Clean up both app data and code
             // All package moves are frozen until finished
 
diff --git a/services/core/java/com/android/server/pm/ResolveIntentHelper.java b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
index 309a448..69490a8 100644
--- a/services/core/java/com/android/server/pm/ResolveIntentHelper.java
+++ b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
@@ -18,7 +18,6 @@
 
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
 
-import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH;
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTANT;
 import static com.android.server.pm.PackageManagerService.DEBUG_INTENT_MATCHING;
 import static com.android.server.pm.PackageManagerService.TAG;
@@ -26,8 +25,6 @@
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
-import android.app.ActivityManagerInternal;
-import android.app.IUnsafeIntentStrictModeCallback;
 import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -45,7 +42,6 @@
 import android.content.pm.ResolveInfo;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.Trace;
@@ -56,9 +52,6 @@
 
 import com.android.internal.app.ResolverActivity;
 import com.android.internal.util.ArrayUtils;
-import com.android.server.LocalServices;
-import com.android.server.am.ActivityManagerService;
-import com.android.server.am.ActivityManagerUtils;
 import com.android.server.compat.PlatformCompat;
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageStateInternal;
@@ -89,8 +82,6 @@
     private final Supplier<ResolveInfo> mResolveInfoSupplier;
     @NonNull
     private final Supplier<ActivityInfo> mInstantAppInstallerActivitySupplier;
-    @NonNull
-    private final Handler mHandler;
 
     ResolveIntentHelper(@NonNull Context context,
             @NonNull PreferredActivityHelper preferredActivityHelper,
@@ -98,8 +89,7 @@
             @NonNull DomainVerificationManagerInternal domainVerificationManager,
             @NonNull UserNeedsBadgingCache userNeedsBadgingCache,
             @NonNull Supplier<ResolveInfo> resolveInfoSupplier,
-            @NonNull Supplier<ActivityInfo> instantAppInstallerActivitySupplier,
-            @NonNull Handler handler) {
+            @NonNull Supplier<ActivityInfo> instantAppInstallerActivitySupplier) {
         mContext = context;
         mPreferredActivityHelper = preferredActivityHelper;
         mPlatformCompat = platformCompat;
@@ -108,47 +98,6 @@
         mUserNeedsBadging = userNeedsBadgingCache;
         mResolveInfoSupplier = resolveInfoSupplier;
         mInstantAppInstallerActivitySupplier = instantAppInstallerActivitySupplier;
-        mHandler = handler;
-    }
-
-    private static void filterNonExportedComponents(Intent intent, int filterCallingUid,
-            int callingPid, List<ResolveInfo> query, PlatformCompat platformCompat,
-            String resolvedType, Computer computer, Handler handler) {
-        if (query == null
-                || intent.getPackage() != null
-                || intent.getComponent() != null
-                || ActivityManager.canAccessUnexportedComponents(filterCallingUid)) {
-            return;
-        }
-        AndroidPackage caller = computer.getPackage(filterCallingUid);
-        String callerPackage = caller == null ? "Not specified" : caller.getPackageName();
-        ActivityManagerInternal activityManagerInternal = LocalServices
-                .getService(ActivityManagerInternal.class);
-        final IUnsafeIntentStrictModeCallback callback = activityManagerInternal
-                .getRegisteredStrictModeCallback(callingPid);
-        for (int i = query.size() - 1; i >= 0; i--) {
-            if (!query.get(i).getComponentInfo().exported) {
-                boolean hasToBeExportedToMatch = platformCompat.isChangeEnabledByUid(
-                        ActivityManagerService.IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS,
-                        filterCallingUid);
-                ActivityManagerUtils.logUnsafeIntentEvent(
-                        UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH,
-                        filterCallingUid, intent, resolvedType, hasToBeExportedToMatch);
-                if (callback != null) {
-                    handler.post(() -> {
-                        try {
-                            callback.onImplicitIntentMatchedInternalComponent(intent.cloneFilter());
-                        } catch (RemoteException e) {
-                            activityManagerInternal.unregisterStrictModeCallback(callingPid);
-                        }
-                    });
-                }
-                if (!hasToBeExportedToMatch) {
-                    return;
-                }
-                query.remove(i);
-            }
-        }
     }
 
     /**
@@ -159,22 +108,7 @@
     public ResolveInfo resolveIntentInternal(Computer computer, Intent intent, String resolvedType,
             @PackageManager.ResolveInfoFlagsBits long flags,
             @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
-            boolean resolveForStart, int filterCallingUid) {
-        return resolveIntentInternal(computer, intent, resolvedType, flags,
-                privateResolveFlags, userId, resolveForStart, filterCallingUid, false, 0);
-    }
-
-    /**
-     * Normally instant apps can only be resolved when they're visible to the caller.
-     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
-     * since we need to allow the system to start any installed application.
-     * Allows picking exported components only.
-     */
-    public ResolveInfo resolveIntentInternal(Computer computer, Intent intent, String resolvedType,
-            @PackageManager.ResolveInfoFlagsBits long flags,
-            @PackageManagerInternal.PrivateResolveFlags long privateResolveFlags, int userId,
-            boolean resolveForStart, int filterCallingUid, boolean exportedComponentsOnly,
-            int callingPid) {
+            boolean resolveForStart, int filterCallingUid, int callingPid) {
         try {
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
 
@@ -188,14 +122,15 @@
 
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
             final List<ResolveInfo> query = computer.queryIntentActivitiesInternal(intent,
-                    resolvedType, flags, privateResolveFlags, filterCallingUid, userId,
-                    resolveForStart, true /*allowDynamicSplits*/);
-            if (exportedComponentsOnly) {
-                filterNonExportedComponents(intent, filterCallingUid, callingPid, query,
-                        mPlatformCompat, resolvedType, computer, mHandler);
-            }
+                    resolvedType, flags, privateResolveFlags, filterCallingUid, callingPid,
+                    userId, resolveForStart, /*allowDynamicSplits*/ true);
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
+            var args = new SaferIntentUtils.IntentArgs(intent, resolvedType,
+                    false /* isReceiver */, resolveForStart, filterCallingUid, callingPid);
+            args.platformCompat = mPlatformCompat;
+            SaferIntentUtils.filterNonExportedComponents(args, query);
+
             final boolean queryMayBeFiltered =
                     UserHandle.getAppId(filterCallingUid) >= Process.FIRST_APPLICATION_UID
                             && !resolveForStart;
@@ -331,6 +266,7 @@
             throws RemoteException {
         Objects.requireNonNull(packageName);
         final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
         computer.enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
                 false /* checkShell */, "get launch intent sender for package");
         final int packageUid = computer.getPackageUid(callingPackage, 0 /* flags */, userId);
@@ -346,17 +282,17 @@
         intentToResolve.setPackage(packageName);
         final ContentResolver contentResolver = mContext.getContentResolver();
         String resolvedType = intentToResolve.resolveTypeIfNeeded(contentResolver);
-        List<ResolveInfo> ris = computer.queryIntentActivitiesInternal(intentToResolve, resolvedType,
-                0 /* flags */, 0 /* privateResolveFlags */, callingUid, userId,
-                true /* resolveForStart */, false /* allowDynamicSplits */);
+        List<ResolveInfo> ris = computer.queryIntentActivitiesInternal(intentToResolve,
+                resolvedType, 0 /* flags */, 0 /* privateResolveFlags */, callingUid, callingPid,
+                userId,  /* resolveForStart */ true,  /* allowDynamicSplits */false);
         if (ris == null || ris.size() <= 0) {
             intentToResolve.removeCategory(Intent.CATEGORY_INFO);
             intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
             intentToResolve.setPackage(packageName);
             resolvedType = intentToResolve.resolveTypeIfNeeded(contentResolver);
             ris = computer.queryIntentActivitiesInternal(intentToResolve, resolvedType,
-                    0 /* flags */, 0 /* privateResolveFlags */, callingUid, userId,
-                    true /* resolveForStart */, false /* allowDynamicSplits */);
+                    0 /* flags */, 0 /* privateResolveFlags */, callingUid, callingPid,
+                    userId,  /* resolveForStart */ true,  /* allowDynamicSplits */false);
         }
 
         final Intent intent = new Intent(intentToResolve);
@@ -390,16 +326,17 @@
             String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId,
             int queryingUid) {
         return queryIntentReceiversInternal(computer, intent, resolvedType, flags, userId,
-                queryingUid, false);
+                queryingUid, Process.INVALID_PID, false);
     }
 
     /**
-     * @see PackageManagerInternal#queryIntentReceivers(Intent, String, long, int, int, boolean)
+     * @see PackageManagerInternal#queryIntentReceivers
      */
     @NonNull
-    public List<ResolveInfo> queryIntentReceiversInternal(Computer computer, Intent intent,
-            String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId,
-            int filterCallingUid, boolean forSend) {
+    public List<ResolveInfo> queryIntentReceiversInternal(
+            Computer computer, Intent intent, String resolvedType,
+            @PackageManager.ResolveInfoFlagsBits long flags, int userId,
+            int filterCallingUid, int callingPid, boolean forSend) {
         if (!mUserManager.exists(userId)) return Collections.emptyList();
         // The identity used to filter the receiver components
         final int queryingUid = forSend ? Process.SYSTEM_UID : filterCallingUid;
@@ -421,6 +358,12 @@
         }
         final ComponentResolverApi componentResolver = computer.getComponentResolver();
         List<ResolveInfo> list = Collections.emptyList();
+
+        var args = new SaferIntentUtils.IntentArgs(intent, resolvedType,
+                true /* isReceiver */, forSend, filterCallingUid, callingPid);
+        args.platformCompat = mPlatformCompat;
+        args.snapshot = computer;
+
         if (comp != null) {
             final ActivityInfo ai = computer.getReceiverInfo(comp, flags, userId);
             if (ai != null) {
@@ -457,9 +400,7 @@
                     ri.activityInfo = ai;
                     list = new ArrayList<>(1);
                     list.add(ri);
-                    PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
-                            mPlatformCompat, computer, list, true, intent,
-                            resolvedType, filterCallingUid);
+                    SaferIntentUtils.enforceIntentFilterMatching(args, list);
                 }
             }
         } else {
@@ -479,15 +420,13 @@
                     list = result;
                 }
             }
-            PackageManagerServiceUtils.applyNullActionBlocking(
-                    mPlatformCompat, computer, list, true, intent, filterCallingUid);
+            SaferIntentUtils.blockNullAction(args, list);
         }
 
         if (originalIntent != null) {
             // We also have to ensure all components match the original intent
-            PackageManagerServiceUtils.applyEnforceIntentFilterMatching(
-                    mPlatformCompat, computer,
-                    list, true, originalIntent, resolvedType, filterCallingUid);
+            args.intent = originalIntent;
+            SaferIntentUtils.enforceIntentFilterMatching(args, list);
         }
 
         return computer.applyPostResolutionFilter(list, instantAppPkgName, false, queryingUid,
@@ -495,14 +434,16 @@
     }
 
 
-    public ResolveInfo resolveServiceInternal(@NonNull Computer computer, Intent intent,
+    public ResolveInfo resolveServiceInternal(
+            @NonNull Computer computer, Intent intent,
             String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId,
-            int callingUid) {
+            int callingUid, int callingPid, boolean resolveForStart) {
         if (!mUserManager.exists(userId)) return null;
         flags = computer.updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
                 false /* isImplicitImageCaptureIntentAndNotSetByDpc */);
         List<ResolveInfo> query = computer.queryIntentServicesInternal(
-                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
+                intent, resolvedType, flags, userId, callingUid, callingPid,
+                /*includeInstantApps*/ false, resolveForStart);
         if (query != null) {
             if (query.size() >= 1) {
                 // If there is more than one service with the same priority,
@@ -705,7 +646,8 @@
                 if (comp == null) {
                     ri = resolveIntentInternal(computer, sintent,
                             specificTypes != null ? specificTypes[i] : null, flags,
-                            0 /*privateResolveFlags*/, userId, false, Binder.getCallingUid());
+                            0 /*privateResolveFlags*/, userId, false,
+                            Binder.getCallingUid(), Binder.getCallingPid());
                     if (ri == null) {
                         continue;
                     }
diff --git a/services/core/java/com/android/server/pm/SaferIntentUtils.java b/services/core/java/com/android/server/pm/SaferIntentUtils.java
new file mode 100644
index 0000000..8175321
--- /dev/null
+++ b/services/core/java/com/android/server/pm/SaferIntentUtils.java
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.pm;
+
+import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH;
+import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH;
+import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH;
+import static com.android.server.pm.PackageManagerService.DEBUG_INTENT_MATCHING;
+import static com.android.server.pm.PackageManagerService.TAG;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
+import android.compat.annotation.EnabledAfter;
+import android.compat.annotation.Overridable;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ComponentInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.Build;
+import android.os.Process;
+import android.os.UserHandle;
+import android.security.Flags;
+import android.util.Log;
+import android.util.LogPrinter;
+import android.util.Printer;
+import android.util.Slog;
+
+import com.android.internal.pm.pkg.component.ParsedMainComponent;
+import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.IntentResolver;
+import com.android.server.LocalServices;
+import com.android.server.am.BroadcastFilter;
+import com.android.server.compat.PlatformCompat;
+import com.android.server.pm.resolution.ComponentResolverApi;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
+
+import java.util.List;
+
+/**
+ * The way Safer Intent is implemented is to add several "hooks" into PMS's intent
+ * resolution process, and in some cases, AMS's runtime receiver resolution. Think of
+ * these methods as resolution "passes", where they post-process the resolved component list.
+ * <p>
+ * Here are the 4 main hooking entry points for each component type:
+ * <ul>
+ *     <li>Activity: {@link ComputerEngine#queryIntentActivitiesInternal} or
+ *     {@link ResolveIntentHelper#resolveIntentInternal}</li>
+ *     <li>Service: {@link Computer#queryIntentServicesInternal}</li>
+ *     <li>Static BroadcastReceivers: {@link ResolveIntentHelper#queryIntentReceiversInternal}</li>
+ *     <li>Runtime BroadcastReceivers:
+ *     {@link com.android.server.am.ActivityManagerService#broadcastIntentLockedTraced}</li>
+ * </ul>
+ */
+public class SaferIntentUtils {
+
+    // This is a hack to workaround b/240373119; a proper fix should be implemented instead.
+    public static final ThreadLocal<Boolean> DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS =
+            ThreadLocal.withInitial(() -> false);
+
+    /**
+     * Apps targeting Android U and above will need to export components in order to invoke them
+     * through implicit intents.
+     * <p>
+     * If a component is not exported and invoked, it will be removed from the list of receivers.
+     * This applies specifically to activities and broadcasts.
+     */
+    @ChangeId
+    @Overridable
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    private static final long IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS = 229362273;
+
+    /**
+     * Intents sent from apps enabling this feature will stop resolving to components with
+     * non matching intent filters, even when explicitly setting a component name, unless the
+     * target components are in the same app as the calling app.
+     * <p>
+     * When an app registers an exported component in its manifest and adds &lt;intent-filter&gt;s,
+     * the component can be started by any intent - even those that do not match the intent filter.
+     * This has proven to be something that many developers find counterintuitive.
+     * Without checking the intent when the component is started, in some circumstances this can
+     * allow 3P apps to trigger internal-only functionality.
+     */
+    @ChangeId
+    @Overridable
+    @Disabled
+    private static final long ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS = 161252188;
+
+    private static ParsedMainComponent infoToComponent(
+            ComponentInfo info, ComponentResolverApi resolver, boolean isReceiver) {
+        if (info instanceof ActivityInfo) {
+            if (isReceiver) {
+                return resolver.getReceiver(info.getComponentName());
+            } else {
+                return resolver.getActivity(info.getComponentName());
+            }
+        } else if (info instanceof ServiceInfo) {
+            return resolver.getService(info.getComponentName());
+        } else {
+            // This shall never happen
+            throw new IllegalArgumentException("Unsupported component type");
+        }
+    }
+
+    /**
+     * Helper method to report an unsafe intent event.
+     */
+    public static void reportUnsafeIntentEvent(
+            int event, int callingUid, int callingPid,
+            Intent intent, String resolvedType, boolean blocked) {
+        String[] categories = intent.getCategories() == null ? new String[0]
+                : intent.getCategories().toArray(String[]::new);
+        String component = intent.getComponent() == null ? null
+                : intent.getComponent().flattenToString();
+        FrameworkStatsLog.write(FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED,
+                event,
+                callingUid,
+                component,
+                intent.getPackage(),
+                intent.getAction(),
+                categories,
+                resolvedType,
+                intent.getScheme(),
+                blocked);
+        LocalServices.getService(ActivityManagerInternal.class)
+                .triggerUnsafeIntentStrictMode(callingPid, event, intent);
+    }
+
+    /**
+     * All the relevant information about an intent resolution transaction.
+     */
+    public static class IntentArgs {
+
+        /* Several system_server components */
+
+        @Nullable
+        public PlatformCompat platformCompat;
+        @Nullable
+        public PackageDataSnapshot snapshot;
+
+        /* Information about the intent itself */
+
+        public Intent intent;
+        public String resolvedType;
+        public boolean isReceiver;
+
+        /* Information about the caller */
+
+        // Whether this intent resolution transaction is actually for starting a component and
+        // not only for querying matching components.
+        // This information is required because we only want to log and trigger strict mode
+        // violations on unsafe intent events when the caller actually wants to start something.
+        public boolean resolveForStart;
+        public int callingUid;
+        // When resolveForStart is false, callingPid does not matter as this is only used
+        // to lookup the strict mode violation callback.
+        public int callingPid;
+
+        public IntentArgs(
+                Intent intent, String resolvedType, boolean isReceiver,
+                boolean resolveForStart, int callingUid, int callingPid) {
+            this.isReceiver = isReceiver;
+            this.intent = intent;
+            this.resolvedType = resolvedType;
+            this.resolveForStart = resolveForStart;
+            this.callingUid = callingUid;
+            this.callingPid = resolveForStart ? callingPid : Process.INVALID_PID;
+        }
+
+        boolean isChangeEnabled(long changeId) {
+            return platformCompat == null || platformCompat.isChangeEnabledByUidInternal(
+                    changeId, callingUid);
+        }
+
+        void reportEvent(int event, boolean blocked) {
+            if (resolveForStart) {
+                SaferIntentUtils.reportUnsafeIntentEvent(
+                        event, callingUid, callingPid, intent, resolvedType, blocked);
+            }
+        }
+    }
+
+    /**
+     * Remove components if the intent has null action.
+     * <p>
+     * Because blocking null action applies to all resolution cases, it has to be hooked
+     * in all 4 locations. Note, for component intent resolution in Activity, Service,
+     * and static BroadcastReceivers, null action blocking is actually handled within
+     * {@link #enforceIntentFilterMatching}; we only need to handle it in this method when
+     * the intent does not specify an explicit component name.
+     * <p>
+     * `compat` and `snapshot` may be null when this method is called in ActivityManagerService
+     * CTS tests. The code in this method shall properly avoid control flows using these arguments.
+     */
+    public static void blockNullAction(IntentArgs args, List componentList) {
+        if (ActivityManager.canAccessUnexportedComponents(args.callingUid)) return;
+
+        final Computer computer = (Computer) args.snapshot;
+        ComponentResolverApi resolver = null;
+
+        final boolean enforce = Flags.blockNullActionIntents()
+                && args.isChangeEnabled(IntentFilter.BLOCK_NULL_ACTION_INTENTS);
+
+        for (int i = componentList.size() - 1; i >= 0; --i) {
+            boolean match = true;
+
+            Object c = componentList.get(i);
+            if (c instanceof ResolveInfo resolveInfo) {
+                if (computer == null) {
+                    // PackageManagerService is not started
+                    return;
+                }
+                if (resolver == null) {
+                    resolver = computer.getComponentResolver();
+                }
+                final ParsedMainComponent comp = infoToComponent(
+                        resolveInfo.getComponentInfo(), resolver, args.isReceiver);
+                if (!comp.getIntents().isEmpty() && args.intent.getAction() == null) {
+                    match = false;
+                }
+            } else if (c instanceof IntentFilter) {
+                if (args.intent.getAction() == null) {
+                    match = false;
+                }
+            }
+
+            if (!match) {
+                args.reportEvent(
+                        UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH, enforce);
+                if (enforce) {
+                    Slog.w(TAG, "Blocking intent with null action: " + args.intent);
+                    componentList.remove(i);
+                }
+            }
+        }
+    }
+
+    /**
+     * Remove ResolveInfos that does not match the provided component intent.
+     * <p>
+     * Component intents cannot refer to a runtime registered BroadcastReceiver, so we only
+     * need to hook into the rest of the 3 entry points. Please note, this method also
+     * handles null action blocking for all component intents; do not go through an additional
+     * {@link #blockNullAction} pass!
+     */
+    public static void enforceIntentFilterMatching(
+            IntentArgs args, List<ResolveInfo> resolveInfos) {
+        if (DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.get()) return;
+
+        // Do not enforce filter matching when the caller is system or root
+        if (ActivityManager.canAccessUnexportedComponents(args.callingUid)) return;
+
+        final Computer computer = (Computer) args.snapshot;
+        final ComponentResolverApi resolver = computer.getComponentResolver();
+
+        final Printer logPrinter = DEBUG_INTENT_MATCHING
+                ? new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM)
+                : null;
+
+        final boolean enforceMatch = Flags.enforceIntentFilterMatch()
+                && args.isChangeEnabled(ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS);
+        final boolean blockNullAction = Flags.blockNullActionIntents()
+                && args.isChangeEnabled(IntentFilter.BLOCK_NULL_ACTION_INTENTS);
+
+        for (int i = resolveInfos.size() - 1; i >= 0; --i) {
+            final ComponentInfo info = resolveInfos.get(i).getComponentInfo();
+
+            // Skip filter matching when the caller is targeting the same app
+            if (UserHandle.isSameApp(args.callingUid, info.applicationInfo.uid)) {
+                continue;
+            }
+
+            final ParsedMainComponent comp = infoToComponent(info, resolver, args.isReceiver);
+
+            if (comp == null || comp.getIntents().isEmpty()) {
+                continue;
+            }
+
+            Boolean match = null;
+
+            if (args.intent.getAction() == null) {
+                args.reportEvent(
+                        UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NULL_ACTION_MATCH,
+                        enforceMatch && blockNullAction);
+                if (blockNullAction) {
+                    // Skip intent filter matching if blocking null action
+                    match = false;
+                }
+            }
+
+            if (match == null) {
+                // Check if any intent filter matches
+                for (int j = 0, size = comp.getIntents().size(); j < size; ++j) {
+                    IntentFilter intentFilter = comp.getIntents().get(j).getIntentFilter();
+                    if (IntentResolver.intentMatchesFilter(
+                            intentFilter, args.intent, args.resolvedType)) {
+                        match = true;
+                        break;
+                    }
+                }
+            }
+
+            // At this point, the value `match` has the following states:
+            // null : Intent does not match any intent filter
+            // false: Null action intent detected AND blockNullAction == true
+            // true : The intent matches at least one intent filter
+
+            if (match == null) {
+                args.reportEvent(
+                        UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__EXPLICIT_INTENT_FILTER_UNMATCH,
+                        enforceMatch);
+                match = false;
+            }
+
+            if (!match) {
+                // All non-matching intents has to be marked accordingly
+                if (Flags.enforceIntentFilterMatch()) {
+                    args.intent.addExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
+                }
+                if (enforceMatch) {
+                    Slog.w(TAG, "Intent does not match component's intent filter: " + args.intent);
+                    Slog.w(TAG, "Access blocked: " + comp.getComponentName());
+                    if (DEBUG_INTENT_MATCHING) {
+                        Slog.v(TAG, "Component intent filters:");
+                        comp.getIntents().forEach(f -> f.getIntentFilter().dump(logPrinter, "  "));
+                        Slog.v(TAG, "-----------------------------");
+                    }
+                    resolveInfos.remove(i);
+                }
+            }
+        }
+    }
+
+    /**
+     * Filter non-exported components from the componentList if intent is implicit.
+     * <p>
+     * Implicit intents cannot be used to start Services since API 21+.
+     * Implicit broadcasts cannot be delivered to static BroadcastReceivers since API 25+.
+     * So we only need to hook into Activity and runtime BroadcastReceiver intent resolution.
+     */
+    public static void filterNonExportedComponents(IntentArgs args, List componentList) {
+        if (componentList == null
+                || args.intent.getPackage() != null
+                || args.intent.getComponent() != null
+                || ActivityManager.canAccessUnexportedComponents(args.callingUid)) {
+            return;
+        }
+
+        final boolean enforce =
+                args.isChangeEnabled(IMPLICIT_INTENTS_ONLY_MATCH_EXPORTED_COMPONENTS);
+        boolean violated = false;
+
+        for (int i = componentList.size() - 1; i >= 0; i--) {
+            Object c = componentList.get(i);
+            if (c instanceof ResolveInfo resolveInfo) {
+                if (resolveInfo.getComponentInfo().exported) {
+                    continue;
+                }
+            } else if (c instanceof BroadcastFilter broadcastFilter) {
+                if (broadcastFilter.exported) {
+                    continue;
+                }
+            } else {
+                continue;
+            }
+            violated = true;
+            if (!enforce) {
+                break;
+            }
+            componentList.remove(i);
+        }
+
+        if (violated) {
+            args.reportEvent(
+                    UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH,
+                    enforce);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
index ec8af2e..929fccc 100644
--- a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
+++ b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
@@ -729,7 +729,7 @@
                     if (!pkgSetting.isSystem() || pkgSetting.isUpdatedSystemApp()) {
                         final int flags = pkgSetting.isUpdatedSystemApp()
                                 ? PackageManager.DELETE_KEEP_DATA : 0;
-                        synchronized (mPm.mInstallLock) {
+                        try (var installLock = mPm.mInstallLock.acquireLock()) {
                             mDeletePackageHelper.deletePackageLIF(pkg.getPackageName(), null, true,
                                     mPm.mUserManager.getUserIds(), flags, new PackageRemovedInfo(),
                                     true);
diff --git a/services/core/java/com/android/server/pm/StorageEventHelper.java b/services/core/java/com/android/server/pm/StorageEventHelper.java
index cef3244..951986f 100644
--- a/services/core/java/com/android/server/pm/StorageEventHelper.java
+++ b/services/core/java/com/android/server/pm/StorageEventHelper.java
@@ -156,7 +156,7 @@
             freezers.add(mPm.freezePackage(ps.getPackageName(), UserHandle.USER_ALL,
                     "loadPrivatePackagesInner", ApplicationExitInfo.REASON_OTHER,
                     null /* request */));
-            synchronized (mPm.mInstallLock) {
+            try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
                 final AndroidPackage pkg;
                 try {
                     pkg = mPm.initPackageTracedLI(
@@ -194,7 +194,7 @@
 
             try {
                 sm.prepareUserStorage(volumeUuid, user.id, flags);
-                synchronized (mPm.mInstallLock) {
+                try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
                     appDataHelper.reconcileAppsDataLI(volumeUuid, user.id, flags,
                             true /* migrateAppData */);
                 }
@@ -247,7 +247,7 @@
 
         final int[] userIds = mPm.mUserManager.getUserIds();
         final ArrayList<AndroidPackage> unloaded = new ArrayList<>();
-        synchronized (mPm.mInstallLock) {
+        try (PackageManagerTracedLock installLock = mPm.mInstallLock.acquireLock()) {
             synchronized (mPm.mLock) {
                 final List<? extends PackageStateInternal> packages =
                         mPm.mSettings.getVolumePackagesLPr(volumeUuid);
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index ef32485..041f2d3 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -66,7 +66,7 @@
      * Prepare storage areas for given user on all mounted devices.
      */
     void prepareUserData(UserInfo userInfo, int flags) {
-        synchronized (mInstallLock) {
+        try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
             final StorageManager storage = mContext.getSystemService(StorageManager.class);
             /*
              * Internal storage must be prepared before adoptable storage, since the user's volume
@@ -157,7 +157,7 @@
      * Destroy storage areas for given user on all mounted devices.
      */
     void destroyUserData(int userId, int flags) {
-        synchronized (mInstallLock) {
+        try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
             final StorageManager storage = mContext.getSystemService(StorageManager.class);
             /*
              * Volume destruction order isn't really important, but to avoid any weird issues we
@@ -262,7 +262,7 @@
             }
 
             if (destroyUser) {
-                synchronized (mInstallLock) {
+                try (PackageManagerTracedLock installLock = mInstallLock.acquireLock()) {
                     destroyUserDataLI(volumeUuid, userId,
                             StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
                 }
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index e93d320..ffb23e6 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -39,7 +39,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.pm.Installer;
 import com.android.server.pm.PackageDexOptimizer;
 import com.android.server.pm.PackageManagerService;
 import com.android.server.pm.PackageManagerServiceUtils;
@@ -99,9 +98,6 @@
 
     private IPackageManager mPackageManager;
     private final PackageDexOptimizer mPackageDexOptimizer;
-    private final Object mInstallLock;
-    @GuardedBy("mInstallLock")
-    private final Installer mInstaller;
 
     private BatteryManager mBatteryManager = null;
     private PowerManager mPowerManager = null;
@@ -116,21 +112,18 @@
     private static final int DEX_SEARCH_FOUND_SPLIT = 2;  // dex file is a split apk
     private static final int DEX_SEARCH_FOUND_SECONDARY = 3;  // dex file is a secondary dex
 
-    public DexManager(Context context, PackageDexOptimizer pdo, Installer installer,
-            Object installLock, DynamicCodeLogger dynamicCodeLogger) {
-        this(context, pdo, installer, installLock, dynamicCodeLogger, null);
+    public DexManager(Context context, PackageDexOptimizer pdo,
+            DynamicCodeLogger dynamicCodeLogger) {
+        this(context, pdo, dynamicCodeLogger, null);
     }
 
     @VisibleForTesting
-    public DexManager(Context context, PackageDexOptimizer pdo, Installer installer,
-            Object installLock, DynamicCodeLogger dynamicCodeLogger,
-            @Nullable IPackageManager packageManager) {
+    public DexManager(Context context, PackageDexOptimizer pdo,
+            DynamicCodeLogger dynamicCodeLogger, @Nullable IPackageManager packageManager) {
         mContext = context;
         mPackageCodeLocationsCache = new HashMap<>();
         mPackageDexUsage = new PackageDexUsage();
         mPackageDexOptimizer = pdo;
-        mInstaller = installer;
-        mInstallLock = installLock;
         mDynamicCodeLogger = dynamicCodeLogger;
         mPackageManager = packageManager;
 
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 5360788..f5882a38 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -74,6 +74,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
@@ -1609,7 +1610,7 @@
         /** Map of skin temperature sensor name to a corresponding list of samples */
         @GuardedBy("mSamples")
         @VisibleForTesting
-        final ArrayMap<String, ArrayList<Sample>> mSamples = new ArrayMap<>();
+        final ArrayMap<String, LinkedList<Sample>> mSamples = new ArrayMap<>();
 
         /** Map of skin temperature sensor name to the corresponding SEVERE temperature threshold */
         @GuardedBy("mSamples")
@@ -1706,10 +1707,10 @@
                         continue;
                     }
 
-                    ArrayList<Sample> samples = mSamples.computeIfAbsent(temperature.getName(),
-                            k -> new ArrayList<>(RING_BUFFER_SIZE));
+                    LinkedList<Sample> samples = mSamples.computeIfAbsent(temperature.getName(),
+                            k -> new LinkedList<>());
                     if (samples.size() == RING_BUFFER_SIZE) {
-                        samples.remove(0);
+                        samples.removeFirst();
                     }
                     samples.add(new Sample(now, temperature.getValue()));
                 }
@@ -1724,8 +1725,7 @@
         float getSlopeOf(List<Sample> samples) {
             long sumTimes = 0L;
             float sumTemperatures = 0.0f;
-            for (int s = 0; s < samples.size(); ++s) {
-                Sample sample = samples.get(s);
+            for (final Sample sample : samples) {
                 sumTimes += sample.time;
                 sumTemperatures += sample.temperature;
             }
@@ -1734,8 +1734,7 @@
 
             long sampleVariance = 0L;
             float sampleCovariance = 0.0f;
-            for (int s = 0; s < samples.size(); ++s) {
-                Sample sample = samples.get(s);
+            for (final Sample sample : samples) {
                 long timeDelta = sample.time - meanTime;
                 float temperatureDelta = sample.temperature - meanTemperature;
                 sampleVariance += timeDelta * timeDelta;
@@ -1795,9 +1794,9 @@
 
                 float maxNormalized = Float.NaN;
                 int noThresholdSampleCount = 0;
-                for (Map.Entry<String, ArrayList<Sample>> entry : mSamples.entrySet()) {
+                for (Map.Entry<String, LinkedList<Sample>> entry : mSamples.entrySet()) {
                     String name = entry.getKey();
-                    ArrayList<Sample> samples = entry.getValue();
+                    LinkedList<Sample> samples = entry.getValue();
 
                     Float threshold = mSevereThresholds.get(name);
                     if (threshold == null) {
@@ -1806,7 +1805,7 @@
                         continue;
                     }
 
-                    float currentTemperature = samples.get(0).temperature;
+                    float currentTemperature = samples.getLast().temperature;
 
                     if (samples.size() < MINIMUM_SAMPLE_COUNT) {
                         // Don't try to forecast, just use the latest one we have
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 72b854b..a9192c4c 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -936,13 +936,8 @@
         }
         mLastStartReason = request.reason;
         mLastStartActivityTimeMs = System.currentTimeMillis();
-        // Reset the ActivityRecord#mCurrentLaunchCanTurnScreenOn state of last start activity in
-        // case the state is not yet consumed during rapid activity launch.
-        if (mLastStartActivityRecord != null) {
-            mLastStartActivityRecord.setCurrentLaunchCanTurnScreenOn(false);
-        }
-        mLastStartActivityRecord = null;
 
+        final ActivityRecord previousStart = mLastStartActivityRecord;
         final IApplicationThread caller = request.caller;
         Intent intent = request.intent;
         NeededUriGrants intentGrants = request.intentGrants;
@@ -1370,6 +1365,18 @@
             request.outActivity[0] = mLastStartActivityRecord;
         }
 
+        // Reset the ActivityRecord#mCurrentLaunchCanTurnScreenOn state of activity started
+        // before this one if it is no longer the top-most focusable activity.
+        // Doing so in case the state is not yet consumed during rapid activity launch.
+        if (previousStart != null && !previousStart.finishing && previousStart.isAttached()
+                && previousStart.currentLaunchCanTurnScreenOn()) {
+            final ActivityRecord topFocusable = previousStart.getDisplayContent().getActivity(
+                    ar -> ar.isFocusable() && !ar.finishing);
+            if (previousStart != topFocusable) {
+                previousStart.setCurrentLaunchCanTurnScreenOn(false);
+            }
+        }
+
         return mLastStartActivityResult;
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index a10f7e7..3867d2d 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -155,7 +155,7 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.HostingRecord;
 import com.android.server.am.UserState;
-import com.android.server.pm.PackageManagerServiceUtils;
+import com.android.server.pm.SaferIntentUtils;
 import com.android.server.utils.Slogf;
 import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
 
@@ -769,7 +769,7 @@
             // (e.g. AMS.startActivityAsUser).
             final long token = Binder.clearCallingIdentity();
             try {
-                return mService.getPackageManagerInternalLocked().resolveIntentExported(
+                return mService.getPackageManagerInternalLocked().resolveIntent(
                         intent, resolvedType, modifiedFlags, privateResolveFlags, userId, true,
                         filterCallingUid, callingPid);
             } finally {
@@ -2856,14 +2856,14 @@
             // We need to temporarily disable the explicit intent filter matching enforcement
             // because Task does not store the resolved type of the intent data, causing filter
             // mismatch in certain cases. (b/240373119)
-            PackageManagerServiceUtils.DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.set(true);
+            SaferIntentUtils.DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.set(true);
             return mService.getActivityStartController().startActivityInPackage(taskCallingUid,
                     callingPid, callingUid, callingPackage, callingFeatureId, intent, null, null,
                     null, 0, 0, options, userId, task, "startActivityFromRecents",
                     false /* validateIncomingUser */, null /* originatingPendingIntent */,
                     BackgroundStartPrivileges.NONE);
         } finally {
-            PackageManagerServiceUtils.DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.set(false);
+            SaferIntentUtils.DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.set(false);
             synchronized (mService.mGlobalLock) {
                 mService.continueWindowLayout();
             }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a551c7c..a3a6b51 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -4160,6 +4160,7 @@
                 && mImeLayeringTarget != null
                 && mImeLayeringTarget.mActivityRecord != null
                 && mImeLayeringTarget.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+                && mImeLayeringTarget.getBounds().equals(mImeWindowsContainer.getBounds())
                 // IME is attached to app windows that fill display area. This excludes
                 // letterboxed windows.
                 && mImeLayeringTarget.matchesDisplayAreaBounds();
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index d0086aa..2f23955 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2011,9 +2011,14 @@
             public String toString() {
                 final StringBuilder tmpSb = new StringBuilder(32);
                 return "{nonDecorInsets=" + mNonDecorInsets.toShortString(tmpSb)
+                        + ", overrideNonDecorInsets=" + mOverrideNonDecorInsets.toShortString(tmpSb)
                         + ", configInsets=" + mConfigInsets.toShortString(tmpSb)
+                        + ", overrideConfigInsets=" + mOverrideConfigInsets.toShortString(tmpSb)
                         + ", nonDecorFrame=" + mNonDecorFrame.toShortString(tmpSb)
-                        + ", configFrame=" + mConfigFrame.toShortString(tmpSb) + '}';
+                        + ", overrideNonDecorFrame=" + mOverrideNonDecorFrame.toShortString(tmpSb)
+                        + ", configFrame=" + mConfigFrame.toShortString(tmpSb)
+                        + ", overrideConfigFrame=" + mOverrideConfigFrame.toShortString(tmpSb)
+                        + '}';
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index be8c2ae..9c7c41c 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1693,7 +1693,7 @@
     }
 
     /**
-     * Check if home activity start should be allowed on a display.
+     * Check if home activity start should be allowed on a {@link TaskDisplayArea}.
      *
      * @param homeInfo           {@code ActivityInfo} of the home activity that is going to be
      *                           launched.
@@ -1717,6 +1717,10 @@
             return false;
         }
 
+        if (taskDisplayArea != null && !taskDisplayArea.canHostHomeTask()) {
+            return false;
+        }
+
         final int displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId()
                 : INVALID_DISPLAY;
         if (shouldPlacePrimaryHomeOnDisplay(displayId)) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 218334e..86c6f8d 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -52,6 +52,7 @@
 import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
 import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
 import static android.window.TransitionInfo.FLAG_IS_INPUT_METHOD;
+import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
 import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP;
@@ -95,6 +96,7 @@
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 import android.window.ScreenCapture;
+import android.window.TaskFragmentAnimationParams;
 import android.window.TransitionInfo;
 import android.window.WindowContainerTransaction;
 
@@ -2728,12 +2730,13 @@
             return out;
         }
 
-        final AnimationOptions animOptions = calculateAnimationOptionsForActivityTransition(type,
-                sortedTargets);
-        if (!Flags.moveAnimationOptionsToChange() && animOptions != null) {
-            out.setAnimationOptions(animOptions);
+        final AnimationOptions animOptionsForActivityTransition =
+                calculateAnimationOptionsForActivityTransition(type, sortedTargets);
+        if (!Flags.moveAnimationOptionsToChange() && animOptionsForActivityTransition != null) {
+            out.setAnimationOptions(animOptionsForActivityTransition);
         }
 
+        final ArraySet<WindowContainer> occludedAtEndContainers = new ArraySet<>();
         // Convert all the resolved ChangeInfos into TransactionInfo.Change objects in order.
         final int count = sortedTargets.size();
         for (int i = 0; i < count; ++i) {
@@ -2757,8 +2760,26 @@
             info.mReadyFlags = change.getFlags();
             change.setDisplayId(info.mDisplayId, getDisplayId(target));
 
+            // Add FLAGS_IS_OCCLUDED to preventing from visible-translucent change which belows
+            // the non-translucent change playing unexpected open animation.
+            if (change.getMode() == TRANSIT_TO_FRONT || change.getMode() == TRANSIT_OPEN) {
+                for (int occIndex = occludedAtEndContainers.size() - 1; occIndex >= 0; --occIndex) {
+                    if (target.isDescendantOf(occludedAtEndContainers.valueAt(occIndex))) {
+                        change.setFlags(change.getFlags() | FLAG_IS_OCCLUDED);
+                        break;
+                    }
+                }
+            }
+            if (!change.hasFlags(FLAG_TRANSLUCENT)  && (change.getMode() == TRANSIT_OPEN
+                    || change.getMode() == TRANSIT_TO_FRONT
+                    || change.getMode() == TRANSIT_CHANGE)) {
+                occludedAtEndContainers.add(target.getParent());
+            }
+
             final Task task = target.asTask();
             final TaskFragment taskFragment = target.asTaskFragment();
+            final boolean isEmbeddedTaskFragment = taskFragment != null
+                    && taskFragment.isEmbedded();
             final ActivityRecord activityRecord = target.asActivityRecord();
 
             if (task != null) {
@@ -2798,7 +2819,7 @@
                 change.setEndAbsBounds(bounds);
             }
 
-            if (activityRecord != null || (taskFragment != null && taskFragment.isEmbedded())) {
+            if (activityRecord != null || isEmbeddedTaskFragment) {
                 final int backgroundColor;
                 final TaskFragment organizedTf = activityRecord != null
                         ? activityRecord.getOrganizedTaskFragment()
@@ -2823,9 +2844,27 @@
                 change.setBackgroundColor(ColorUtils.setAlphaComponent(backgroundColor, 255));
             }
 
-            if (Flags.moveAnimationOptionsToChange() && activityRecord != null
-                    && animOptions != null) {
-                change.setAnimationOptions(animOptions);
+            AnimationOptions animOptions = null;
+            if (Flags.moveAnimationOptionsToChange()) {
+                if (activityRecord != null && animOptionsForActivityTransition != null) {
+                    animOptions = animOptionsForActivityTransition;
+                } else if (Flags.activityEmbeddingOverlayPresentationFlag()
+                        && isEmbeddedTaskFragment) {
+                    final TaskFragmentAnimationParams params = taskFragment.getAnimationParams();
+                    if (params.hasOverrideAnimation()) {
+                        // Only set AnimationOptions if there's any animation override.
+                        // We use separated field for backgroundColor, and
+                        // AnimationOptions#backgroundColor will be removed in long term.
+                        animOptions = AnimationOptions.makeCustomAnimOptions(
+                                taskFragment.getTask().getBasePackageName(),
+                                params.getOpenAnimationResId(), params.getChangeAnimationResId(),
+                                params.getCloseAnimationResId(), 0 /* backgroundColor */,
+                                false /* overrideTaskTransition */);
+                    }
+                }
+                if (animOptions != null) {
+                    change.setAnimationOptions(animOptions);
+                }
             }
 
             if (activityRecord != null) {
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 7eda53f..1034611 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -23,8 +23,8 @@
 import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.window.TaskFragmentOperation.OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS;
-import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
 import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_OR_MOVE_TASK_FRAGMENT_DECOR_SURFACE;
+import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
 import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
 import static android.window.TaskFragmentOperation.OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE;
 import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_BOTTOM_OF_TASK;
@@ -1835,7 +1835,7 @@
 
             task.getParent().positionChildAt(
                     hop.getToTop() ? POSITION_TOP : POSITION_BOTTOM,
-                    task, false /* includingParents */);
+                    task, hop.includingParents());
         }
         return TRANSACT_EFFECTS_LIFECYCLE;
     }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a7b3f4f..dcd4bd6 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1814,9 +1814,11 @@
         if (mInsetsSourceProviders == null) {
             return false;
         }
+        final @InsetsType int decorInsetsTypes =
+                mWmService.mConfigTypes | mWmService.mOverrideConfigTypes;
         for (int i = mInsetsSourceProviders.size() - 1; i >= 0; i--) {
             final InsetsSource source = mInsetsSourceProviders.valueAt(i).getSource();
-            if ((source.getType() & mWmService.mConfigTypes) != 0) {
+            if ((source.getType() & decorInsetsTypes) != 0) {
                 return true;
             }
         }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
index 323ef6a..88d3238 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
@@ -33,6 +33,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.hardware.SensorManager;
+import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
 import android.os.Handler;
 import android.os.HandlerExecutor;
@@ -119,7 +120,8 @@
         int targetDisplayState = Display.STATE_DOZE;
         when(mDisplayBrightnessStrategySelector.selectStrategy(
                 any(StrategySelectionRequest.class))).thenReturn(displayBrightnessStrategy);
-        mDisplayBrightnessController.updateBrightness(displayPowerRequest, targetDisplayState);
+        mDisplayBrightnessController.updateBrightness(displayPowerRequest, targetDisplayState, mock(
+                DisplayManagerInternal.DisplayOffloadSession.class));
         verify(displayBrightnessStrategy).updateBrightness(
                 eq(new StrategyExecutionRequest(displayPowerRequest, DEFAULT_BRIGHTNESS,
                         /* userSetBrightnessChanged= */ false)));
@@ -128,6 +130,12 @@
     }
 
     @Test
+    public void isAllowAutoBrightnessWhileDozingDelegatesToDozeBrightnessStrategy() {
+        mDisplayBrightnessController.isAllowAutoBrightnessWhileDozing();
+        verify(mDisplayBrightnessStrategySelector).isAllowAutoBrightnessWhileDozing();
+    }
+
+    @Test
     public void isAllowAutoBrightnessWhileDozingConfigDelegatesToDozeBrightnessStrategy() {
         mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig();
         verify(mDisplayBrightnessStrategySelector).isAllowAutoBrightnessWhileDozingConfig();
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
index df96712..639d06d 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
@@ -16,13 +16,15 @@
 
 package com.android.server.display.brightness;
 
+import static junit.framework.Assert.assertFalse;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.ContentResolver;
@@ -97,6 +99,9 @@
     @Mock
     private DisplayManagerFlags mDisplayManagerFlags;
 
+    @Mock
+    private DisplayManagerInternal.DisplayOffloadSession mDisplayOffloadSession;
+
     private DisplayBrightnessStrategySelector mDisplayBrightnessStrategySelector;
     private Context mContext;
     private DisplayBrightnessStrategySelector.Injector mInjector =
@@ -191,7 +196,7 @@
                 DISALLOW_AUTO_BRIGHTNESS_WHILE_DOZING);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_DOZE,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mDozeBrightnessModeStrategy);
     }
 
@@ -205,7 +210,30 @@
                 DISALLOW_AUTO_BRIGHTNESS_WHILE_DOZING);
         assertNotEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_DOZE,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
+                mDozeBrightnessModeStrategy);
+    }
+
+    @Test
+    public void selectStrategyDoesNotSelectDozeStrategyWhenOffloadSessionAutoBrightnessIsEnabled() {
+        when(mDisplayManagerFlags.offloadControlsDozeAutoBrightness()).thenReturn(true);
+        when(mDisplayManagerFlags.isDisplayOffloadEnabled()).thenReturn(true);
+        when(mDisplayOffloadSession.allowAutoBrightnessInDoze()).thenReturn(true);
+        when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
+                true);
+        when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
+                true);
+
+        mDisplayBrightnessStrategySelector = new DisplayBrightnessStrategySelector(mContext,
+                mInjector, DISPLAY_ID, mDisplayManagerFlags);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
+                DisplayManagerInternal.DisplayPowerRequest.class);
+        displayPowerRequest.policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+        displayPowerRequest.dozeScreenBrightness = 0.2f;
+
+        assertNotEquals(mDisplayBrightnessStrategySelector.selectStrategy(
+                        new StrategySelectionRequest(displayPowerRequest, Display.STATE_DOZE,
+                                0.1f, false, mDisplayOffloadSession)),
                 mDozeBrightnessModeStrategy);
     }
 
@@ -215,7 +243,7 @@
                 DisplayManagerInternal.DisplayPowerRequest.class);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_OFF,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mScreenOffBrightnessModeStrategy);
     }
 
@@ -227,7 +255,7 @@
         when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(Float.NaN);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mOverrideBrightnessStrategy);
     }
 
@@ -240,7 +268,7 @@
         when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(0.3f);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mTemporaryBrightnessStrategy);
     }
 
@@ -254,7 +282,7 @@
         when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(Float.NaN);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mBoostBrightnessStrategy);
     }
 
@@ -268,7 +296,7 @@
         when(mOffloadBrightnessStrategy.getOffloadScreenBrightness()).thenReturn(Float.NaN);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mInvalidBrightnessStrategy);
     }
 
@@ -279,7 +307,7 @@
         when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(0.3f);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mFollowerBrightnessStrategy);
     }
 
@@ -297,13 +325,18 @@
         when(mOffloadBrightnessStrategy.getOffloadScreenBrightness()).thenReturn(0.3f);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mOffloadBrightnessStrategy);
     }
 
     @Test
     public void selectStrategy_selectsAutomaticStrategyWhenValid() {
         when(mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()).thenReturn(true);
+        when(mDisplayManagerFlags.offloadControlsDozeAutoBrightness()).thenReturn(true);
+        when(mDisplayManagerFlags.isDisplayOffloadEnabled()).thenReturn(true);
+        when(mDisplayOffloadSession.allowAutoBrightnessInDoze()).thenReturn(true);
+        when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
+                true);
         mDisplayBrightnessStrategySelector = new DisplayBrightnessStrategySelector(mContext,
                 mInjector, DISPLAY_ID, mDisplayManagerFlags);
         DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
@@ -316,13 +349,11 @@
         when(mAutomaticBrightnessStrategy.isAutoBrightnessValid()).thenReturn(true);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mAutomaticBrightnessStrategy);
-        verifyZeroInteractions(mOffloadBrightnessStrategy);
         verify(mAutomaticBrightnessStrategy).setAutoBrightnessState(Display.STATE_ON,
-                false, BrightnessReason.REASON_UNKNOWN,
+                true, BrightnessReason.REASON_UNKNOWN,
                 DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT, 0.1f, false);
-
     }
 
     @Test
@@ -341,7 +372,7 @@
         when(mAutoBrightnessFallbackStrategy.isValid()).thenReturn(true);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mAutoBrightnessFallbackStrategy);
     }
 
@@ -359,7 +390,7 @@
         assertNotEquals(mOffloadBrightnessStrategy,
                 mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                                0.1f, false)));
+                                0.1f, false, mDisplayOffloadSession)));
     }
 
     @Test
@@ -377,7 +408,7 @@
         when(mAutomaticBrightnessStrategy.isAutoBrightnessValid()).thenReturn(false);
         assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
                         new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                                0.1f, false)),
+                                0.1f, false, mDisplayOffloadSession)),
                 mFallbackBrightnessStrategy);
     }
 
@@ -392,7 +423,7 @@
 
         mDisplayBrightnessStrategySelector.selectStrategy(
                 new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
-                        0.1f, false));
+                        0.1f, false, mDisplayOffloadSession));
 
         StrategySelectionNotifyRequest strategySelectionNotifyRequest =
                 new StrategySelectionNotifyRequest(displayPowerRequest, Display.STATE_ON,
@@ -422,4 +453,78 @@
         assertEquals(mAutomaticBrightnessStrategy,
                 mDisplayBrightnessStrategySelector.getAutomaticBrightnessStrategy());
     }
+
+    @Test
+    public void setAllowAutoBrightnessWhileDozing_enabledWhenConfigAndOffloadSessionAreEnabled() {
+        when(mDisplayManagerFlags.offloadControlsDozeAutoBrightness()).thenReturn(true);
+        when(mDisplayManagerFlags.isDisplayOffloadEnabled()).thenReturn(true);
+        when(mDisplayOffloadSession.allowAutoBrightnessInDoze()).thenReturn(true);
+        when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
+                true);
+        mDisplayBrightnessStrategySelector = new DisplayBrightnessStrategySelector(mContext,
+                mInjector, DISPLAY_ID, mDisplayManagerFlags);
+        mDisplayBrightnessStrategySelector
+                .setAllowAutoBrightnessWhileDozing(mDisplayOffloadSession);
+        assertTrue(mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozing());
+    }
+
+    @Test
+    public void setAllowAutoBrightnessWhileDozing_disabledWhenOffloadSessionFlagIsDisabled() {
+        when(mDisplayManagerFlags.offloadControlsDozeAutoBrightness()).thenReturn(true);
+        when(mDisplayManagerFlags.isDisplayOffloadEnabled()).thenReturn(true);
+        when(mDisplayOffloadSession.allowAutoBrightnessInDoze()).thenReturn(false);
+        when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
+                true);
+        mDisplayBrightnessStrategySelector = new DisplayBrightnessStrategySelector(mContext,
+                mInjector, DISPLAY_ID, mDisplayManagerFlags);
+        mDisplayBrightnessStrategySelector
+                .setAllowAutoBrightnessWhileDozing(mDisplayOffloadSession);
+        assertFalse(mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozing());
+    }
+
+    @Test
+    public void setAllowAutoBrightnessWhileDozing_disabledWhenABWhileDozingConfigIsDisabled() {
+        when(mDisplayManagerFlags.offloadControlsDozeAutoBrightness()).thenReturn(true);
+        when(mDisplayManagerFlags.isDisplayOffloadEnabled()).thenReturn(true);
+        when(mDisplayOffloadSession.allowAutoBrightnessInDoze()).thenReturn(true);
+        when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
+                false);
+        mDisplayBrightnessStrategySelector = new DisplayBrightnessStrategySelector(mContext,
+                mInjector, DISPLAY_ID, mDisplayManagerFlags);
+        mDisplayBrightnessStrategySelector
+                .setAllowAutoBrightnessWhileDozing(mDisplayOffloadSession);
+        assertFalse(mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozing());
+    }
+
+    @Test
+    public void setAllowAutoBrightnessWhileDozing_EnabledWhenOffloadSessionIsNotSet() {
+        when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
+                true);
+        mDisplayBrightnessStrategySelector = new DisplayBrightnessStrategySelector(mContext,
+                mInjector, DISPLAY_ID, mDisplayManagerFlags);
+        mDisplayBrightnessStrategySelector.setAllowAutoBrightnessWhileDozing(null);
+        assertTrue(mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozing());
+    }
+
+    @Test
+    public void setAllowAutoBrightnessWhileDozing_EnabledWhenFlagsAreDisabled() {
+        when(mDisplayManagerFlags.offloadControlsDozeAutoBrightness()).thenReturn(true);
+        when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
+                true);
+        mDisplayBrightnessStrategySelector = new DisplayBrightnessStrategySelector(mContext,
+                mInjector, DISPLAY_ID, mDisplayManagerFlags);
+
+        // Same as the config_allowAutoBrightnessWhileDozing when either of the concerned flags
+        // are disabled
+        when(mDisplayManagerFlags.isDisplayOffloadEnabled()).thenReturn(false);
+        mDisplayBrightnessStrategySelector
+                .setAllowAutoBrightnessWhileDozing(mDisplayOffloadSession);
+        assertTrue(mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozing());
+
+        when(mDisplayManagerFlags.isDisplayOffloadEnabled()).thenReturn(true);
+        when(mDisplayManagerFlags.offloadControlsDozeAutoBrightness()).thenReturn(false);
+        mDisplayBrightnessStrategySelector
+                .setAllowAutoBrightnessWhileDozing(mDisplayOffloadSession);
+        assertTrue(mDisplayBrightnessStrategySelector.isAllowAutoBrightnessWhileDozing());
+    }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java
index daa827ea..5f12677 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ServiceBindingOomAdjPolicyTest.java
@@ -556,7 +556,7 @@
         rInfo.serviceInfo = makeServiceInfo(compName.getClassName(), compName.getPackageName(),
                 serviceUid);
         doReturn(rInfo).when(mPackageManagerInt).resolveService(any(Intent.class), any(),
-                anyLong(), anyInt(), anyInt());
+                anyLong(), anyInt(), anyInt(), anyInt());
 
         return serviceIntent;
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 396edae..9ab607d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -140,6 +140,7 @@
         PropertyInvalidatedCache.disableForTestMode()
         val apply = ExtendedMockito.mockitoSession()
                 .strictness(Strictness.LENIENT)
+                .mockStatic(SaferIntentUtils::class.java)
                 .mockStatic(SystemProperties::class.java)
                 .mockStatic(SystemConfig::class.java)
                 .mockStatic(SELinuxMMAC::class.java, Mockito.CALLS_REAL_METHODS)
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerTracedLockTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerTracedLockTest.java
new file mode 100644
index 0000000..eebd921
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerTracedLockTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.pm;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class PackageManagerTracedLockTest {
+    PackageManagerTracedLock mLock = new PackageManagerTracedLock();
+    PackageManagerTracedLock.RawLock mRawLock = mLock.getRawLock();
+
+    @After
+    public void tearDown() {
+        if (mRawLock.isHeldByCurrentThread()) {
+            mRawLock.unlock();
+        }
+    }
+
+    @Test
+    public void testAcquireLock() {
+        assertFalse(mRawLock.isLocked());
+        try (var autoClosableLock = mLock.acquireLock()) {
+            assertTrue(mRawLock.isHeldByCurrentThread());
+            assertTrue(mRawLock.isLocked());
+            assertEquals(autoClosableLock.getRawLock(), mRawLock);
+            assertEquals(1, mRawLock.getHoldCount());
+            try (var autoClosableLock2 = mLock.acquireLock()) {
+                assertTrue(mRawLock.isHeldByCurrentThread());
+                assertTrue(mRawLock.isLocked());
+                assertEquals(autoClosableLock2.getRawLock(), mRawLock);
+                assertEquals(2, mRawLock.getHoldCount());
+            }
+            assertTrue(mRawLock.isHeldByCurrentThread());
+            assertTrue(mRawLock.isLocked());
+            assertEquals(1, mRawLock.getHoldCount());
+        }
+        assertFalse(mRawLock.isHeldByCurrentThread());
+        assertFalse(mRawLock.isLocked());
+        assertEquals(0, mRawLock.getHoldCount());
+    }
+
+    @Test
+    public void testUnlockInsideTry() {
+        assertFalse(mRawLock.isLocked());
+        try (var autoClosableLock = mLock.acquireLock()) {
+            assertTrue(mRawLock.isHeldByCurrentThread());
+            assertTrue(mRawLock.isLocked());
+            assertEquals(autoClosableLock.getRawLock(), mRawLock);
+            assertEquals(1, mRawLock.getHoldCount());
+            mRawLock.unlock();
+            assertFalse(mRawLock.isHeldByCurrentThread());
+            assertFalse(mRawLock.isLocked());
+            assertEquals(0, mRawLock.getHoldCount());
+            mRawLock.lock();
+        }
+        assertFalse(mRawLock.isHeldByCurrentThread());
+        assertFalse(mRawLock.isLocked());
+        assertEquals(0, mRawLock.getHoldCount());
+    }
+
+    @Test
+    public void testRawLock() {
+        assertFalse(mRawLock.isLocked());
+        mRawLock.lock();
+        assertTrue(mRawLock.isLocked());
+        assertTrue(mRawLock.isHeldByCurrentThread());
+        assertEquals(1, mRawLock.getHoldCount());
+        assertTrue(mRawLock.tryLock());
+        assertTrue(mRawLock.isLocked());
+        assertTrue(mRawLock.isHeldByCurrentThread());
+        assertEquals(2, mRawLock.getHoldCount());
+        mRawLock.unlock();
+        assertTrue(mRawLock.isLocked());
+        assertTrue(mRawLock.isHeldByCurrentThread());
+        assertEquals(1, mRawLock.getHoldCount());
+        mRawLock.unlock();
+        assertFalse(mRawLock.isLocked());
+        assertFalse(mRawLock.isHeldByCurrentThread());
+    }
+
+    @Test
+    public void testTrylock() throws InterruptedException {
+        assertFalse(mRawLock.isLocked());
+        HandlerThread thread = new HandlerThread("PackageManagerTracedLockTestThread",
+                android.os.Process.THREAD_PRIORITY_BACKGROUND);
+        thread.start();
+        Handler handler = new Handler(thread.getLooper());
+        handler.post(() -> mRawLock.lock());
+        waitForHandler(handler);
+        assertTrue(mRawLock.isLocked());
+        assertFalse(mRawLock.isHeldByCurrentThread());
+        assertEquals(0, mRawLock.getHoldCount());
+        assertFalse(mRawLock.tryLock());
+        handler.post(() -> mRawLock.unlock());
+        waitForHandler(handler);
+        assertFalse(mRawLock.isLocked());
+        assertFalse(mRawLock.isHeldByCurrentThread());
+        assertEquals(0, mRawLock.getHoldCount());
+        thread.interrupt();
+    }
+
+    private void waitForHandler(Handler handler) throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        handler.post(latch::countDown);
+        assertTrue(latch.await(1, TimeUnit.SECONDS));
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java
index 7dae235..a6784417 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -83,8 +83,6 @@
     @Mock BatteryManager mMockBatteryManager;
     @Mock PowerManager mMockPowerManager;
 
-    private final Object mInstallLock = new Object();
-
     private DynamicCodeLogger mDynamicCodeLogger;
     private DexManager mDexManager;
 
@@ -160,8 +158,8 @@
                 .getSystemService(PowerManager.class);
 
         mDynamicCodeLogger = new DynamicCodeLogger(mInstaller);
-        mDexManager = new DexManager(mockContext, /*PackageDexOptimizer*/ null, mInstaller,
-                mInstallLock, mDynamicCodeLogger, mPM);
+        mDexManager = new DexManager(mockContext, /*PackageDexOptimizer*/ null,
+                mDynamicCodeLogger, mPM);
 
         // Foo and Bar are available to user0.
         // Only Bar is available to user1;
diff --git a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
index 32bbc7a..3685afd 100644
--- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
@@ -68,6 +68,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
@@ -513,7 +514,7 @@
     @Test
     public void testTemperatureWatcherGetSlopeOf() throws RemoteException {
         TemperatureWatcher watcher = mService.mTemperatureWatcher;
-        List<TemperatureWatcher.Sample> samples = new ArrayList<>();
+        List<TemperatureWatcher.Sample> samples = new LinkedList<>();
         for (int i = 0; i < 30; ++i) {
             samples.add(watcher.createSampleForTesting(i, (float) (i / 2 * 2)));
         }
@@ -538,7 +539,7 @@
     public void testTemperatureWatcherGetForecast() throws RemoteException {
         TemperatureWatcher watcher = mService.mTemperatureWatcher;
 
-        ArrayList<TemperatureWatcher.Sample> samples = new ArrayList<>();
+        LinkedList<TemperatureWatcher.Sample> samples = new LinkedList<>();
 
         // Add a single sample
         samples.add(watcher.createSampleForTesting(0, 25.0f));
@@ -551,7 +552,7 @@
 
         // Add some time-series data
         for (int i = 1; i < 20; ++i) {
-            samples.add(0, watcher.createSampleForTesting(1000 * i, 25.0f + 0.5f * i));
+            samples.add(watcher.createSampleForTesting(1000 * i, 25.0f + 0.5f * i));
         }
 
         // Now the forecast should vary depending on how far ahead we are trying to predict
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 89140a2..2030b30 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -416,9 +416,7 @@
         doReturn("packageName").when(mMockPackageManager).getNameForUid(anyInt());
         doReturn(false).when(mMockPackageManager).isInstantAppInstallerComponent(any());
         doReturn(null).when(mMockPackageManager).resolveIntent(any(), any(), anyLong(), anyLong(),
-                anyInt(), anyBoolean(), anyInt());
-        doReturn(null).when(mMockPackageManager).resolveIntentExported(any(), any(),
-                anyLong(), anyLong(), anyInt(), anyBoolean(), anyInt(), anyInt());
+                anyInt(), anyBoolean(), anyInt(), anyInt());
         doReturn(new ComponentName("", "")).when(mMockPackageManager).getSystemUiServiceComponent();
 
         // Never review permissions
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 87395a1..417ee6b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -1343,6 +1343,27 @@
         assertEquals(mAppWindow, mDisplayContent.computeImeControlTarget());
     }
 
+    @SetupWindows(addWindows = W_ACTIVITY)
+    @Test
+    public void testShouldImeAttachedToApp_targetBoundsDifferentFromImeContainer_returnsFalse()
+            throws Exception {
+        Rect imeContainerBounds = new Rect(0, 0, 100, 100);
+        Rect imeTargetBounds = new Rect(0, 0, 100, 200);
+        spyOn(mAppWindow);
+        spyOn(mAppWindow.mActivityRecord);
+        doReturn(imeTargetBounds).when(mAppWindow).getBounds();
+        doReturn(true).when(mAppWindow.mActivityRecord).matchParentBounds();
+        mDisplayContent.setImeInputTarget(mAppWindow);
+        mDisplayContent.setImeLayeringTarget(
+                mDisplayContent.getImeInputTarget().getWindowState());
+        mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController());
+        final DisplayArea.Tokens imeContainer = mDisplayContent.getImeContainer();
+        spyOn(imeContainer);
+        doReturn(imeContainerBounds).when(imeContainer).getBounds();
+
+        assertFalse(mDisplayContent.shouldImeAttachedToApp());
+    }
+
     @Test
     public void testUpdateSystemGestureExclusion() throws Exception {
         final DisplayContent dc = createNewDisplay();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 7756edd..d88871c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -906,6 +906,24 @@
     }
 
     /**
+     * Tests whether home can be started if it's not allowed by policy.
+     */
+    @Test
+    public void testCanStartHome_returnsFalse_ifDisallowedByPolicy() {
+        final ActivityInfo info = new ActivityInfo();
+        info.applicationInfo = new ApplicationInfo();
+        final WindowProcessController app = mock(WindowProcessController.class);
+        doReturn(app).when(mAtm).getProcessController(any(), anyInt());
+        doReturn(false).when(app).isInstrumenting();
+        final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
+        doReturn(false).when(taskDisplayArea).canHostHomeTask();
+
+        assertFalse(mRootWindowContainer.canStartHomeOnDisplayArea(info, taskDisplayArea,
+                false /* allowInstrumenting*/));
+    }
+
+
+    /**
      * Tests that secondary home activity should not be resolved if device is still locked.
      */
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index fb854c5..ab4deca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -31,6 +31,7 @@
 import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
 import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -1455,6 +1456,53 @@
     }
 
     @Test
+    public void testReorderWithParents() {
+        /*
+                  root
+               ____|______
+               |         |
+           firstTda    secondTda
+               |             |
+         firstRootTask    secondRootTask
+
+         */
+        final TaskDisplayArea firstTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
+        final TaskDisplayArea secondTaskDisplayArea = createTaskDisplayArea(
+                mDisplayContent, mRootWindowContainer.mWmService, "TestTaskDisplayArea",
+                FEATURE_VENDOR_FIRST);
+        final Task firstRootTask = firstTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final Task secondRootTask = secondTaskDisplayArea.createRootTask(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final ActivityRecord firstActivity = new ActivityBuilder(mAtm)
+                .setTask(firstRootTask).build();
+        final ActivityRecord secondActivity = new ActivityBuilder(mAtm)
+                .setTask(secondRootTask).build();
+        // This assertion is just a defense to ensure that firstRootTask is not the top most
+        // by default
+        assertThat(mDisplayContent.getTopRootTask()).isEqualTo(secondRootTask);
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+
+        // Reorder to top
+        wct.reorder(firstRootTask.mRemoteToken.toWindowContainerToken(), true /* onTop */,
+                true /* includingParents */);
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
+
+        // firstRootTask can only be on the top if its TDA was also reordered to the Top which
+        // in-turn ensures that the reorder happened including the parents.
+        assertThat(mDisplayContent.getTopRootTask()).isEqualTo(firstRootTask);
+
+        // Reorder to bottom
+        wct.reorder(firstRootTask.mRemoteToken.toWindowContainerToken(), false /* onTop */,
+                true /* includingParents */);
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
+
+        // firstRootTask can only be on the bottom if its TDA was also reordered to the bottom
+        // which in-turn ensures that the reorder happened including the parents.
+        assertThat(mDisplayContent.getBottomMostTask()).isEqualTo(firstRootTask);
+    }
+
+    @Test
     public void testAppearDeferThenVanish() {
         final ITaskOrganizer organizer = registerMockOrganizer();
         final Task rootTask = createRootTask();
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 2e93cba..27c383c 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -403,7 +403,9 @@
 
         mAppStandby.addListener(mStandbyChangeListener);
 
-        mPackageMonitor.register(getContext(), null, UserHandle.ALL, true);
+        mPackageMonitor.register(getContext(),
+                /* thread= */ USE_DEDICATED_HANDLER_THREAD ? mHandler.getLooper() : null,
+                UserHandle.ALL, true);
 
         IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
         filter.addAction(Intent.ACTION_USER_STARTED);
diff --git a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
index f5688bf..7356cdc 100644
--- a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
+++ b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java
@@ -83,7 +83,7 @@
         // Check SDK version of the vendor partition.
         final int vendorApiLevel = SystemProperties.getInt(
                 "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT);
-        if (vendorApiLevel < Build.VERSION_CODES.VANILLA_ICE_CREAM) return true;
+        if (vendorApiLevel < Build.VENDOR_API_2024_Q2) return true;
 
         // Check SDK version of the client app.
         if (!Compatibility.isChangeEnabled(ENABLE_CHECKING_TELEPHONY_FEATURES)) return true;
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 7d845a3..9af73ea 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -3381,4 +3381,13 @@
      * @return {@code true} if the boolean config is set successfully, {@code false} otherwise.
      */
     boolean setDatagramControllerBooleanConfig(boolean reset, int booleanType, boolean enable);
+
+    /**
+     * This API can be used by only CTS to set the cache whether satellite communication is allowed.
+     *
+     * @param state a state indicates whether satellite access allowed state should be cached and
+     * the allowed state.
+     * @return {@code true} if the setting is successful, {@code false} otherwise.
+     */
+    boolean setIsSatelliteCommunicationAllowedForCurrentLocationCache(in String state);
 }
diff --git a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
index 5cdfb28..5a27593 100644
--- a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
@@ -393,5 +393,10 @@
             this.mLogToLogcat = logToLogcat;
         }
 
+        @Override
+        public int getId() {
+            return ordinal();
+        }
+
     }
 }
diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
index f6ac080..1d7b6b3 100644
--- a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
@@ -725,5 +725,10 @@
             this.mLogToLogcat = logToLogcat;
         }
 
+        @Override
+        public int getId() {
+            return ordinal();
+        }
+
     }
 }
diff --git a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
index 4267c2c..60456f9 100644
--- a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
@@ -174,5 +174,10 @@
             this.mLogToLogcat = logToLogcat;
         }
 
+        @Override
+        public int getId() {
+            return ordinal();
+        }
+
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
index 97304cb..d2326d1 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
@@ -21,7 +21,9 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -76,6 +78,43 @@
         }
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null || obj.getClass() != this.getClass()) {
+            return false;
+        }
+        DataType objAsDataType = (DataType) obj;
+        return Objects.equals(this.mDataTypeName, objAsDataType.mDataTypeName)
+                && Objects.equals(
+                        new HashSet<>(this.mPurposes), new HashSet<>(objAsDataType.mPurposes))
+                && Objects.equals(this.mIsCollectionOptional, objAsDataType.mIsCollectionOptional)
+                && Objects.equals(this.mIsSharingOptional, objAsDataType.mIsSharingOptional)
+                && Objects.equals(this.mEphemeral, objAsDataType.mEphemeral);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 1;
+        int prime = 31;
+        result =
+                (prime * result) + (this.mDataTypeName != null ? this.mDataTypeName.hashCode() : 0);
+        result =
+                (prime * result)
+                        + (this.mPurposes != null ? new HashSet<>(this.mPurposes).hashCode() : 0);
+        result =
+                (prime * result)
+                        + (this.mIsCollectionOptional != null
+                                ? this.mIsCollectionOptional.hashCode()
+                                : 0);
+        result =
+                (prime * result)
+                        + (this.mIsSharingOptional != null
+                                ? this.mIsSharingOptional.hashCode()
+                                : 0);
+        result = (prime * result) + (this.mEphemeral != null ? this.mEphemeral.hashCode() : 0);
+        return result;
+    }
+
     private final String mDataTypeName;
 
     private final List<Purpose> mPurposes;
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
index 54c80f6..f156484 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
@@ -20,6 +20,7 @@
 import com.android.asllib.marshallable.AppInfoTest;
 import com.android.asllib.marshallable.DataCategoryTest;
 import com.android.asllib.marshallable.DataLabelsTest;
+import com.android.asllib.marshallable.DataTypeEqualityTest;
 import com.android.asllib.marshallable.DeveloperInfoTest;
 import com.android.asllib.marshallable.SafetyLabelsTest;
 import com.android.asllib.marshallable.SecurityLabelsTest;
@@ -37,6 +38,7 @@
     AppInfoTest.class,
     DataCategoryTest.class,
     DataLabelsTest.class,
+    DataTypeEqualityTest.class,
     DeveloperInfoTest.class,
     SafetyLabelsTest.class,
     SecurityLabelsTest.class,
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataTypeEqualityTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataTypeEqualityTest.java
new file mode 100644
index 0000000..da7f287
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataTypeEqualityTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@RunWith(JUnit4.class)
+public class DataTypeEqualityTest {
+
+    public static final List<String> OPTIONAL_FIELD_NAMES =
+            List.of("isDataDeletable", "isDataEncrypted");
+    public static final List<String> OPTIONAL_FIELD_NAMES_OD =
+            List.of("is_data_deletable", "is_data_encrypted");
+
+    /** Logic for setting up tests (empty if not yet needed). */
+    public static void main(String[] params) throws Exception {}
+
+    @Before
+    public void setUp() throws Exception {
+        System.out.println("set up.");
+    }
+
+    /** Test for equality different order. */
+    @Test
+    public void testEqualityDifferentOrder() throws Exception {
+        System.out.println("starting testEqualityDifferentOrder.");
+        DataType dataType1 =
+                new DataType(
+                        "datatype1",
+                        Arrays.asList(
+                                DataType.Purpose.ADVERTISING, DataType.Purpose.PERSONALIZATION),
+                        true,
+                        false,
+                        null);
+        DataType dataType2 =
+                new DataType(
+                        "datatype1",
+                        Arrays.asList(
+                                DataType.Purpose.PERSONALIZATION, DataType.Purpose.ADVERTISING),
+                        true,
+                        false,
+                        null);
+        assertEquals(dataType1, dataType2);
+        assertEquals(dataType2, dataType1);
+    }
+
+    /** Test for contains different order. */
+    @Test
+    public void testContainsDifferentOrder() throws Exception {
+        System.out.println("starting testContainsDifferentOrder.");
+        DataType dataType1 =
+                new DataType(
+                        "datatype1",
+                        Arrays.asList(
+                                DataType.Purpose.ADVERTISING, DataType.Purpose.PERSONALIZATION),
+                        true,
+                        false,
+                        null);
+        DataType dataType2 =
+                new DataType(
+                        "datatype1",
+                        Arrays.asList(
+                                DataType.Purpose.PERSONALIZATION, DataType.Purpose.ADVERTISING),
+                        true,
+                        false,
+                        null);
+        Set<DataType> set = new HashSet<>();
+        set.add(dataType1);
+        assertTrue(set.contains(dataType2));
+    }
+
+    /** Test for inequality. */
+    @Test
+    public void testInequality() throws Exception {
+        System.out.println("starting testInequality.");
+        DataType dataType1 =
+                new DataType(
+                        "datatype1",
+                        Arrays.asList(
+                                DataType.Purpose.ADVERTISING, DataType.Purpose.PERSONALIZATION),
+                        true,
+                        false,
+                        null);
+        DataType dataType2 =
+                new DataType(
+                        "datatype1",
+                        Arrays.asList(DataType.Purpose.PERSONALIZATION),
+                        true,
+                        false,
+                        null);
+        assertNotEquals(dataType1, dataType2);
+        assertNotEquals(dataType2, dataType1);
+    }
+
+    /** Test for inequality bool. */
+    @Test
+    public void testInequalityBool() throws Exception {
+        System.out.println("starting testInequalityBool.");
+        DataType dataType1 =
+                new DataType(
+                        "datatype1",
+                        Arrays.asList(
+                                DataType.Purpose.ADVERTISING, DataType.Purpose.PERSONALIZATION),
+                        true,
+                        false,
+                        null);
+        DataType dataType2 =
+                new DataType(
+                        "datatype1",
+                        Arrays.asList(
+                                DataType.Purpose.ADVERTISING, DataType.Purpose.PERSONALIZATION),
+                        true,
+                        false,
+                        true);
+        assertNotEquals(dataType1, dataType2);
+        assertNotEquals(dataType2, dataType1);
+    }
+
+    /** Test for does not contain. */
+    @Test
+    public void testDoesNotContain() throws Exception {
+        System.out.println("starting testDoesNotContain.");
+        System.out.println("starting testContainsDifferentOrder.");
+        DataType dataType1 =
+                new DataType(
+                        "datatype1",
+                        Arrays.asList(
+                                DataType.Purpose.ADVERTISING, DataType.Purpose.PERSONALIZATION),
+                        true,
+                        false,
+                        null);
+        DataType dataType2 =
+                new DataType(
+                        "datatype1",
+                        Arrays.asList(DataType.Purpose.PERSONALIZATION),
+                        true,
+                        false,
+                        null);
+        Set<DataType> set = new HashSet<>();
+        set.add(dataType1);
+        assertFalse(set.contains(dataType2));
+    }
+}