Merge "[30/n] Encapsulate rounded corners logic in AppCompatRoundedCorners" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 4e34b63..59a7cbc 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -21,6 +21,7 @@
         // !!! KEEP THIS LIST ALPHABETICAL !!!
         "aconfig_mediacodec_flags_java_lib",
         "android.adaptiveauth.flags-aconfig-java",
+        "android.app.appfunctions.flags-aconfig-java",
         "android.app.contextualsearch.flags-aconfig-java",
         "android.app.flags-aconfig-java",
         "android.app.ondeviceintelligence-aconfig-java",
@@ -1383,6 +1384,21 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+// AppFunctions
+aconfig_declarations {
+    name: "android.app.appfunctions.flags-aconfig",
+    exportable: true,
+    package: "android.app.appfunctions.flags",
+    container: "system",
+    srcs: ["core/java/android/app/appfunctions/flags/flags.aconfig"],
+}
+
+java_aconfig_library {
+    name: "android.app.appfunctions.flags-aconfig-java",
+    aconfig_declarations: "android.app.appfunctions.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
 // Adaptive Auth
 aconfig_declarations {
     name: "android.adaptiveauth.flags-aconfig",
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index ba66ff7..d61439c 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -357,6 +357,7 @@
     }
 
     // TODO(b/172085676): Move inside alarm store.
+    @GuardedBy("mLock")
     private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
             new SparseArray<>();
     private final SparseArray<AlarmManager.AlarmClockInfo> mTmpSparseAlarmClockArray =
@@ -2616,6 +2617,13 @@
                 mInFlightListeners.add(callback);
             }
         }
+
+        /** @see AlarmManagerInternal#getNextAlarmTriggerTimeForUser(int) */
+        @Override
+        public long getNextAlarmTriggerTimeForUser(@UserIdInt int userId) {
+            final AlarmManager.AlarmClockInfo nextAlarm = getNextAlarmClockImpl(userId);
+            return nextAlarm != null ? nextAlarm.getTriggerTime() : 0;
+        }
     }
 
     boolean hasUseExactAlarmInternal(String packageName, int uid) {
diff --git a/core/api/current.txt b/core/api/current.txt
index ea039a7..36c91758 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -10684,6 +10684,7 @@
     field public static final String ACTIVITY_SERVICE = "activity";
     field public static final String ALARM_SERVICE = "alarm";
     field public static final String APPWIDGET_SERVICE = "appwidget";
+    field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final String APP_FUNCTION_SERVICE = "app_function";
     field public static final String APP_OPS_SERVICE = "appops";
     field public static final String APP_SEARCH_SERVICE = "app_search";
     field public static final String AUDIO_SERVICE = "audio";
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index e73f471..114a2c4 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import static android.app.appfunctions.flags.Flags.enableAppFunctionManager;
+
 import android.accounts.AccountManager;
 import android.accounts.IAccountManager;
 import android.adservices.AdServicesFrameworkInitializer;
@@ -28,6 +30,8 @@
 import android.app.admin.IDevicePolicyManager;
 import android.app.ambientcontext.AmbientContextManager;
 import android.app.ambientcontext.IAmbientContextManager;
+import android.app.appfunctions.AppFunctionManager;
+import android.app.appfunctions.IAppFunctionManager;
 import android.app.appsearch.AppSearchManagerFrameworkInitializer;
 import android.app.blob.BlobStoreManagerFrameworkInitializer;
 import android.app.contentsuggestions.ContentSuggestionsManager;
@@ -925,6 +929,21 @@
                 return new CompanionDeviceManager(service, ctx.getOuterContext());
             }});
 
+        if (enableAppFunctionManager()) {
+            registerService(Context.APP_FUNCTION_SERVICE, AppFunctionManager.class,
+                    new CachedServiceFetcher<>() {
+                        @Override
+                        public AppFunctionManager createService(ContextImpl ctx)
+                                throws ServiceNotFoundException {
+                            IAppFunctionManager service;
+                            //TODO(b/357551503): If the feature not present avoid look up every time
+                            service = IAppFunctionManager.Stub.asInterface(
+                                    ServiceManager.getServiceOrThrow(Context.APP_FUNCTION_SERVICE));
+                            return new AppFunctionManager(service, ctx.getOuterContext());
+                        }
+                    });
+        }
+
         registerService(Context.VIRTUAL_DEVICE_SERVICE, VirtualDeviceManager.class,
                 new CachedServiceFetcher<VirtualDeviceManager>() {
             @Override
diff --git a/core/java/android/app/appfunctions/AppFunctionManager.java b/core/java/android/app/appfunctions/AppFunctionManager.java
new file mode 100644
index 0000000..a01e373
--- /dev/null
+++ b/core/java/android/app/appfunctions/AppFunctionManager.java
@@ -0,0 +1,44 @@
+/*
+ * 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 android.app.appfunctions;
+
+import android.annotation.SystemService;
+import android.content.Context;
+
+/**
+ * Provides app functions related functionalities.
+ *
+ * <p>App function is a specific piece of functionality that an app offers to the system. These
+ * functionalities can be integrated into various system features.
+ *
+ * @hide
+ */
+@SystemService(Context.APP_FUNCTION_SERVICE)
+public final class AppFunctionManager {
+    private final IAppFunctionManager mService;
+    private final Context mContext;
+
+    /**
+     * TODO(b/357551503): add comments when implement this class
+     *
+     * @hide
+     */
+    public AppFunctionManager(IAppFunctionManager mService, Context context) {
+        this.mService = mService;
+        this.mContext = context;
+    }
+}
diff --git a/core/java/android/app/appfunctions/IAppFunctionManager.aidl b/core/java/android/app/appfunctions/IAppFunctionManager.aidl
new file mode 100644
index 0000000..018bc75
--- /dev/null
+++ b/core/java/android/app/appfunctions/IAppFunctionManager.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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 android.app.appfunctions;
+
+/**
+* Interface between an app and the server implementation service (AppFunctionManagerService).
+* @hide
+*/
+oneway interface IAppFunctionManager {
+}
\ No newline at end of file
diff --git a/core/java/android/app/appfunctions/flags/flags.aconfig b/core/java/android/app/appfunctions/flags/flags.aconfig
new file mode 100644
index 0000000..367effc
--- /dev/null
+++ b/core/java/android/app/appfunctions/flags/flags.aconfig
@@ -0,0 +1,11 @@
+package: "android.app.appfunctions.flags"
+container: "system"
+
+flag {
+    name: "enable_app_function_manager"
+    is_exported: true
+    is_fixed_read_only: true
+    namespace: "machine_learning"
+    description: "This flag the new App Function manager system service."
+    bug: "357551503"
+}
\ No newline at end of file
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9aebfc8..9dccc9a 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -16,6 +16,7 @@
 
 package android.content;
 
+import static android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER;
 import static android.content.flags.Flags.FLAG_ENABLE_BIND_PACKAGE_ISOLATED_PROCESS;
 
 import android.annotation.AttrRes;
@@ -51,6 +52,7 @@
 import android.app.IServiceConnection;
 import android.app.VrManager;
 import android.app.ambientcontext.AmbientContextManager;
+import android.app.appfunctions.AppFunctionManager;
 import android.app.people.PeopleManager;
 import android.app.time.TimeManager;
 import android.companion.virtual.VirtualDeviceManager;
@@ -6310,6 +6312,16 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve an
+     * {@link AppFunctionManager} for
+     * executing app functions.
+     *
+     * @see #getSystemService(String)
+     */
+    @FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER)
+    public static final String APP_FUNCTION_SERVICE = "app_function";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve an
      * {@link android.content.integrity.AppIntegrityManager}.
      * @hide
      */
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index de39847..ff737a4 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -58,8 +58,6 @@
 import static android.view.inputmethod.Flags.ctrlShiftShortcut;
 import static android.view.inputmethod.Flags.predictiveBackIme;
 
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
 import android.annotation.AnyThread;
 import android.annotation.CallSuper;
 import android.annotation.DrawableRes;
@@ -500,36 +498,53 @@
     public static final int BACK_DISPOSITION_ADJUST_NOTHING = 3;
 
     /**
-     * Enum flag to be used for {@link #setBackDisposition(int)}.
+     * The disposition mode that indicates the expected affordance for the back button.
      *
      * @hide
      */
-    @Retention(SOURCE)
-    @IntDef(value = {BACK_DISPOSITION_DEFAULT, BACK_DISPOSITION_WILL_NOT_DISMISS,
-            BACK_DISPOSITION_WILL_DISMISS, BACK_DISPOSITION_ADJUST_NOTHING},
-            prefix = "BACK_DISPOSITION_")
+    @IntDef(prefix = { "BACK_DISPOSITION_" }, value = {
+            BACK_DISPOSITION_DEFAULT,
+            BACK_DISPOSITION_WILL_NOT_DISMISS,
+            BACK_DISPOSITION_WILL_DISMISS,
+            BACK_DISPOSITION_ADJUST_NOTHING,
+    })
+    @Retention(RetentionPolicy.SOURCE)
     public @interface BackDispositionMode {}
 
     /**
+     * The IME is active, and ready to accept touch/key events. It may or may not be visible.
+     *
      * @hide
-     * The IME is active.  It may or may not be visible.
      */
-    public static final int IME_ACTIVE = 0x1;
+    public static final int IME_ACTIVE = 1 << 0;
 
     /**
-     * @hide
      * The IME is perceptibly visible to the user.
+     *
+     * @hide
      */
-    public static final int IME_VISIBLE = 0x2;
+    public static final int IME_VISIBLE = 1 << 1;
 
     /**
-     * @hide
      * The IME is visible, but not yet perceptible to the user (e.g. fading in)
      * by {@link android.view.WindowInsetsController}.
      *
      * @see InputMethodManager#reportPerceptible
+     * @hide
      */
-    public static final int IME_VISIBLE_IMPERCEPTIBLE = 0x4;
+    public static final int IME_VISIBLE_IMPERCEPTIBLE = 1 << 2;
+
+    /**
+     * The IME window visibility state.
+     *
+     * @hide
+     */
+    @IntDef(flag = true, prefix = { "IME_" }, value = {
+            IME_ACTIVE,
+            IME_VISIBLE,
+            IME_VISIBLE_IMPERCEPTIBLE,
+    })
+    public @interface ImeWindowVisibility {}
 
     // Min and max values for back disposition.
     private static final int BACK_DISPOSITION_MIN = BACK_DISPOSITION_DEFAULT;
@@ -1342,7 +1357,8 @@
         mImeSurfaceRemoverRunnable = null;
     }
 
-    private void setImeWindowStatus(int visibilityFlags, int backDisposition) {
+    private void setImeWindowStatus(@ImeWindowVisibility int visibilityFlags,
+            @BackDispositionMode int backDisposition) {
         mPrivOps.setImeWindowStatusAsync(visibilityFlags, backDisposition);
     }
 
@@ -3301,7 +3317,7 @@
         ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_IME_HIDE_WINDOW);
         ImeTracing.getInstance().triggerServiceDump("InputMethodService#hideWindow", mDumper,
                 null /* icProto */);
-        setImeWindowStatus(0, mBackDisposition);
+        setImeWindowStatus(0 /* visibilityFlags */, mBackDisposition);
         if (android.view.inputmethod.Flags.refactorInsetsController()) {
             // The ImeInsetsSourceProvider need the statsToken when dispatching the control. We
             // send the token here, so that another request in the provider can be cancelled.
@@ -4476,6 +4492,7 @@
         };
     }
 
+    @ImeWindowVisibility
     private int mapToImeWindowStatus() {
         return IME_ACTIVE
                 | (isInputViewShown() ? IME_VISIBLE : 0);
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 06e53ac..133b3d1 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -267,10 +267,10 @@
     private boolean mDozing;
     private boolean mWindowless;
     private boolean mPreviewMode;
-    private volatile int mDozeScreenState = Display.STATE_UNKNOWN;
-    private volatile @Display.StateReason int mDozeScreenStateReason = Display.STATE_REASON_UNKNOWN;
-    private volatile int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
-    private volatile float mDozeScreenBrightnessFloat = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+    private int mDozeScreenState = Display.STATE_UNKNOWN;
+    private @Display.StateReason int mDozeScreenStateReason = Display.STATE_REASON_UNKNOWN;
+    private int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
+    private float mDozeScreenBrightnessFloat = PowerManager.BRIGHTNESS_INVALID_FLOAT;
 
     private boolean mDebug = false;
 
@@ -913,13 +913,15 @@
      */
     @UnsupportedAppUsage
     public void startDozing() {
-        if (mCanDoze && !mDozing) {
-            mDozing = true;
-            updateDoze();
+        synchronized (this) {
+            if (mCanDoze && !mDozing) {
+                mDozing = true;
+                updateDoze();
+            }
         }
     }
 
-    private void updateDoze() {
+    private synchronized void updateDoze() {
         if (mDreamToken == null) {
             Slog.w(mTag, "Updating doze without a dream token.");
             return;
@@ -927,6 +929,9 @@
 
         if (mDozing) {
             try {
+                Slog.v(mTag, "UpdateDoze mDozeScreenState=" + mDozeScreenState
+                        + " mDozeScreenBrightness=" + mDozeScreenBrightness
+                        + " mDozeScreenBrightnessFloat=" + mDozeScreenBrightnessFloat);
                 if (startAndStopDozingInBackground()) {
                     mDreamManager.startDozingOneway(
                             mDreamToken, mDozeScreenState, mDozeScreenStateReason,
@@ -1048,10 +1053,12 @@
      */
     @UnsupportedAppUsage
     public void setDozeScreenState(int state, @Display.StateReason int reason) {
-        if (mDozeScreenState != state) {
-            mDozeScreenState = state;
-            mDozeScreenStateReason = reason;
-            updateDoze();
+        synchronized (this) {
+            if (mDozeScreenState != state) {
+                mDozeScreenState = state;
+                mDozeScreenStateReason = reason;
+                updateDoze();
+            }
         }
     }
 
@@ -1103,9 +1110,11 @@
         if (brightness != PowerManager.BRIGHTNESS_DEFAULT) {
             brightness = clampAbsoluteBrightness(brightness);
         }
-        if (mDozeScreenBrightness != brightness) {
-            mDozeScreenBrightness = brightness;
-            updateDoze();
+        synchronized (this) {
+            if (mDozeScreenBrightness != brightness) {
+                mDozeScreenBrightness = brightness;
+                updateDoze();
+            }
         }
     }
 
@@ -1141,9 +1150,12 @@
         if (!Float.isNaN(brightness)) {
             brightness = clampAbsoluteBrightnessFloat(brightness);
         }
-        if (!BrightnessSynchronizer.floatEquals(mDozeScreenBrightnessFloat, brightness)) {
-            mDozeScreenBrightnessFloat = brightness;
-            updateDoze();
+
+        synchronized (this) {
+            if (!BrightnessSynchronizer.floatEquals(mDozeScreenBrightnessFloat, brightness)) {
+                mDozeScreenBrightnessFloat = brightness;
+                updateDoze();
+            }
         }
     }
 
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index 09306c7..288be9c 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -28,6 +28,7 @@
 import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.util.TypedValue;
+import android.view.WindowInsets;
 
 import dalvik.system.CloseGuard;
 
@@ -881,12 +882,13 @@
     }
 
     /**
-     * @return if a window animation has outsets applied to it.
+     * @return the edges to which outsets should be applied if run as a windoow animation.
      *
      * @hide
      */
-    public boolean hasExtension() {
-        return false;
+    @WindowInsets.Side.InsetsSide
+    public int getExtensionEdges() {
+        return 0x0;
     }
 
     /**
diff --git a/core/java/android/view/animation/AnimationSet.java b/core/java/android/view/animation/AnimationSet.java
index 5aaa994..bbdc9d0 100644
--- a/core/java/android/view/animation/AnimationSet.java
+++ b/core/java/android/view/animation/AnimationSet.java
@@ -21,6 +21,7 @@
 import android.graphics.RectF;
 import android.os.Build;
 import android.util.AttributeSet;
+import android.view.WindowInsets;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -540,12 +541,12 @@
 
     /** @hide */
     @Override
-    public boolean hasExtension() {
+    @WindowInsets.Side.InsetsSide
+    public int getExtensionEdges() {
+        int edge = 0x0;
         for (Animation animation : mAnimations) {
-            if (animation.hasExtension()) {
-                return true;
-            }
+            edge |= animation.getExtensionEdges();
         }
-        return false;
+        return edge;
     }
 }
diff --git a/core/java/android/view/animation/ExtendAnimation.java b/core/java/android/view/animation/ExtendAnimation.java
index 210eb8a..1aeee07 100644
--- a/core/java/android/view/animation/ExtendAnimation.java
+++ b/core/java/android/view/animation/ExtendAnimation.java
@@ -20,6 +20,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Insets;
 import android.util.AttributeSet;
+import android.view.WindowInsets;
 
 /**
  * An animation that controls the outset of an object.
@@ -151,9 +152,12 @@
 
     /** @hide */
     @Override
-    public boolean hasExtension() {
-        return mFromInsets.left < 0 || mFromInsets.top < 0 || mFromInsets.right < 0
-                || mFromInsets.bottom < 0;
+    @WindowInsets.Side.InsetsSide
+    public int getExtensionEdges() {
+        return (mFromInsets.left < 0 || mToInsets.left < 0 ?  WindowInsets.Side.LEFT : 0)
+            | (mFromInsets.right < 0 || mToInsets.right < 0 ?  WindowInsets.Side.RIGHT : 0)
+            | (mFromInsets.top < 0 || mToInsets.top < 0 ?  WindowInsets.Side.TOP : 0)
+            | (mFromInsets.bottom < 0 || mToInsets.bottom < 0 ? WindowInsets.Side.BOTTOM : 0);
     }
 
     @Override
diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
index 921363c..b009c99 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
@@ -20,6 +20,8 @@
 import android.annotation.DrawableRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.inputmethodservice.InputMethodService.BackDispositionMode;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.net.Uri;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -106,13 +108,10 @@
      *
      * @param vis visibility flags
      * @param backDisposition disposition flags
-     * @see android.inputmethodservice.InputMethodService#IME_ACTIVE
-     * @see android.inputmethodservice.InputMethodService#IME_VISIBLE
-     * @see android.inputmethodservice.InputMethodService#BACK_DISPOSITION_DEFAULT
-     * @see android.inputmethodservice.InputMethodService#BACK_DISPOSITION_ADJUST_NOTHING
      */
     @AnyThread
-    public void setImeWindowStatusAsync(int vis, int backDisposition) {
+    public void setImeWindowStatusAsync(@ImeWindowVisibility int vis,
+            @BackDispositionMode int backDisposition) {
         final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
         if (ops == null) {
             return;
diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
index e0c90d8..cb20ceb 100644
--- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
@@ -33,6 +33,7 @@
 import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MESSAGES;
 import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.GROUP_ID;
 import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.LEVEL;
+import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.LOCATION;
 import static android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData.MESSAGE;
 import static android.internal.perfetto.protos.TracePacketOuterClass.TracePacket.INTERNED_DATA;
 import static android.internal.perfetto.protos.TracePacketOuterClass.TracePacket.PROTOLOG_MESSAGE;
@@ -449,6 +450,8 @@
                 case (int) GROUP_ID:
                     os.write(GROUP_ID, pis.readInt(GROUP_ID));
                     break;
+                case (int) LOCATION:
+                    os.write(LOCATION, pis.readInt(LOCATION));
                 default:
                     throw new RuntimeException(
                             "Unexpected field id " + pis.getFieldNumber());
diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
index 7240aff..3adc6b2 100644
--- a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
+++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.statusbar;
 
+import android.inputmethodservice.InputMethodService.BackDispositionMode;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArrayMap;
@@ -30,7 +32,9 @@
     public final int mDisabledFlags1;                   // switch[0]
     public final int mAppearance;                       // switch[1]
     public final AppearanceRegion[] mAppearanceRegions; // switch[2]
+    @ImeWindowVisibility
     public final int mImeWindowVis;                     // switch[3]
+    @BackDispositionMode
     public final int mImeBackDisposition;               // switch[4]
     public final boolean mShowImeSwitcher;              // switch[5]
     public final int mDisabledFlags2;                   // switch[6]
@@ -42,10 +46,11 @@
     public final LetterboxDetails[] mLetterboxDetails;
 
     public RegisterStatusBarResult(ArrayMap<String, StatusBarIcon> icons, int disabledFlags1,
-            int appearance, AppearanceRegion[] appearanceRegions, int imeWindowVis,
-            int imeBackDisposition, boolean showImeSwitcher, int disabledFlags2,
-            boolean navbarColorManagedByIme, int behavior, int requestedVisibleTypes,
-            String packageName, int transientBarTypes, LetterboxDetails[] letterboxDetails) {
+            int appearance, AppearanceRegion[] appearanceRegions,
+            @ImeWindowVisibility int imeWindowVis, @BackDispositionMode int imeBackDisposition,
+            boolean showImeSwitcher, int disabledFlags2, boolean navbarColorManagedByIme,
+            int behavior, int requestedVisibleTypes, String packageName, int transientBarTypes,
+            LetterboxDetails[] letterboxDetails) {
         mIcons = new ArrayMap<>(icons);
         mDisabledFlags1 = disabledFlags1;
         mAppearance = appearance;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
index 8d30db6..5355138 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
@@ -18,6 +18,7 @@
 
 import static android.graphics.Matrix.MTRANS_X;
 import static android.graphics.Matrix.MTRANS_Y;
+import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
 
 import android.annotation.CallSuper;
 import android.graphics.Point;
@@ -146,6 +147,14 @@
     /** To be overridden by subclasses to adjust the animation surface change. */
     void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) {
         // Update the surface position and alpha.
+        if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader()
+                && mAnimation.getExtensionEdges() != 0x0
+                && !(mChange.hasFlags(FLAG_TRANSLUCENT)
+                        && mChange.getActivityComponent() != null)) {
+            // Extend non-translucent activities
+            t.setEdgeExtensionEffect(mLeash, mAnimation.getExtensionEdges());
+        }
+
         mTransformation.getMatrix().postTranslate(mContentRelOffset.x, mContentRelOffset.y);
         t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix);
         t.setAlpha(mLeash, mTransformation.getAlpha());
@@ -165,7 +174,7 @@
         if (!cropRect.intersect(mWholeAnimationBounds)) {
             // Hide the surface when it is outside of the animation area.
             t.setAlpha(mLeash, 0);
-        } else if (mAnimation.hasExtension()) {
+        } else if (mAnimation.getExtensionEdges() != 0) {
             // Allow the surface to be shown in its original bounds in case we want to use edge
             // extensions.
             cropRect.union(mContentBounds);
@@ -180,6 +189,10 @@
     @CallSuper
     void onAnimationEnd(@NonNull SurfaceControl.Transaction t) {
         onAnimationUpdate(t, mAnimation.getDuration());
+        if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader()
+                && mAnimation.getExtensionEdges() != 0x0) {
+            t.setEdgeExtensionEffect(mLeash, /* edge */ 0);
+        }
     }
 
     final long getDurationHint() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index 5696a54..d2cef4b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -144,8 +144,10 @@
             // ending states.
             prepareForJumpCut(info, startTransaction);
         } else {
-            addEdgeExtensionIfNeeded(startTransaction, finishTransaction,
-                    postStartTransactionCallbacks, adapters);
+            if (!com.android.graphics.libgui.flags.Flags.edgeExtensionShader()) {
+                addEdgeExtensionIfNeeded(startTransaction, finishTransaction,
+                        postStartTransactionCallbacks, adapters);
+            }
             addBackgroundColorIfNeeded(info, startTransaction, finishTransaction, adapters);
             for (ActivityEmbeddingAnimationAdapter adapter : adapters) {
                 duration = Math.max(duration, adapter.getDurationHint());
@@ -341,7 +343,7 @@
             @NonNull List<ActivityEmbeddingAnimationAdapter> adapters) {
         for (ActivityEmbeddingAnimationAdapter adapter : adapters) {
             final Animation animation = adapter.mAnimation;
-            if (!animation.hasExtension()) {
+            if (animation.getExtensionEdges() == 0) {
                 continue;
             }
             if (adapter.mChange.hasFlags(FLAG_TRANSLUCENT)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index efa1031..f002d89 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -1601,6 +1601,11 @@
                 getResources().getColor(android.R.color.system_neutral1_1000)));
         mManageMenuScrim.setBackgroundDrawable(new ColorDrawable(
                 getResources().getColor(android.R.color.system_neutral1_1000)));
+        if (mShowingManage) {
+            // the manage menu location depends on the manage button location which may need a
+            // layout pass, so post this to the looper
+            post(() -> showManageMenu(true));
+        }
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
index 73aa7ce..a6ed3b8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
@@ -22,6 +22,7 @@
 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
 import android.content.Context
 import android.os.IBinder
+import android.os.Trace
 import android.util.SparseArray
 import android.view.SurfaceControl
 import android.view.WindowManager
@@ -51,6 +52,8 @@
 import com.android.wm.shell.sysui.ShellInit
 import com.android.wm.shell.transition.Transitions
 
+const val VISIBLE_TASKS_COUNTER_NAME = "DESKTOP_MODE_VISIBLE_TASKS"
+
 /**
  * A [Transitions.TransitionObserver] that observes transitions and the proposed changes to log
  * appropriate desktop mode session log events. This observes transitions related to desktop mode
@@ -292,8 +295,14 @@
             val previousTaskInfo = preTransitionVisibleFreeformTasks[taskId]
             when {
                 // new tasks added
-                previousTaskInfo == null ->
+                previousTaskInfo == null -> {
                     desktopModeEventLogger.logTaskAdded(sessionId, currentTaskUpdate)
+                    Trace.setCounter(
+                        Trace.TRACE_TAG_WINDOW_MANAGER,
+                        VISIBLE_TASKS_COUNTER_NAME,
+                        postTransitionVisibleFreeformTasks.size().toLong()
+                    )
+                }
                 // old tasks that were resized or repositioned
                 // TODO(b/347935387): Log changes only once they are stable.
                 buildTaskUpdateForTask(previousTaskInfo) != currentTaskUpdate ->
@@ -305,6 +314,11 @@
         preTransitionVisibleFreeformTasks.forEach { taskId, taskInfo ->
             if (!postTransitionVisibleFreeformTasks.containsKey(taskId)) {
                 desktopModeEventLogger.logTaskRemoved(sessionId, buildTaskUpdateForTask(taskInfo))
+                Trace.setCounter(
+                    Trace.TRACE_TAG_WINDOW_MANAGER,
+                    VISIBLE_TASKS_COUNTER_NAME,
+                    postTransitionVisibleFreeformTasks.size().toLong()
+                )
             }
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 7784784..de6887a2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -502,15 +502,19 @@
                 backgroundColorForTransition = getTransitionBackgroundColorIfSet(info, change, a,
                         backgroundColorForTransition);
 
-                if (!isTask && a.hasExtension()) {
-                    if (!TransitionUtil.isOpeningType(mode)) {
-                        // Can screenshot now (before startTransaction is applied)
-                        edgeExtendWindow(change, a, startTransaction, finishTransaction);
+                if (!isTask && a.getExtensionEdges() != 0x0) {
+                    if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader()) {
+                        finishTransaction.setEdgeExtensionEffect(change.getLeash(), /* edge */ 0);
                     } else {
-                        // Need to screenshot after startTransaction is applied otherwise activity
-                        // may not be visible or ready yet.
-                        postStartTransactionCallbacks
-                                .add(t -> edgeExtendWindow(change, a, t, finishTransaction));
+                        if (!TransitionUtil.isOpeningType(mode)) {
+                            // Can screenshot now (before startTransaction is applied)
+                            edgeExtendWindow(change, a, startTransaction, finishTransaction);
+                        } else {
+                            // Need to screenshot after startTransaction is applied otherwise
+                            // activity may not be visible or ready yet.
+                            postStartTransactionCallbacks
+                                    .add(t -> edgeExtendWindow(change, a, t, finishTransaction));
+                        }
                     }
                 }
 
@@ -558,7 +562,7 @@
 
                 buildSurfaceAnimation(animations, a, change.getLeash(), onAnimFinish,
                         mTransactionPool, mMainExecutor, animRelOffset, cornerRadius,
-                        clipRect);
+                        clipRect, change.getActivityComponent() != null);
 
                 final TransitionInfo.AnimationOptions options;
                 if (Flags.moveAnimationOptionsToChange()) {
@@ -823,7 +827,7 @@
             @NonNull Animation anim, @NonNull SurfaceControl leash,
             @NonNull Runnable finishCallback, @NonNull TransactionPool pool,
             @NonNull ShellExecutor mainExecutor, @Nullable Point position, float cornerRadius,
-            @Nullable Rect clipRect) {
+            @Nullable Rect clipRect, boolean isActivity) {
         final SurfaceControl.Transaction transaction = pool.acquire();
         final ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
         final Transformation transformation = new Transformation();
@@ -835,13 +839,13 @@
             final long currentPlayTime = Math.min(va.getDuration(), va.getCurrentPlayTime());
 
             applyTransformation(currentPlayTime, transaction, leash, anim, transformation, matrix,
-                    position, cornerRadius, clipRect);
+                    position, cornerRadius, clipRect, isActivity);
         };
         va.addUpdateListener(updateListener);
 
         final Runnable finisher = () -> {
             applyTransformation(va.getDuration(), transaction, leash, anim, transformation, matrix,
-                    position, cornerRadius, clipRect);
+                    position, cornerRadius, clipRect, isActivity);
 
             pool.release(transaction);
             mainExecutor.execute(() -> {
@@ -931,7 +935,8 @@
         a.restrictDuration(MAX_ANIMATION_DURATION);
         a.scaleCurrentDuration(mTransitionAnimationScaleSetting);
         buildSurfaceAnimation(animations, a, wt.getSurface(), finisher, mTransactionPool,
-                mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds());
+                mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds(),
+                change.getActivityComponent() != null);
     }
 
     private void attachThumbnailAnimation(@NonNull ArrayList<Animator> animations,
@@ -955,7 +960,8 @@
         a.restrictDuration(MAX_ANIMATION_DURATION);
         a.scaleCurrentDuration(mTransitionAnimationScaleSetting);
         buildSurfaceAnimation(animations, a, wt.getSurface(), finisher, mTransactionPool,
-                mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds());
+                mMainExecutor, change.getEndRelOffset(), cornerRadius, change.getEndAbsBounds(),
+                change.getActivityComponent() != null);
     }
 
     private static int getWallpaperTransitType(TransitionInfo info) {
@@ -1005,9 +1011,14 @@
 
     private static void applyTransformation(long time, SurfaceControl.Transaction t,
             SurfaceControl leash, Animation anim, Transformation tmpTransformation, float[] matrix,
-            Point position, float cornerRadius, @Nullable Rect immutableClipRect) {
+            Point position, float cornerRadius, @Nullable Rect immutableClipRect,
+            boolean isActivity) {
         tmpTransformation.clear();
         anim.getTransformation(time, tmpTransformation);
+        if (com.android.graphics.libgui.flags.Flags.edgeExtensionShader()
+                && anim.getExtensionEdges() != 0x0 && isActivity) {
+            t.setEdgeExtensionEffect(leash, anim.getExtensionEdges());
+        }
         if (position != null) {
             tmpTransformation.getMatrix().postTranslate(position.x, position.y);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
index e196254..1958825 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/ScreenRotationAnimation.java
@@ -325,21 +325,21 @@
             @NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) {
         buildSurfaceAnimation(animations, mRotateEnterAnimation, mSurfaceControl, finishCallback,
                 mTransactionPool, mainExecutor, null /* position */, 0 /* cornerRadius */,
-                null /* clipRect */);
+                null /* clipRect */, false /* isActivity */);
     }
 
     private void startScreenshotRotationAnimation(@NonNull ArrayList<Animator> animations,
             @NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) {
         buildSurfaceAnimation(animations, mRotateExitAnimation, mAnimLeash, finishCallback,
                 mTransactionPool, mainExecutor, null /* position */, 0 /* cornerRadius */,
-                null /* clipRect */);
+                null /* clipRect */, false /* isActivity */);
     }
 
     private void buildScreenshotAlphaAnimation(@NonNull ArrayList<Animator> animations,
             @NonNull Runnable finishCallback, @NonNull ShellExecutor mainExecutor) {
         buildSurfaceAnimation(animations, mRotateAlphaAnimation, mAnimLeash, finishCallback,
                 mTransactionPool, mainExecutor, null /* position */, 0 /* cornerRadius */,
-                null /* clipRect */);
+                null /* clipRect */, false /* isActivity */);
     }
 
     private void startColorAnimation(float animationScale, @NonNull ShellExecutor animExecutor) {
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/OWNERS b/libs/WindowManager/Shell/tests/e2e/desktopmode/OWNERS
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/OWNERS
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/OWNERS
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/Android.bp b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/Android.bp
new file mode 100644
index 0000000..50581f7
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/Android.bp
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+    name: "WMShellFlickerTestsDesktopMode",
+    defaults: ["WMShellFlickerTestsDefault"],
+    manifest: "AndroidManifest.xml",
+    test_config_template: "AndroidTestTemplate.xml",
+    srcs: ["src/**/*.kt"],
+    static_libs: [
+        "WMShellFlickerTestsBase",
+        "WMShellScenariosDesktopMode",
+        "WMShellTestUtils",
+    ],
+    data: ["trace_config/*"],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidManifest.xml
similarity index 95%
copy from libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml
copy to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidManifest.xml
index d54b694..1bbbefa 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidManifest.xml
@@ -16,7 +16,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
-          package="com.android.wm.shell.flicker.service">
+          package="com.android.wm.shell.flicker">
 
     <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
     <!-- Read and write traces from external storage -->
@@ -71,7 +71,7 @@
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.wm.shell.flicker.service"
-                     android:label="WindowManager Flicker Service Tests">
+                     android:targetPackage="com.android.wm.shell.flicker"
+                     android:label="WindowManager Shell Flicker Tests">
     </instrumentation>
 </manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidTestTemplate.xml
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidTestTemplate.xml
index a66dfb4..40dbbac 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/AndroidTestTemplate.xml
@@ -59,13 +59,6 @@
         <option name="test-file-name" value="{MODULE}.apk"/>
         <option name="test-file-name" value="FlickerTestApp.apk"/>
     </target_preparer>
-    <!-- Enable mocking GPS location by the test app -->
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-        <option name="run-command"
-                value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location allow"/>
-        <option name="teardown-command"
-                value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location deny"/>
-    </target_preparer>
 
     <!-- Needed for pushing the trace config file -->
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
@@ -97,7 +90,7 @@
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
         <option name="pull-pattern-keys" value="perfetto_file_path"/>
         <option name="directory-keys"
-                value="/data/user/0/com.android.wm.shell.flicker.service/files"/>
+                value="/data/user/0/com.android.wm.shell.flicker/files"/>
         <option name="collect-on-run-ended-only" value="true"/>
         <option name="clean-up" value="true"/>
     </metrics_collector>
diff --git a/libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/res/xml/network_security_config.xml
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/res/xml/network_security_config.xml
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/CloseAllAppWithAppHeaderExitLandscape.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppWithAppHeaderExitLandscape.kt
similarity index 80%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/CloseAllAppWithAppHeaderExitLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppWithAppHeaderExitLandscape.kt
index 5563bb9..b697d80 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/CloseAllAppWithAppHeaderExitLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppWithAppHeaderExitLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,9 +23,9 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_APP
-import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_LAST_APP
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.CloseAllAppsWithAppHeaderExit
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_APP
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_LAST_APP
+import com.android.wm.shell.scenarios.CloseAllAppsWithAppHeaderExit
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/CloseAllAppWithAppHeaderExitPortrait.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppWithAppHeaderExitPortrait.kt
similarity index 80%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/CloseAllAppWithAppHeaderExitPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppWithAppHeaderExitPortrait.kt
index 3d16d2219..a11e876 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/CloseAllAppWithAppHeaderExitPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppWithAppHeaderExitPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,9 +23,9 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_APP
-import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_LAST_APP
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.CloseAllAppsWithAppHeaderExit
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_APP
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_LAST_APP
+import com.android.wm.shell.scenarios.CloseAllAppsWithAppHeaderExit
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
similarity index 98%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
index 430f80b..8584b59 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.flicker.AssertionInvocationGroup
 import android.tools.flicker.assertors.assertions.AppLayerIsInvisibleAtEnd
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/EnterDesktopWithDragLandscape.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/EnterDesktopWithDragLandscape.kt
similarity index 84%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/EnterDesktopWithDragLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/EnterDesktopWithDragLandscape.kt
index 9dfafe9..f7b2556 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/EnterDesktopWithDragLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/EnterDesktopWithDragLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,8 +23,8 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.END_DRAG_TO_DESKTOP
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithDrag
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.END_DRAG_TO_DESKTOP
+import com.android.wm.shell.scenarios.EnterDesktopWithDrag
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/EnterDesktopWithDragPortrait.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/EnterDesktopWithDragPortrait.kt
similarity index 84%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/EnterDesktopWithDragPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/EnterDesktopWithDragPortrait.kt
index 1c7d623..f4bf0f9 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/EnterDesktopWithDragPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/EnterDesktopWithDragPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,8 +23,8 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.END_DRAG_TO_DESKTOP
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithDrag
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.END_DRAG_TO_DESKTOP
+import com.android.wm.shell.scenarios.EnterDesktopWithDrag
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppToMinimumWindowSizeLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppToMinimumWindowSizeLandscape.kt
index 6319cf7..45e5fdc 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppToMinimumWindowSizeLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,8 +23,8 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE
+import com.android.wm.shell.scenarios.ResizeAppWithCornerResize
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppToMinimumWindowSizePortrait.kt
similarity index 85%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppToMinimumWindowSizePortrait.kt
index 431f6e3..62a2571 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppToMinimumWindowSizePortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.flicker.FlickerConfig
 import android.tools.flicker.annotation.ExpectedScenarios
@@ -22,8 +22,8 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE
+import com.android.wm.shell.scenarios.ResizeAppWithCornerResize
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppWithCornerResizeLandscape.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithCornerResizeLandscape.kt
similarity index 84%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppWithCornerResizeLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithCornerResizeLandscape.kt
index 8d1a530..ea8b10b 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppWithCornerResizeLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithCornerResizeLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,8 +23,8 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE
+import com.android.wm.shell.scenarios.ResizeAppWithCornerResize
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppWithCornerResizePortrait.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithCornerResizePortrait.kt
similarity index 84%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppWithCornerResizePortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithCornerResizePortrait.kt
index 2d81c8c..d7bba6e 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppWithCornerResizePortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/ResizeAppWithCornerResizePortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,8 +23,8 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE
+import com.android.wm.shell.scenarios.ResizeAppWithCornerResize
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/trace_config/trace_config.textproto
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/trace_config/trace_config.textproto
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/Android.bp b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/Android.bp
new file mode 100644
index 0000000..4389f09
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/Android.bp
@@ -0,0 +1,46 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_library {
+    name: "WMShellScenariosDesktopMode",
+    platform_apis: true,
+    optimize: {
+        enabled: false,
+    },
+    srcs: ["src/**/*.kt"],
+    static_libs: [
+        "WMShellFlickerTestsBase",
+        "WMShellTestUtils",
+        "wm-shell-flicker-utils",
+        "androidx.test.ext.junit",
+        "flickertestapplib",
+        "flickerlib-helpers",
+        "flickerlib-trace_processor_shell",
+        "platform-test-annotations",
+        "wm-flicker-common-app-helpers",
+        "launcher-helper-lib",
+        "launcher-aosp-tapl",
+    ],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/CloseAllAppsWithAppHeaderExit.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseAllAppsWithAppHeaderExit.kt
similarity index 89%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/CloseAllAppsWithAppHeaderExit.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseAllAppsWithAppHeaderExit.kt
index e77a457..e9056f3 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/CloseAllAppsWithAppHeaderExit.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseAllAppsWithAppHeaderExit.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
+import android.platform.test.annotations.Postsubmit
 import android.app.Instrumentation
 import android.tools.NavBar
 import android.tools.Rotation
@@ -28,16 +29,18 @@
 import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.window.flags.Flags
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
 
-@Ignore("Base Test Class")
-abstract class CloseAllAppsWithAppHeaderExit
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class CloseAllAppsWithAppHeaderExit
 @JvmOverloads
 constructor(val rotation: Rotation = Rotation.ROTATION_0) {
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowMultiWindow.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindow.kt
similarity index 87%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowMultiWindow.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindow.kt
index bbf0ce5..ca1dc1a 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowMultiWindow.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindow.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
+import android.platform.test.annotations.Postsubmit
 import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
 import com.android.server.wm.flicker.helpers.ImeAppHelper
 import com.android.server.wm.flicker.helpers.MailAppHelper
@@ -25,12 +26,13 @@
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
 
-/** Base scenario test for window drag CUJ with multiple windows. */
-@Ignore("Base Test Class")
-abstract class DragAppWindowMultiWindow : DragAppWindowScenarioTestBase()
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class DragAppWindowMultiWindow : DragAppWindowScenarioTestBase()
 {
     private val imeAppHelper = ImeAppHelper(instrumentation)
     private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowScenarioTestBase.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowScenarioTestBase.kt
similarity index 93%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowScenarioTestBase.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowScenarioTestBase.kt
index a613ca1..7219287 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowScenarioTestBase.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowScenarioTestBase.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -24,7 +24,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowSingleWindow.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowSingleWindow.kt
similarity index 83%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowSingleWindow.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowSingleWindow.kt
index 0655620..91cfd17 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/DragAppWindowSingleWindow.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowSingleWindow.kt
@@ -14,20 +14,21 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
+import android.platform.test.annotations.Postsubmit
 import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.window.flags.Flags
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Test
-
-/** Base scenario test for window drag CUJ with single window. */
-@Ignore("Base Test Class")
-abstract class DragAppWindowSingleWindow : DragAppWindowScenarioTestBase()
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class DragAppWindowSingleWindow : DragAppWindowScenarioTestBase()
 {
     private val simpleAppHelper = SimpleAppHelper(instrumentation)
     private val testApp = DesktopModeAppHelper(simpleAppHelper)
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/EnterDesktopWithAppHandleMenu.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithAppHandleMenu.kt
similarity index 87%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/EnterDesktopWithAppHandleMenu.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithAppHandleMenu.kt
index 47a215a..1073050 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/EnterDesktopWithAppHandleMenu.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithAppHandleMenu.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
+import android.platform.test.annotations.Postsubmit
 import android.app.Instrumentation
 import android.tools.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
@@ -27,12 +28,12 @@
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Test
-
-/** Base test class for enter desktop with app handle menu CUJ. */
-@Ignore("Base Test Class")
-abstract class EnterDesktopWithAppHandleMenu {
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class EnterDesktopWithAppHandleMenu {
 
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
     private val tapl = LauncherInstrumentation()
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/EnterDesktopWithDrag.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
similarity index 87%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/EnterDesktopWithDrag.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
index fe139d2..0f0d2df 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/EnterDesktopWithDrag.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/EnterDesktopWithDrag.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
+import android.platform.test.annotations.Postsubmit
 import android.app.Instrumentation
 import android.tools.NavBar
 import android.tools.Rotation
@@ -26,17 +27,18 @@
 import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.window.flags.Flags
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
 
-
-@Ignore("Base Test Class")
-abstract class EnterDesktopWithDrag
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class EnterDesktopWithDrag
 @JvmOverloads
 constructor(val rotation: Rotation = Rotation.ROTATION_0) {
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ExitDesktopWithDragToTopDragZone.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ExitDesktopWithDragToTopDragZone.kt
similarity index 87%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ExitDesktopWithDragToTopDragZone.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ExitDesktopWithDragToTopDragZone.kt
index 0b6c9af..533be88 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ExitDesktopWithDragToTopDragZone.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ExitDesktopWithDragToTopDragZone.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
+import android.platform.test.annotations.Postsubmit
 import android.app.Instrumentation
 import android.tools.NavBar
 import android.tools.Rotation
@@ -26,17 +27,18 @@
 import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.window.flags.Flags
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
 
-
-@Ignore("Base Test Class")
-abstract class ExitDesktopWithDragToTopDragZone
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class ExitDesktopWithDragToTopDragZone
 @JvmOverloads
 constructor(val rotation: Rotation = Rotation.ROTATION_0) {
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MaximizeAppWindow.kt
similarity index 87%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MaximizeAppWindow.kt
index 20e2167c..e3660fe 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MaximizeAppWindow.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
+import android.platform.test.annotations.Postsubmit
 import android.app.Instrumentation
 import android.tools.NavBar
 import android.tools.Rotation
@@ -26,17 +27,17 @@
 import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.window.flags.Flags
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
-
-/** Base scenario test for maximize app window CUJ in desktop mode. */
-@Ignore("Base Test Class")
-abstract class MaximizeAppWindow
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class MaximizeAppWindow
 {
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
     private val tapl = LauncherInstrumentation()
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MinimizeWindowOnAppOpen.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MinimizeWindowOnAppOpen.kt
similarity index 91%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MinimizeWindowOnAppOpen.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MinimizeWindowOnAppOpen.kt
index c847710..b86765e 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MinimizeWindowOnAppOpen.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/MinimizeWindowOnAppOpen.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
+import android.platform.test.annotations.Postsubmit
 import android.app.Instrumentation
 import android.tools.traces.parsers.WindowManagerStateHelper
 import androidx.test.platform.app.InstrumentationRegistry
@@ -31,16 +32,17 @@
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Test
-
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
 /**
  * Base scenario test for minimizing the least recently used window when a new window is opened
  * above the window limit. For tangor devices, which this test currently runs on, the window limit
  * is 4.
  */
-@Ignore("Base Test Class")
-abstract class MinimizeWindowOnAppOpen()
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class MinimizeWindowOnAppOpen()
 {
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
     private val tapl = LauncherInstrumentation()
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppWithCornerResize.kt
similarity index 88%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppWithCornerResize.kt
index 136cf37..63e7387 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppWithCornerResize.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
+import android.platform.test.annotations.Postsubmit
 import android.app.Instrumentation
 import android.tools.NavBar
 import android.tools.Rotation
@@ -26,17 +27,18 @@
 import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.window.flags.Flags
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
 
-
-@Ignore("Base Test Class")
-abstract class ResizeAppWithCornerResize
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class ResizeAppWithCornerResize
 @JvmOverloads
 constructor(val rotation: Rotation = Rotation.ROTATION_0,
     val horizontalChange: Int = 50,
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/SwitchToOverviewFromDesktop.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/SwitchToOverviewFromDesktop.kt
similarity index 88%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/SwitchToOverviewFromDesktop.kt
rename to libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/SwitchToOverviewFromDesktop.kt
index b4cadf4..53e36e23 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/SwitchToOverviewFromDesktop.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/SwitchToOverviewFromDesktop.kt
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.desktopmode.scenarios
+package com.android.wm.shell.scenarios
 
+import android.platform.test.annotations.Postsubmit
 import android.app.Instrumentation
 import android.tools.NavBar
 import android.tools.Rotation
@@ -26,21 +27,23 @@
 import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.window.flags.Flags
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import org.junit.After
 import org.junit.Assume
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
 
 /**
 * Base test for opening recent apps overview from desktop mode.
 *
 * Navigation mode can be passed as a constructor parameter, by default it is set to gesture navigation.
 */
-@Ignore("Base Test Class")
-abstract class SwitchToOverviewFromDesktop
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class SwitchToOverviewFromDesktop
 @JvmOverloads
 constructor(val navigationMode: NavBar = NavBar.MODE_GESTURAL) {
 
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/OWNERS b/libs/WindowManager/Shell/tests/e2e/splitscreen/OWNERS
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/OWNERS
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/OWNERS
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidManifest.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidManifest.xml
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidManifest.xml
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidManifest.xml
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidTestTemplate.xml
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidTestTemplate.xml
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/AndroidTestTemplate.xml
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/OWNERS b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/OWNERS
similarity index 100%
copy from libs/WindowManager/Shell/tests/flicker/splitscreen/OWNERS
copy to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/OWNERS
diff --git a/libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/res/xml/network_security_config.xml
similarity index 100%
copy from libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml
copy to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/res/xml/network_security_config.xml
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/MultipleShowImeRequestsInSplitScreen.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/MultipleShowImeRequestsInSplitScreen.kt
similarity index 73%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/MultipleShowImeRequestsInSplitScreen.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/MultipleShowImeRequestsInSplitScreen.kt
index dad5db9..a9dba4a 100644
--- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/MultipleShowImeRequestsInSplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/MultipleShowImeRequestsInSplitScreen.kt
@@ -17,11 +17,13 @@
 package com.android.wm.shell.flicker.splitscreen
 
 import android.platform.test.annotations.Presubmit
+import android.tools.NavBar
 import android.tools.Rotation
+import android.tools.ScenarioBuilder
 import android.tools.flicker.junit.FlickerParametersRunnerFactory
 import android.tools.flicker.legacy.FlickerBuilder
 import android.tools.flicker.legacy.LegacyFlickerTest
-import android.tools.flicker.legacy.LegacyFlickerTestFactory
+import android.tools.traces.SERVICE_TRACE_CONFIG
 import android.tools.traces.component.ComponentNameMatcher
 import androidx.test.filters.RequiresDevice
 import com.android.wm.shell.flicker.splitscreen.benchmark.MultipleShowImeRequestsInSplitScreenBenchmark
@@ -35,7 +37,7 @@
 /**
  * Test quick switch between two split pairs.
  *
- * To run this test: `atest WMShellFlickerTestsSplitScreenGroup2:MultipleShowImeRequestsInSplitScreen`
+ * To run this test: `atest WMShellFlickerTestsSplitScreenGroupOther:MultipleShowImeRequestsInSplitScreen`
  */
 @RequiresDevice
 @RunWith(Parameterized::class)
@@ -58,10 +60,22 @@
             }
 
     companion object {
+        private fun createFlickerTest(
+            navBarMode: NavBar
+        ) = LegacyFlickerTest(ScenarioBuilder()
+            .withStartRotation(Rotation.ROTATION_0)
+            .withEndRotation(Rotation.ROTATION_0)
+            .withNavBarMode(navBarMode), resultReaderProvider = { scenario ->
+            android.tools.flicker.datastore.CachedResultReader(
+                scenario, SERVICE_TRACE_CONFIG
+            )
+        })
+
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
-        fun getParams() = LegacyFlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(Rotation.ROTATION_0)
+        fun getParams() = listOf(
+            createFlickerTest(NavBar.MODE_GESTURAL),
+            createFlickerTest(NavBar.MODE_3BUTTON)
         )
     }
-}
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
similarity index 98%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
index d349988..3018b56 100644
--- a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.flicker.splitscreen
 
-import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.tools.NavBar
 import android.tools.flicker.junit.FlickerParametersRunnerFactory
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/MultipleShowImeRequestsInSplitScreenBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/MultipleShowImeRequestsInSplitScreenBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/MultipleShowImeRequestsInSplitScreenBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/MultipleShowImeRequestsInSplitScreenBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/trace_config/trace_config.textproto
similarity index 100%
rename from libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/trace_config/trace_config.textproto
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/Android.bp
new file mode 100644
index 0000000..dd0018a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/Android.bp
@@ -0,0 +1,41 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+    name: "WMShellFlickerServiceTests",
+    defaults: ["WMShellFlickerTestsDefault"],
+    manifest: "AndroidManifest.xml",
+    test_config_template: "AndroidTestTemplate.xml",
+    srcs: ["src/**/*.kt"],
+    static_libs: [
+        "WMShellFlickerTestsBase",
+        "WMShellScenariosSplitScreen",
+        "WMShellTestUtils",
+    ],
+    data: [
+        ":FlickerTestApp",
+        "trace_config/*",
+    ],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidManifest.xml
similarity index 97%
rename from libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidManifest.xml
index d54b694..662e7f3 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidManifest.xml
@@ -16,7 +16,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
-          package="com.android.wm.shell.flicker.service">
+          package="com.android.wm.shell">
 
     <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
     <!-- Read and write traces from external storage -->
@@ -71,7 +71,7 @@
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.wm.shell.flicker.service"
+                     android:targetPackage="com.android.wm.shell"
                      android:label="WindowManager Flicker Service Tests">
     </instrumentation>
 </manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml
similarity index 74%
copy from libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml
copy to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml
index a66dfb4..6c903a2 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/AndroidTestTemplate.xml
@@ -14,7 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<configuration description="Runs WindowManager Shell Flicker Tests {MODULE}">
+<configuration description="WMShell Platinum Tests {MODULE}">
     <option name="test-tag" value="FlickerTests"/>
     <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
     <option name="isolated-storage" value="false"/>
@@ -59,37 +59,15 @@
         <option name="test-file-name" value="{MODULE}.apk"/>
         <option name="test-file-name" value="FlickerTestApp.apk"/>
     </target_preparer>
-    <!-- Enable mocking GPS location by the test app -->
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-        <option name="run-command"
-                value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location allow"/>
-        <option name="teardown-command"
-                value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location deny"/>
-    </target_preparer>
-
     <!-- Needed for pushing the trace config file -->
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="push-file"
-                key="trace_config.textproto"
-                value="/data/misc/perfetto-traces/trace_config.textproto"
-        />
-        <!--Install the content provider automatically when we push some file in sdcard folder.-->
-        <!--Needed to avoid the installation during the test suite.-->
-        <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
-    </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest">
         <option name="package" value="{PACKAGE}"/>
         <option name="shell-timeout" value="6600s"/>
         <option name="test-timeout" value="6000s"/>
         <option name="hidden-api-checks" value="false"/>
-        <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
-        <!-- PerfettoListener related arguments -->
-        <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
-        <option name="instrumentation-arg"
-                key="perfetto_config_file"
-                value="trace_config.textproto"
-        />
+        <option name="device-listeners" value="android.tools.collectors.DefaultUITraceListener"/>
+        <!-- DefaultUITraceListener args -->
         <option name="instrumentation-arg" key="per_run" value="true"/>
         <option name="instrumentation-arg" key="perfetto_persist_pid_track" value="true"/>
     </test>
@@ -97,7 +75,7 @@
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
         <option name="pull-pattern-keys" value="perfetto_file_path"/>
         <option name="directory-keys"
-                value="/data/user/0/com.android.wm.shell.flicker.service/files"/>
+                value="/data/user/0/com.android.wm.shell/files"/>
         <option name="collect-on-run-ended-only" value="true"/>
         <option name="clean-up" value="true"/>
     </metrics_collector>
diff --git a/libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/res/xml/network_security_config.xml
similarity index 100%
copy from libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml
copy to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/res/xml/network_security_config.xml
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/CopyContentInSplitGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/CopyContentInSplitGesturalNavLandscape.kt
index 1684a26..3cb9cf2 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/CopyContentInSplitGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit
+import com.android.wm.shell.scenarios.CopyContentInSplit
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/CopyContentInSplitGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/CopyContentInSplitGesturalNavPortrait.kt
index 3b5fad6..b27a8ae 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/CopyContentInSplitGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit
+import com.android.wm.shell.scenarios.CopyContentInSplit
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
index 2b8a903..9388114 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider
+import com.android.wm.shell.scenarios.DismissSplitScreenByDivider
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
index b284fe1..30ef492 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider
+import com.android.wm.shell.scenarios.DismissSplitScreenByDivider
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
index a400ee4..059f967 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome
+import com.android.wm.shell.scenarios.DismissSplitScreenByGoHome
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
index 7f5ee4c..0c6d546 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome
+import com.android.wm.shell.scenarios.DismissSplitScreenByGoHome
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DragDividerToResizeGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DragDividerToResizeGesturalNavLandscape.kt
index 1b075c4..14fb72b 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DragDividerToResizeGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize
+import com.android.wm.shell.scenarios.DragDividerToResize
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DragDividerToResizeGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DragDividerToResizeGesturalNavPortrait.kt
index 6ca3737..9be61a5 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/DragDividerToResizeGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize
+import com.android.wm.shell.scenarios.DragDividerToResize
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
index f7d231f0..c12d199 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromAllApps
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
index ab819fa..11cd38a 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromAllApps
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
index a6b732c..66d4bfa 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromNotification
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
index 07e5f4b..f3a11eb 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromNotification
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
index 2725694..327ecc3 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromShortcut
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
index 58cc4d7..dd5a395 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromShortcut
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
index 85897a1..8e7cf30 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromTaskbar
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
index 891b6df..0324dac 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromTaskbar
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
index 7983652..2fa141e 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview
+import com.android.wm.shell.scenarios.EnterSplitScreenFromOverview
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
index 1bdea66..0176913 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview
+import com.android.wm.shell.scenarios.EnterSplitScreenFromOverview
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
index bab0c0a..1db28dc 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider
+import com.android.wm.shell.scenarios.SwitchAppByDoubleTapDivider
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
index 17a59ab..c69167b 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider
+import com.android.wm.shell.scenarios.SwitchAppByDoubleTapDivider
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
index 2c36d64..602283a 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromAnotherApp
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
index 6e91d04..7cc14e0 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromAnotherApp
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
index a921b46..daf6547 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromHome
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
index 05f8912..b0f5e65 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromHome
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
index 1ae1f53..88fa783 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromRecent
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
index e14ca55..aa36f44 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromRecent
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt
index ce0c4c4..292f413 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs
+import com.android.wm.shell.scenarios.SwitchBetweenSplitPairs
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt
index 5a8d2d5..865958f 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.Rotation
 import android.tools.flicker.FlickerConfig
@@ -23,7 +23,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs
+import com.android.wm.shell.scenarios.SwitchBetweenSplitPairs
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
index d442615..6c36e84 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.flicker.FlickerConfig
 import android.tools.flicker.annotation.ExpectedScenarios
@@ -22,7 +22,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen
+import com.android.wm.shell.scenarios.UnlockKeyguardToSplitScreen
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
similarity index 90%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
index ddc8a06..61ccd36 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-service/src/com/android/server/wm/shell/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.flicker
+package com.android.wm.shell.flicker
 
 import android.tools.flicker.FlickerConfig
 import android.tools.flicker.annotation.ExpectedScenarios
@@ -22,7 +22,7 @@
 import android.tools.flicker.config.FlickerConfig
 import android.tools.flicker.config.FlickerServiceConfig
 import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen
+import com.android.wm.shell.scenarios.UnlockKeyguardToSplitScreen
 import org.junit.Test
 import org.junit.runner.RunWith
 
diff --git a/libs/WindowManager/Shell/tests/flicker/service/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/Android.bp
similarity index 67%
rename from libs/WindowManager/Shell/tests/flicker/service/Android.bp
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/Android.bp
index a5bc261..90210b1 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/Android.bp
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/Android.bp
@@ -26,9 +26,7 @@
 filegroup {
     name: "WMShellFlickerServicePlatinumTests-src",
     srcs: [
-        "src/**/platinum/*.kt",
-        "src/**/scenarios/*.kt",
-        "src/**/common/*.kt",
+        "src/**/*.kt",
     ],
 }
 
@@ -43,33 +41,42 @@
     ],
     static_libs: [
         "wm-shell-flicker-utils",
+        "WMShellScenariosSplitScreen",
     ],
 }
 
 android_test {
-    name: "WMShellFlickerServiceTests",
-    defaults: ["WMShellFlickerTestsDefault"],
-    manifest: "AndroidManifest.xml",
-    package_name: "com.android.wm.shell.flicker.service",
-    instrumentation_target_package: "com.android.wm.shell.flicker.service",
-    test_config_template: "AndroidTestTemplate.xml",
-    srcs: ["src/**/*.kt"],
-    static_libs: ["WMShellFlickerTestsBase"],
-    data: ["trace_config/*"],
-}
-
-android_test {
     name: "WMShellFlickerServicePlatinumTests",
-    defaults: ["WMShellFlickerTestsDefault"],
+    platform_apis: true,
+    certificate: "platform",
+    optimize: {
+        enabled: false,
+    },
     manifest: "AndroidManifest.xml",
-    package_name: "com.android.wm.shell.flicker.service",
-    instrumentation_target_package: "com.android.wm.shell.flicker.service",
     test_config_template: "AndroidTestTemplate.xml",
     test_suites: [
         "device-tests",
         "device-platinum-tests",
     ],
     srcs: [":WMShellFlickerServicePlatinumTests-src"],
-    static_libs: ["WMShellFlickerTestsBase"],
-    data: ["trace_config/*"],
+    static_libs: [
+        "WMShellFlickerTestsBase",
+        "WMShellScenariosSplitScreen",
+        "WMShellTestUtils",
+        "ui-trace-collector",
+        "collector-device-lib",
+        "wm-shell-flicker-utils",
+        "androidx.test.ext.junit",
+        "flickertestapplib",
+        "flickerlib-helpers",
+        "flickerlib-trace_processor_shell",
+        "platform-test-annotations",
+        "wm-flicker-common-app-helpers",
+        "launcher-helper-lib",
+        "launcher-aosp-tapl",
+    ],
+    data: [
+        ":FlickerTestApp",
+        "trace_config/*",
+    ],
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidManifest.xml
similarity index 97%
copy from libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml
copy to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidManifest.xml
index d54b694..662e7f3 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidManifest.xml
@@ -16,7 +16,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:tools="http://schemas.android.com/tools"
-          package="com.android.wm.shell.flicker.service">
+          package="com.android.wm.shell">
 
     <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
     <!-- Read and write traces from external storage -->
@@ -71,7 +71,7 @@
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.wm.shell.flicker.service"
+                     android:targetPackage="com.android.wm.shell"
                      android:label="WindowManager Flicker Service Tests">
     </instrumentation>
 </manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml
similarity index 74%
copy from libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml
copy to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml
index a66dfb4..6c903a2 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/AndroidTestTemplate.xml
@@ -14,7 +14,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<configuration description="Runs WindowManager Shell Flicker Tests {MODULE}">
+<configuration description="WMShell Platinum Tests {MODULE}">
     <option name="test-tag" value="FlickerTests"/>
     <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
     <option name="isolated-storage" value="false"/>
@@ -59,37 +59,15 @@
         <option name="test-file-name" value="{MODULE}.apk"/>
         <option name="test-file-name" value="FlickerTestApp.apk"/>
     </target_preparer>
-    <!-- Enable mocking GPS location by the test app -->
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-        <option name="run-command"
-                value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location allow"/>
-        <option name="teardown-command"
-                value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location deny"/>
-    </target_preparer>
-
     <!-- Needed for pushing the trace config file -->
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="push-file"
-                key="trace_config.textproto"
-                value="/data/misc/perfetto-traces/trace_config.textproto"
-        />
-        <!--Install the content provider automatically when we push some file in sdcard folder.-->
-        <!--Needed to avoid the installation during the test suite.-->
-        <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
-    </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest">
         <option name="package" value="{PACKAGE}"/>
         <option name="shell-timeout" value="6600s"/>
         <option name="test-timeout" value="6000s"/>
         <option name="hidden-api-checks" value="false"/>
-        <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
-        <!-- PerfettoListener related arguments -->
-        <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
-        <option name="instrumentation-arg"
-                key="perfetto_config_file"
-                value="trace_config.textproto"
-        />
+        <option name="device-listeners" value="android.tools.collectors.DefaultUITraceListener"/>
+        <!-- DefaultUITraceListener args -->
         <option name="instrumentation-arg" key="per_run" value="true"/>
         <option name="instrumentation-arg" key="perfetto_persist_pid_track" value="true"/>
     </test>
@@ -97,7 +75,7 @@
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
         <option name="pull-pattern-keys" value="perfetto_file_path"/>
         <option name="directory-keys"
-                value="/data/user/0/com.android.wm.shell.flicker.service/files"/>
+                value="/data/user/0/com.android.wm.shell/files"/>
         <option name="collect-on-run-ended-only" value="true"/>
         <option name="clean-up" value="true"/>
     </metrics_collector>
diff --git a/libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/res/xml/network_security_config.xml
similarity index 100%
copy from libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml
copy to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/res/xml/network_security_config.xml
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/CopyContentInSplitGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/CopyContentInSplitGesturalNavLandscape.kt
index 64293b2..4c2ca67 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/CopyContentInSplitGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit
+import com.android.wm.shell.scenarios.CopyContentInSplit
 import org.junit.Test
 
 open class CopyContentInSplitGesturalNavLandscape : CopyContentInSplit(Rotation.ROTATION_90) {
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/CopyContentInSplitGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/CopyContentInSplitGesturalNavPortrait.kt
index 517ba2d..0cca310 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/CopyContentInSplitGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit
+import com.android.wm.shell.scenarios.CopyContentInSplit
 import org.junit.Test
 
 open class CopyContentInSplitGesturalNavPortrait : CopyContentInSplit(Rotation.ROTATION_0) {
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByDividerGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByDividerGesturalNavLandscape.kt
index 1bafe3b..7aa62cf 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByDividerGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider
+import com.android.wm.shell.scenarios.DismissSplitScreenByDivider
 import org.junit.Test
 
 open class DismissSplitScreenByDividerGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByDividerGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByDividerGesturalNavPortrait.kt
index fd0100f..de11fc6 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByDividerGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider
+import com.android.wm.shell.scenarios.DismissSplitScreenByDivider
 import org.junit.Test
 
 open class DismissSplitScreenByDividerGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
index 850b3d8..daa6aac 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome
+import com.android.wm.shell.scenarios.DismissSplitScreenByGoHome
 import org.junit.Test
 
 open class DismissSplitScreenByGoHomeGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
index 0b752bf..ff57d00 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome
+import com.android.wm.shell.scenarios.DismissSplitScreenByGoHome
 import org.junit.Test
 
 open class DismissSplitScreenByGoHomeGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DragDividerToResizeGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DragDividerToResizeGesturalNavLandscape.kt
index 3c52aa7..0ac19c8 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DragDividerToResizeGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize
+import com.android.wm.shell.scenarios.DragDividerToResize
 import org.junit.Test
 
 open class DragDividerToResizeGesturalNavLandscape : DragDividerToResize(Rotation.ROTATION_90) {
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DragDividerToResizeGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DragDividerToResizeGesturalNavPortrait.kt
index c2e21b8..5713602e 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/DragDividerToResizeGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize
+import com.android.wm.shell.scenarios.DragDividerToResize
 import org.junit.Test
 
 open class DragDividerToResizeGesturalNavPortrait : DragDividerToResize(Rotation.ROTATION_0) {
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
index bf85ab4..d7333f1a 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromAllApps
 import org.junit.Test
 
 open class EnterSplitScreenByDragFromAllAppsGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
index 0ac4ca2..e29a140 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromAllApps
 import org.junit.Test
 
 open class EnterSplitScreenByDragFromAllAppsGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
index 80bd088..9ccccb1 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromNotification
 import org.junit.Test
 
 open class EnterSplitScreenByDragFromNotificationGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
index 0dffb4a..87a4d08 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromNotification
 import org.junit.Test
 
 open class EnterSplitScreenByDragFromNotificationGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
index b721f2f..559652c 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromShortcut
 import org.junit.Test
 
 open class EnterSplitScreenByDragFromShortcutGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
index 22cbc77..bcb8e0c 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromShortcut
 import org.junit.Test
 
 open class EnterSplitScreenByDragFromShortcutGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
index ac0f9e2..39e0fed 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromTaskbar
 import org.junit.Test
 
 open class EnterSplitScreenByDragFromTaskbarGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
index f7a229d..6431629 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar
+import com.android.wm.shell.scenarios.EnterSplitScreenByDragFromTaskbar
 import org.junit.Test
 
 open class EnterSplitScreenByDragFromTaskbarGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
index 6dbbcb0..2093424 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview
+import com.android.wm.shell.scenarios.EnterSplitScreenFromOverview
 import org.junit.Test
 
 open class EnterSplitScreenFromOverviewGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
index bd69ea9..f89259d 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview
+import com.android.wm.shell.scenarios.EnterSplitScreenFromOverview
 import org.junit.Test
 
 open class EnterSplitScreenFromOverviewGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
index 404b96f..e5aff0c 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider
+import com.android.wm.shell.scenarios.SwitchAppByDoubleTapDivider
 import org.junit.Test
 
 open class SwitchAppByDoubleTapDividerGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
index a79687d..defade9 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider
+import com.android.wm.shell.scenarios.SwitchAppByDoubleTapDivider
 import org.junit.Test
 
 open class SwitchAppByDoubleTapDividerGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
index b52eb4c..e28deca 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromAnotherApp
 import org.junit.Test
 
 open class SwitchBackToSplitFromAnotherAppGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
index d79620c..99fb06c 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromAnotherApp
 import org.junit.Test
 
 open class SwitchBackToSplitFromAnotherAppGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
index d27bfa1..7045e66 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromHome
 import org.junit.Test
 
 open class SwitchBackToSplitFromHomeGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
index 3c7d4d4..b2da052 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromHome
 import org.junit.Test
 
 open class SwitchBackToSplitFromHomeGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
index 26a2034..04d7f62 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromRecent
 import org.junit.Test
 
 open class SwitchBackToSplitFromRecentGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
index 5154b35..bc36fb7 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent
+import com.android.wm.shell.scenarios.SwitchBackToSplitFromRecent
 import org.junit.Test
 
 open class SwitchBackToSplitFromRecentGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBetweenSplitPairsGesturalNavLandscape.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBetweenSplitPairsGesturalNavLandscape.kt
index 86451c5..ceda4da 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBetweenSplitPairsGesturalNavLandscape.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs
+import com.android.wm.shell.scenarios.SwitchBetweenSplitPairs
 import org.junit.Test
 
 open class SwitchBetweenSplitPairsGesturalNavLandscape :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBetweenSplitPairsGesturalNavPortrait.kt
similarity index 86%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBetweenSplitPairsGesturalNavPortrait.kt
index baf72b4..365c5cc 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/SwitchBetweenSplitPairsGesturalNavPortrait.kt
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
 import android.tools.Rotation
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs
+import com.android.wm.shell.scenarios.SwitchBetweenSplitPairs
 import org.junit.Test
 
 open class SwitchBetweenSplitPairsGesturalNavPortrait :
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
similarity index 87%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
index 9caab9b..a866297 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen
+import com.android.wm.shell.scenarios.UnlockKeyguardToSplitScreen
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.BlockJUnit4ClassRunner
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
similarity index 87%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
index bf484e5..6d59001 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/platinum/src/com/android/wm/shell/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.platinum
+package com.android.wm.shell
 
 import android.platform.test.annotations.PlatinumTest
 import android.platform.test.annotations.Presubmit
-import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen
+import com.android.wm.shell.scenarios.UnlockKeyguardToSplitScreen
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.BlockJUnit4ClassRunner
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/Android.bp
new file mode 100644
index 0000000..60c7de7
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/Android.bp
@@ -0,0 +1,47 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_library {
+    name: "WMShellScenariosSplitScreen",
+    platform_apis: true,
+    optimize: {
+        enabled: false,
+    },
+    srcs: ["src/**/*.kt"],
+    static_libs: [
+        "WMShellFlickerTestsBase",
+        "WMShellTestUtils",
+        "wm-shell-flicker-utils",
+        "androidx.test.ext.junit",
+        "flickertestapplib",
+        "flickerlib-helpers",
+        "flickerlib-trace_processor_shell",
+        "platform-test-annotations",
+        "wm-flicker-common-app-helpers",
+        "wm-flicker-common-assertions",
+        "launcher-helper-lib",
+        "launcher-aosp-tapl",
+    ],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/CopyContentInSplit.kt
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/CopyContentInSplit.kt
index 6171074..ba46542 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/CopyContentInSplit.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DismissSplitScreenByDivider.kt
similarity index 93%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DismissSplitScreenByDivider.kt
index c1a8ee7..d774a31 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DismissSplitScreenByDivider.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DismissSplitScreenByGoHome.kt
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DismissSplitScreenByGoHome.kt
index 600855a..5aa1619 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DismissSplitScreenByGoHome.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DragDividerToResize.kt
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DragDividerToResize.kt
index b5a6d83..668f367 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/DragDividerToResize.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromAllApps.kt
similarity index 93%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromAllApps.kt
index a189325..06c7b9b 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromAllApps.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -24,7 +24,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Assume
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromNotification.kt
similarity index 94%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromNotification.kt
index bcd0f12..96b22bf 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromNotification.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -25,7 +25,7 @@
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
 import com.android.server.wm.flicker.helpers.MultiWindowUtils
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Assume
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromShortcut.kt
similarity index 94%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromShortcut.kt
index 3f07be0..9e05b63 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromShortcut.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -24,7 +24,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Assume
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromTaskbar.kt
similarity index 93%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromTaskbar.kt
index 5328013..9090055 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenByDragFromTaskbar.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Assume
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenFromOverview.kt
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenFromOverview.kt
index be4035d..d5cc92e 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/EnterSplitScreenFromOverview.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt
similarity index 96%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt
index 2406bde..26203d4 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchAppByDoubleTapDivider.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.graphics.Point
@@ -25,7 +25,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromAnotherApp.kt
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromAnotherApp.kt
index de26982..2ccffa85 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromAnotherApp.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromHome.kt
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromHome.kt
index 873b019..8673c46 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromHome.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromRecent.kt
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromRecent.kt
index 15934d0..c7cbc3e 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBackToSplitFromRecent.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBetweenSplitPairs.kt
similarity index 93%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBetweenSplitPairs.kt
index 79e69ae..4ded148 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/SwitchBetweenSplitPairs.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/UnlockKeyguardToSplitScreen.kt
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
rename to libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/UnlockKeyguardToSplitScreen.kt
index 0f932d4..7b062fcc 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/scenarios/src/com/android/wm/shell/scenarios/UnlockKeyguardToSplitScreen.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.splitscreen.scenarios
+package com.android.wm.shell.scenarios
 
 import android.app.Instrumentation
 import android.tools.NavBar
@@ -23,7 +23,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.uiautomator.UiDevice
 import com.android.launcher3.tapl.LauncherInstrumentation
-import com.android.wm.shell.flicker.service.common.Utils
+import com.android.wm.shell.Utils
 import com.android.wm.shell.flicker.utils.SplitScreenUtils
 import org.junit.After
 import org.junit.Before
diff --git a/libs/WindowManager/Shell/tests/e2e/utils/Android.bp b/libs/WindowManager/Shell/tests/e2e/utils/Android.bp
new file mode 100644
index 0000000..51d9c40
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/utils/Android.bp
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_team: "trendy_team_windowing_tools",
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_library {
+    name: "WMShellTestUtils",
+    srcs: ["src/**/*.kt"],
+    static_libs: ["WMShellFlickerTestsBase"],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/common/Utils.kt b/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/Utils.kt
similarity index 97%
rename from libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/common/Utils.kt
rename to libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/Utils.kt
index 4c6c6cc..dee67f3 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/common/Utils.kt
+++ b/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/Utils.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.flicker.service.common
+package com.android.wm.shell
 
 import android.app.Instrumentation
 import android.platform.test.rule.NavigationModeRule
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/CloseAllAppsWithAppHeaderExitTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/CloseAllAppsWithAppHeaderExitTest.kt
deleted file mode 100644
index 9ba3a45..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/CloseAllAppsWithAppHeaderExitTest.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.flicker.service.desktopmode.functional
-
-import android.platform.test.annotations.Postsubmit
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.CloseAllAppsWithAppHeaderExit
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.BlockJUnit4ClassRunner
-
-/** Functional test for [CloseAllAppsWithAppHeaderExit]. */
-@RunWith(BlockJUnit4ClassRunner::class)
-@Postsubmit
-open class CloseAllAppsWithAppHeaderExitTest : CloseAllAppsWithAppHeaderExit() {
-
-    @Test
-    override fun closeAllAppsInDesktop() {
-        super.closeAllAppsInDesktop()
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowMultiWindowTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowMultiWindowTest.kt
deleted file mode 100644
index ed1d488..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowMultiWindowTest.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.flicker.service.desktopmode.functional
-
-import android.platform.test.annotations.Postsubmit
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.DragAppWindowMultiWindow
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.BlockJUnit4ClassRunner
-
-/** Functional test for [DragAppWindowMultiWindow]. */
-@RunWith(BlockJUnit4ClassRunner::class)
-@Postsubmit
-open class DragAppWindowMultiWindowTest : DragAppWindowMultiWindow()
-{
-    @Test
-    override fun dragAppWindow() {
-        super.dragAppWindow()
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowSingleWindowTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowSingleWindowTest.kt
deleted file mode 100644
index d8b9348..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/DragAppWindowSingleWindowTest.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.flicker.service.desktopmode.functional
-
-import android.platform.test.annotations.Postsubmit
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.DragAppWindowSingleWindow
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.BlockJUnit4ClassRunner
-
-/** Functional test for [DragAppWindowSingleWindow]. */
-@RunWith(BlockJUnit4ClassRunner::class)
-@Postsubmit
-open class DragAppWindowSingleWindowTest : DragAppWindowSingleWindow()
-{
-    @Test
-    override fun dragAppWindow() {
-        super.dragAppWindow()
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithAppHandleMenuTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithAppHandleMenuTest.kt
deleted file mode 100644
index 546ce2d..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithAppHandleMenuTest.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.flicker.service.desktopmode.functional
-
-import android.platform.test.annotations.Postsubmit
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithAppHandleMenu
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.BlockJUnit4ClassRunner
-
-/** Functional test for [EnterDesktopWithAppHandleMenu]. */
-@RunWith(BlockJUnit4ClassRunner::class)
-@Postsubmit
-open class EnterDesktopWithAppHandleMenuTest : EnterDesktopWithAppHandleMenu() {
-    @Test
-    override fun enterDesktopWithAppHandleMenu() {
-        super.enterDesktopWithAppHandleMenu()
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithDragTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithDragTest.kt
deleted file mode 100644
index b5fdb16..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/EnterDesktopWithDragTest.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.flicker.service.desktopmode.functional
-
-import android.platform.test.annotations.Postsubmit
-import android.tools.Rotation
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.EnterDesktopWithDrag
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.BlockJUnit4ClassRunner
-
-/** Functional test for [EnterDesktopWithDrag]. */
-@RunWith(BlockJUnit4ClassRunner::class)
-@Postsubmit
-open class EnterDesktopWithDragTest : EnterDesktopWithDrag(Rotation.ROTATION_0) {
-
-    @Test
-    override fun enterDesktopWithDrag() {
-        super.enterDesktopWithDrag()
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ExitDesktopWithDragToTopDragZoneTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ExitDesktopWithDragToTopDragZoneTest.kt
deleted file mode 100644
index 8f802d2..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ExitDesktopWithDragToTopDragZoneTest.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.flicker.service.desktopmode.functional
-
-import android.platform.test.annotations.Postsubmit
-import android.tools.Rotation
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.ExitDesktopWithDragToTopDragZone
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.BlockJUnit4ClassRunner
-
-/** Functional test for [ExitDesktopWithDragToTopDragZone]. */
-@RunWith(BlockJUnit4ClassRunner::class)
-@Postsubmit
-open class ExitDesktopWithDragToTopDragZoneTest :
-    ExitDesktopWithDragToTopDragZone(Rotation.ROTATION_0) {
-    @Test
-    override fun exitDesktopWithDragToTopDragZone() {
-        super.exitDesktopWithDragToTopDragZone()
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MaximizeAppWindowTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MaximizeAppWindowTest.kt
deleted file mode 100644
index f899082..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MaximizeAppWindowTest.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.flicker.service.desktopmode.functional
-
-import android.platform.test.annotations.Postsubmit
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.MaximizeAppWindow
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.BlockJUnit4ClassRunner
-
-/** Functional test for [MaximizeAppWindow]. */
-@RunWith(BlockJUnit4ClassRunner::class)
-@Postsubmit
-open class MaximizeAppWindowTest : MaximizeAppWindow()
-{
-    @Test
-    override fun maximizeAppWindow() {
-        super.maximizeAppWindow()
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MinimizeWindowOnAppOpenTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MinimizeWindowOnAppOpenTest.kt
deleted file mode 100644
index 63c428a..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/MinimizeWindowOnAppOpenTest.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.flicker.service.desktopmode.functional
-
-import android.platform.test.annotations.Postsubmit
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.MinimizeWindowOnAppOpen
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.BlockJUnit4ClassRunner
-
-/** Functional test for [MinimizeWindowOnAppOpen]. */
-@RunWith(BlockJUnit4ClassRunner::class)
-@Postsubmit
-open class MinimizeWindowOnAppOpenTest : MinimizeWindowOnAppOpen()
-{
-    @Test
-    override fun openAppToMinimizeWindow() {
-        // Launch a new app while 4 apps are already open on desktop. This should result in the
-        // first app we opened to be minimized.
-        super.openAppToMinimizeWindow()
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ResizeAppWithCornerResizeTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ResizeAppWithCornerResizeTest.kt
deleted file mode 100644
index 4797aaf..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/ResizeAppWithCornerResizeTest.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.flicker.service.desktopmode.functional
-
-import android.platform.test.annotations.Postsubmit
-import android.tools.Rotation
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.BlockJUnit4ClassRunner
-
-/** Functional test for [ResizeAppWithCornerResize]. */
-@RunWith(BlockJUnit4ClassRunner::class)
-@Postsubmit
-open class ResizeAppWithCornerResizeTest : ResizeAppWithCornerResize(Rotation.ROTATION_0) {
-    @Test
-    override fun resizeAppWithCornerResize() {
-        super.resizeAppWithCornerResize()
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/SwitchToOverviewFromDesktopTest.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/SwitchToOverviewFromDesktopTest.kt
deleted file mode 100644
index 9a71361..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/functional/SwitchToOverviewFromDesktopTest.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.flicker.service.desktopmode.functional
-
-import android.platform.test.annotations.Postsubmit
-import com.android.wm.shell.flicker.service.desktopmode.scenarios.SwitchToOverviewFromDesktop
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.BlockJUnit4ClassRunner
-
-/** Functional test for [SwitchToOverviewFromDesktop]. */
-@RunWith(BlockJUnit4ClassRunner::class)
-@Postsubmit
-open class SwitchToOverviewFromDesktopTest : SwitchToOverviewFromDesktop() {
-    @Test
-    override fun switchToOverview() {
-        super.switchToOverview()
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS
deleted file mode 100644
index 3ab6a1e..0000000
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Android > Android OS & Apps > Framework (Java + Native) > Window Manager > WM Shell > Split Screen
-# Bug component: 928697
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/flicker/splitscreen/res/xml/network_security_config.xml
deleted file mode 100644
index 4bd9ca0..0000000
--- a/libs/WindowManager/Shell/tests/flicker/splitscreen/res/xml/network_security_config.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2023 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<network-security-config>
-    <domain-config cleartextTrafficPermitted="true">
-        <domain includeSubdomains="true">localhost</domain>
-    </domain-config>
-</network-security-config>
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index d71f3b6..23cd3ce 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -143,6 +143,7 @@
                 "aconfig_text_flags_c_lib",
                 "server_configurable_flags",
                 "libaconfig_storage_read_api_cc",
+                "libgraphicsenv",
             ],
             static_libs: [
                 "libEGL_blobCache",
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 1217b47..b6476c9 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -42,6 +42,11 @@
 constexpr bool initialize_gl_always() {
     return false;
 }
+
+constexpr bool skip_eglmanager_telemetry() {
+    return false;
+}
+
 constexpr bool resample_gainmap_regions() {
     return false;
 }
@@ -103,6 +108,7 @@
 
 bool Properties::clipSurfaceViews = false;
 bool Properties::hdr10bitPlus = false;
+bool Properties::skipTelemetry = false;
 bool Properties::resampleGainmapRegions = false;
 
 int Properties::timeoutMultiplier = 1;
@@ -183,6 +189,8 @@
                                                    hwui_flags::resample_gainmap_regions());
 
     timeoutMultiplier = android::base::GetIntProperty("ro.hw_timeout_multiplier", 1);
+    skipTelemetry = base::GetBoolProperty(PROPERTY_SKIP_EGLMANAGER_TELEMETRY,
+                                          hwui_flags::skip_eglmanager_telemetry());
 
     return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
 }
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 73e80ce..db47152 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -234,6 +234,8 @@
  */
 #define PROPERTY_INITIALIZE_GL_ALWAYS "debug.hwui.initialize_gl_always"
 
+#define PROPERTY_SKIP_EGLMANAGER_TELEMETRY "debug.hwui.skip_eglmanager_telemetry"
+
 ///////////////////////////////////////////////////////////////////////////////
 // Misc
 ///////////////////////////////////////////////////////////////////////////////
@@ -342,6 +344,7 @@
 
     static bool clipSurfaceViews;
     static bool hdr10bitPlus;
+    static bool skipTelemetry;
     static bool resampleGainmapRegions;
 
     static int timeoutMultiplier;
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig
index 13c0b00..a1f5168 100644
--- a/libs/hwui/aconfig/hwui_flags.aconfig
+++ b/libs/hwui/aconfig/hwui_flags.aconfig
@@ -99,6 +99,13 @@
 }
 
 flag {
+  name: "skip_eglmanager_telemetry"
+  namespace: "core_graphics"
+  description: "Skip telemetry in EglManager's calls to eglCreateContext to avoid polluting telemetry"
+  bug: "347911216"
+}
+
+flag {
   name: "resample_gainmap_regions"
   namespace: "core_graphics"
   description: "Resample gainmaps when decoding regions, to improve visual quality"
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 708b011..6010445 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -19,6 +19,7 @@
 #include <EGL/eglext.h>
 #include <GLES/gl.h>
 #include <cutils/properties.h>
+#include <graphicsenv/GpuStatsInfo.h>
 #include <log/log.h>
 #include <sync/sync.h>
 #include <utils/Trace.h>
@@ -366,6 +367,10 @@
         contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG);
         contextAttributes.push_back(Properties::contextPriority);
     }
+    if (Properties::skipTelemetry) {
+        contextAttributes.push_back(EGL_TELEMETRY_HINT_ANDROID);
+        contextAttributes.push_back(android::GpuStatsInfo::SKIP_TELEMETRY);
+    }
     contextAttributes.push_back(EGL_NONE);
     mEglContext = eglCreateContext(
             mEglDisplay, EglExtensions.noConfigContext ? ((EGLConfig) nullptr) : mEglConfig,
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
index c88c4c9..0e71116 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
@@ -25,6 +25,7 @@
 import android.provider.Settings
 import androidx.concurrent.futures.DirectExecutor
 import com.android.internal.util.ConcurrentUtils
+import com.android.settingslib.volume.shared.AudioLogger
 import com.android.settingslib.volume.shared.AudioManagerEventsReceiver
 import com.android.settingslib.volume.shared.model.AudioManagerEvent
 import com.android.settingslib.volume.shared.model.AudioStream
@@ -99,7 +100,7 @@
     private val contentResolver: ContentResolver,
     private val backgroundCoroutineContext: CoroutineContext,
     private val coroutineScope: CoroutineScope,
-    private val logger: Logger,
+    private val logger: AudioLogger,
 ) : AudioRepository {
 
     private val streamSettingNames: Map<AudioStream, String> =
@@ -117,10 +118,10 @@
 
     override val mode: StateFlow<Int> =
         callbackFlow {
-                val listener = AudioManager.OnModeChangedListener { newMode -> trySend(newMode) }
-                audioManager.addOnModeChangedListener(ConcurrentUtils.DIRECT_EXECUTOR, listener)
-                awaitClose { audioManager.removeOnModeChangedListener(listener) }
-            }
+            val listener = AudioManager.OnModeChangedListener { newMode -> trySend(newMode) }
+            audioManager.addOnModeChangedListener(ConcurrentUtils.DIRECT_EXECUTOR, listener)
+            awaitClose { audioManager.removeOnModeChangedListener(listener) }
+        }
             .onStart { emit(audioManager.mode) }
             .flowOn(backgroundCoroutineContext)
             .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), audioManager.mode)
@@ -140,14 +141,14 @@
     override val communicationDevice: StateFlow<AudioDeviceInfo?>
         get() =
             callbackFlow {
-                    val listener = OnCommunicationDeviceChangedListener { trySend(Unit) }
-                    audioManager.addOnCommunicationDeviceChangedListener(
-                        ConcurrentUtils.DIRECT_EXECUTOR,
-                        listener,
-                    )
+                val listener = OnCommunicationDeviceChangedListener { trySend(Unit) }
+                audioManager.addOnCommunicationDeviceChangedListener(
+                    ConcurrentUtils.DIRECT_EXECUTOR,
+                    listener,
+                )
 
-                    awaitClose { audioManager.removeOnCommunicationDeviceChangedListener(listener) }
-                }
+                awaitClose { audioManager.removeOnCommunicationDeviceChangedListener(listener) }
+            }
                 .filterNotNull()
                 .map { audioManager.communicationDevice }
                 .onStart { emit(audioManager.communicationDevice) }
@@ -160,15 +161,15 @@
 
     override fun getAudioStream(audioStream: AudioStream): Flow<AudioStreamModel> {
         return merge(
-                audioManagerEventsReceiver.events.filter {
-                    if (it is StreamAudioManagerEvent) {
-                        it.audioStream == audioStream
-                    } else {
-                        true
-                    }
-                },
-                volumeSettingChanges(audioStream),
-            )
+            audioManagerEventsReceiver.events.filter {
+                if (it is StreamAudioManagerEvent) {
+                    it.audioStream == audioStream
+                } else {
+                    true
+                }
+            },
+            volumeSettingChanges(audioStream),
+        )
             .conflate()
             .map { getCurrentAudioStream(audioStream) }
             .onStart { emit(getCurrentAudioStream(audioStream)) }
@@ -251,11 +252,4 @@
             awaitClose { contentResolver.unregisterContentObserver(observer) }
         }
     }
-
-    interface Logger {
-
-        fun onSetVolumeRequested(audioStream: AudioStream, volume: Int)
-
-        fun onVolumeUpdateReceived(audioStream: AudioStream, model: AudioStreamModel)
-    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt
index 7a66335..ebba7f1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt
@@ -34,6 +34,7 @@
 import com.android.settingslib.bluetooth.onSourceConnectedOrRemoved
 import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MAX
 import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MIN
+import com.android.settingslib.volume.shared.AudioSharingLogger
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -50,6 +51,7 @@
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.runningFold
 import kotlinx.coroutines.flow.stateIn
@@ -90,6 +92,7 @@
     private val btManager: LocalBluetoothManager,
     private val coroutineScope: CoroutineScope,
     private val backgroundCoroutineContext: CoroutineContext,
+    private val logger: AudioSharingLogger
 ) : AudioSharingRepository {
     private val isAudioSharingProfilesReady: StateFlow<Boolean> =
         btManager.profileManager.onServiceStateChanged
@@ -104,6 +107,7 @@
                 btManager.profileManager.leAudioBroadcastProfile.onBroadcastStartedOrStopped
                     .map { isBroadcasting() }
                     .onStart { emit(isBroadcasting()) }
+                    .onEach { logger.onAudioSharingStateChanged(it) }
                     .flowOn(backgroundCoroutineContext)
             } else {
                 flowOf(false)
@@ -156,6 +160,7 @@
                 .map { getSecondaryGroupId() },
             primaryGroupId.map { getSecondaryGroupId() })
             .onStart { emit(getSecondaryGroupId()) }
+            .onEach { logger.onSecondaryGroupIdChanged(it) }
             .flowOn(backgroundCoroutineContext)
             .stateIn(
                 coroutineScope,
@@ -202,6 +207,7 @@
                             acc
                         }
                     }
+                    .onEach { logger.onVolumeMapChanged(it) }
                     .flowOn(backgroundCoroutineContext)
             } else {
                 emptyFlow()
@@ -220,6 +226,7 @@
                     BluetoothUtils.getSecondaryDeviceForBroadcast(contentResolver, btManager)
                 if (cachedDevice != null) {
                     it.setDeviceVolume(cachedDevice.device, volume, /* isGroupOp= */ true)
+                    logger.onSetDeviceVolumeRequested(volume)
                 }
             }
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/shared/AudioLogger.kt b/packages/SettingsLib/src/com/android/settingslib/volume/shared/AudioLogger.kt
new file mode 100644
index 0000000..84f7fcb
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/shared/AudioLogger.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.settingslib.volume.shared
+
+import com.android.settingslib.volume.shared.model.AudioStream
+import com.android.settingslib.volume.shared.model.AudioStreamModel
+
+/** A log interface for audio streams volume events. */
+interface AudioLogger {
+    fun onSetVolumeRequested(audioStream: AudioStream, volume: Int)
+
+    fun onVolumeUpdateReceived(audioStream: AudioStream, model: AudioStreamModel)
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/shared/AudioSharingLogger.kt b/packages/SettingsLib/src/com/android/settingslib/volume/shared/AudioSharingLogger.kt
new file mode 100644
index 0000000..18a4c6d
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/shared/AudioSharingLogger.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.settingslib.volume.shared
+
+/** A log interface for audio sharing volume events. */
+interface AudioSharingLogger {
+
+    fun onAudioSharingStateChanged(state: Boolean)
+
+    fun onSecondaryGroupIdChanged(groupId: Int)
+
+    fun onVolumeMapChanged(map: Map<Int, Int>)
+
+    fun onSetDeviceVolumeRequested(volume: Int)
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt
index 078f0c8..8c5a085 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt
@@ -48,6 +48,7 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
+import org.junit.After
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -101,7 +102,7 @@
 
     @Captor
     private lateinit var assistantCallbackCaptor:
-        ArgumentCaptor<BluetoothLeBroadcastAssistant.Callback>
+            ArgumentCaptor<BluetoothLeBroadcastAssistant.Callback>
 
     @Captor private lateinit var btCallbackCaptor: ArgumentCaptor<BluetoothCallback>
 
@@ -110,6 +111,7 @@
     @Captor
     private lateinit var volumeCallbackCaptor: ArgumentCaptor<BluetoothVolumeControl.Callback>
 
+    private val logger = FakeAudioSharingRepositoryLogger()
     private val testScope = TestScope()
     private val context: Context = ApplicationProvider.getApplicationContext()
     @Spy private val contentResolver: ContentResolver = context.contentResolver
@@ -135,16 +137,23 @@
         Settings.Secure.putInt(
             contentResolver,
             BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
-            TEST_GROUP_ID_INVALID)
+            TEST_GROUP_ID_INVALID
+        )
         underTest =
             AudioSharingRepositoryImpl(
                 contentResolver,
                 btManager,
                 testScope.backgroundScope,
                 testScope.testScheduler,
+                logger
             )
     }
 
+    @After
+    fun tearDown() {
+        logger.reset()
+    }
+
     @Test
     fun audioSharingStateChange_profileReady_emitValues() {
         testScope.runTest {
@@ -160,6 +169,13 @@
             runCurrent()
 
             Truth.assertThat(states).containsExactly(false, true, false, true)
+            Truth.assertThat(logger.logs)
+                .containsAtLeastElementsIn(
+                    listOf(
+                        "onAudioSharingStateChanged state=true",
+                        "onAudioSharingStateChanged state=false",
+                    )
+                ).inOrder()
         }
     }
 
@@ -187,7 +203,8 @@
             Truth.assertThat(groupIds)
                 .containsExactly(
                     TEST_GROUP_ID_INVALID,
-                    TEST_GROUP_ID2)
+                    TEST_GROUP_ID2
+                )
         }
     }
 
@@ -219,13 +236,16 @@
             triggerSourceAdded()
             runCurrent()
             triggerProfileConnectionChange(
-                BluetoothAdapter.STATE_CONNECTING, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)
+                BluetoothAdapter.STATE_CONNECTING, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT
+            )
             runCurrent()
             triggerProfileConnectionChange(
-                BluetoothAdapter.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO)
+                BluetoothAdapter.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO
+            )
             runCurrent()
             triggerProfileConnectionChange(
-                BluetoothAdapter.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT)
+                BluetoothAdapter.STATE_DISCONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT
+            )
             runCurrent()
 
             Truth.assertThat(groupIds)
@@ -235,7 +255,16 @@
                     TEST_GROUP_ID1,
                     TEST_GROUP_ID_INVALID,
                     TEST_GROUP_ID2,
-                    TEST_GROUP_ID_INVALID)
+                    TEST_GROUP_ID_INVALID
+                )
+            Truth.assertThat(logger.logs)
+                .containsAtLeastElementsIn(
+                    listOf(
+                        "onSecondaryGroupIdChanged groupId=$TEST_GROUP_ID_INVALID",
+                        "onSecondaryGroupIdChanged groupId=$TEST_GROUP_ID2",
+                        "onSecondaryGroupIdChanged groupId=$TEST_GROUP_ID1",
+                    )
+                ).inOrder()
         }
     }
 
@@ -257,11 +286,22 @@
             verify(volumeControl).unregisterCallback(any())
             runCurrent()
 
+            val expectedMap1 = mapOf(TEST_GROUP_ID1 to TEST_VOLUME1)
+            val expectedMap2 = mapOf(TEST_GROUP_ID1 to TEST_VOLUME2)
             Truth.assertThat(volumeMaps)
                 .containsExactly(
                     emptyMap<Int, Int>(),
-                    mapOf(TEST_GROUP_ID1 to TEST_VOLUME1),
-                    mapOf(TEST_GROUP_ID1 to TEST_VOLUME2))
+                    expectedMap1,
+                    expectedMap2
+                )
+            Truth.assertThat(logger.logs)
+                .containsAtLeastElementsIn(
+                    listOf(
+                        "onVolumeMapChanged map={}",
+                        "onVolumeMapChanged map=$expectedMap1",
+                        "onVolumeMapChanged map=$expectedMap2",
+                    )
+                ).inOrder()
         }
     }
 
@@ -281,12 +321,19 @@
             Settings.Secure.putInt(
                 contentResolver,
                 BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
-                TEST_GROUP_ID2)
+                TEST_GROUP_ID2
+            )
             `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2))
             underTest.setSecondaryVolume(TEST_VOLUME1)
 
             runCurrent()
             verify(volumeControl).setDeviceVolume(device1, TEST_VOLUME1, true)
+            Truth.assertThat(logger.logs)
+                .isEqualTo(
+                    listOf(
+                        "onSetVolumeRequested volume=$TEST_VOLUME1",
+                    )
+                )
         }
     }
 
@@ -313,7 +360,8 @@
         Settings.Secure.putInt(
             contentResolver,
             BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
-            TEST_GROUP_ID1)
+            TEST_GROUP_ID1
+        )
         `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2))
         assistantCallbackCaptor.value.sourceAdded(device1, receiveState)
     }
@@ -324,7 +372,8 @@
         Settings.Secure.putInt(
             contentResolver,
             BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
-            TEST_GROUP_ID1)
+            TEST_GROUP_ID1
+        )
         assistantCallbackCaptor.value.sourceRemoved(device2)
     }
 
@@ -334,7 +383,8 @@
         Settings.Secure.putInt(
             contentResolver,
             BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
-            TEST_GROUP_ID1)
+            TEST_GROUP_ID1
+        )
         btCallbackCaptor.value.onProfileConnectionStateChanged(cachedDevice2, state, profile)
     }
 
@@ -343,12 +393,14 @@
             .registerContentObserver(
                 eq(Settings.Secure.getUriFor(BluetoothUtils.getPrimaryGroupIdUriForBroadcast())),
                 eq(false),
-                contentObserverCaptor.capture())
+                contentObserverCaptor.capture()
+            )
         `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2))
         Settings.Secure.putInt(
             contentResolver,
             BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
-            TEST_GROUP_ID2)
+            TEST_GROUP_ID2
+        )
         contentObserverCaptor.value.primaryChanged()
     }
 
@@ -380,8 +432,9 @@
             onBroadcastStopped(TEST_REASON, TEST_BROADCAST_ID)
         }
         val sourceAdded:
-            BluetoothLeBroadcastAssistant.Callback.(
-                sink: BluetoothDevice, state: BluetoothLeBroadcastReceiveState) -> Unit =
+                BluetoothLeBroadcastAssistant.Callback.(
+                    sink: BluetoothDevice, state: BluetoothLeBroadcastReceiveState
+                ) -> Unit =
             { sink, state ->
                 onReceiveStateChanged(sink, TEST_SOURCE_ID, state)
             }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt
index 389bf53..bd573fb 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt
@@ -16,10 +16,11 @@
 
 package com.android.settingslib.volume.data.repository
 
+import com.android.settingslib.volume.shared.AudioLogger
 import com.android.settingslib.volume.shared.model.AudioStream
 import com.android.settingslib.volume.shared.model.AudioStreamModel
 
-class FakeAudioRepositoryLogger : AudioRepositoryImpl.Logger {
+class FakeAudioRepositoryLogger : AudioLogger {
 
     private val mutableLogs: MutableList<String> = mutableListOf()
     val logs: List<String>
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioSharingRepositoryLogger.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioSharingRepositoryLogger.kt
new file mode 100644
index 0000000..cc4cc8d
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioSharingRepositoryLogger.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.settingslib.volume.data.repository
+
+import com.android.settingslib.volume.shared.AudioSharingLogger
+import java.util.concurrent.CopyOnWriteArrayList
+
+class FakeAudioSharingRepositoryLogger : AudioSharingLogger {
+    private val mutableLogs = CopyOnWriteArrayList<String>()
+    val logs: List<String>
+        get() = mutableLogs.toList()
+
+    fun reset() {
+        mutableLogs.clear()
+    }
+
+    override fun onAudioSharingStateChanged(state: Boolean) {
+        mutableLogs.add("onAudioSharingStateChanged state=$state")
+    }
+
+    override fun onSecondaryGroupIdChanged(groupId: Int) {
+        mutableLogs.add("onSecondaryGroupIdChanged groupId=$groupId")
+    }
+
+    override fun onVolumeMapChanged(map: GroupIdToVolumes) {
+        mutableLogs.add("onVolumeMapChanged map=$map")
+    }
+
+    override fun onSetDeviceVolumeRequested(volume: Int) {
+        mutableLogs.add("onSetVolumeRequested volume=$volume")
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 7e7c76e..8cc9974 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -35,6 +35,7 @@
 import android.os.ParcelUuid;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -545,6 +546,7 @@
      * Test to verify OnDeviceUnpaired() for csip device unpair.
      */
     @Test
+    @Ignore("b/359066481")
     public void onDeviceUnpaired_unpairCsipSubDevice() {
         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
         when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java
index 194a0e2..4e54d8f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java
@@ -40,6 +40,7 @@
 import com.android.settingslib.testutils.shadow.ShadowInteractionJankMonitor;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -58,6 +59,7 @@
 
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {ShadowInteractionJankMonitor.class, SettingsJankMonitorTest.ShadowBuilder.class})
+@Ignore("b/359066481")
 public class SettingsJankMonitorTest {
     private static final String TEST_KEY = "key";
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java
index 0d318c3..325bb2c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java
@@ -36,6 +36,7 @@
 import com.android.settingslib.testutils.shadow.ShadowSmsApplication;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -86,6 +87,7 @@
         mPowerAllowlistBackend = new PowerAllowlistBackend(mContext, mDeviceIdleService);
     }
 
+    @Ignore("b/359066481")
     @Test
     public void testIsAllowlisted() throws Exception {
         doReturn(new String[] {PACKAGE_ONE}).when(mDeviceIdleService).getFullPowerWhitelist();
@@ -160,6 +162,7 @@
         assertThat(mPowerAllowlistBackend.isDefaultActiveApp(PACKAGE_ONE, UID)).isTrue();
     }
 
+    @Ignore("b/359066481")
     @Test
     public void testIsSystemAllowlisted() throws Exception {
         doReturn(new String[] {PACKAGE_ONE}).when(mDeviceIdleService).getSystemPowerWhitelist();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
index f0f53d6..7f4bdae 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BannerMessagePreferenceTest.java
@@ -44,6 +44,7 @@
 import com.android.settingslib.widget.preference.banner.R;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
@@ -53,6 +54,7 @@
 import org.robolectric.shadows.ShadowTouchDelegate;
 import org.robolectric.util.ReflectionHelpers;
 
+@Ignore("b/359066481")
 @RunWith(RobolectricTestRunner.class)
 public class BannerMessagePreferenceTest {
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 30c4ee5..9ab853f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -690,7 +690,7 @@
         Cursor cursor = getContentResolver().query(Settings.Global.CONTENT_URI, PROJECTION, null,
                 null, null);
         try {
-            return extractRelevantValues(cursor, GlobalSettings.SETTINGS_TO_BACKUP);
+            return extractRelevantValues(cursor, getGlobalSettingsToBackup());
         } finally {
             cursor.close();
         }
@@ -1011,7 +1011,7 @@
                     Settings.System.LEGACY_RESTORE_SETTINGS);
             validators = SystemSettingsValidators.VALIDATORS;
         } else if (contentUri.equals(Settings.Global.CONTENT_URI)) {
-            whitelist = ArrayUtils.concat(String.class, GlobalSettings.SETTINGS_TO_BACKUP,
+            whitelist = ArrayUtils.concat(String.class, getGlobalSettingsToBackup(),
                     Settings.Global.LEGACY_RESTORE_SETTINGS);
             validators = GlobalSettingsValidators.VALIDATORS;
         } else {
@@ -1021,6 +1021,17 @@
         return new SettingsBackupWhitelist(whitelist, validators);
     }
 
+    private String[] getGlobalSettingsToBackup() {
+        // On watches, we don't want to backup or restore 'bluetooth_on' setting, as setting it to
+        // false during restore would cause watch OOBE to fail due to bluetooth connection loss.
+        if (isWatch()) {
+            return ArrayUtils.removeElement(
+                    String.class, GlobalSettings.SETTINGS_TO_BACKUP, Settings.Global.BLUETOOTH_ON);
+        }
+
+        return GlobalSettings.SETTINGS_TO_BACKUP;
+    }
+
     private boolean isBlockedByDynamicList(Set<String> dynamicBlockList, Uri areaUri, String key) {
         String contentKey = Uri.withAppendedPath(areaUri, key).toString();
         return dynamicBlockList.contains(contentKey);
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
index d4ca4a3..3a391505 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
@@ -26,6 +26,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.net.Uri;
@@ -221,6 +222,21 @@
     }
 
     @Test
+    public void testOnRestore_bluetoothOnRestoredOnNonWearablesOnly() {
+        TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+        mAgentUnderTest.mSettingsHelper = settingsHelper;
+
+        restoreGlobalSettings(generateBackupData(Map.of(Settings.Global.BLUETOOTH_ON, "0")));
+
+        var isWatch = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+        if (isWatch) {
+            assertFalse(settingsHelper.mWrittenValues.containsKey(Settings.Global.BLUETOOTH_ON));
+        } else {
+            assertEquals("0", settingsHelper.mWrittenValues.get(Settings.Global.BLUETOOTH_ON));
+        }
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_CONFIGURABLE_FONT_SCALE_DEFAULT)
     public void testFindClosestAllowedFontScale() {
         final String[] availableFontScales = new String[]{"0.5", "0.9", "1.0", "1.1", "1.5"};
@@ -266,6 +282,20 @@
         return buffer.array();
     }
 
+    private void restoreGlobalSettings(byte[] backupData) {
+        mAgentUnderTest.restoreSettings(
+                backupData,
+                /* pos= */ 0,
+                backupData.length,
+                Settings.Global.CONTENT_URI,
+                null,
+                null,
+                null,
+                R.array.restore_blocked_global_settings,
+                /* dynamicBlockList= */ Collections.emptySet(),
+                /* settingsToPreserve= */ Collections.emptySet());
+    }
+
     private byte[] generateUncorruptedHeader() throws IOException {
         try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
             mAgentUnderTest.writeHeader(os);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 9f3c2bf..1d9f469 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -482,6 +482,15 @@
             android:exported="true"
             android:theme="@style/Theme.AppCompat.NoActionBar">
             <intent-filter>
+                <action android:name="com.android.systemui.action.TOUCHPAD_TUTORIAL"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity"
+            android:exported="true"
+            android:theme="@style/Theme.AppCompat.NoActionBar">
+            <intent-filter>
                 <action android:name="com.android.systemui.action.TOUCHPAD_KEYBOARD_TUTORIAL"/>
                 <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 1ff9a80..0314992 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1237,6 +1237,16 @@
 }
 
 flag {
+   name: "relock_with_power_button_immediately"
+   namespace: "systemui"
+   description: "UDFPS unlock followed by immediate power button push should relock"
+   bug: "343327511"
+   metadata {
+        purpose: PURPOSE_BUGFIX
+   }
+}
+
+flag {
    name: "lockscreen_preview_renderer_create_on_main_thread"
    namespace: "systemui"
    description: "Force preview renderer to be created on the main thread"
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
index 26ab10b..85d5d6a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarousel.kt
@@ -24,9 +24,11 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.approachLayout
 import androidx.compose.ui.layout.layout
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.viewinterop.AndroidView
 import com.android.compose.animation.scene.MovableElementKey
 import com.android.compose.animation.scene.SceneScope
@@ -51,6 +53,7 @@
     mediaHost: MediaHost,
     modifier: Modifier = Modifier,
     carouselController: MediaCarouselController,
+    offsetProvider: (() -> IntOffset)? = null,
 ) {
     if (!isVisible) {
         return
@@ -68,21 +71,38 @@
 
     MovableElement(
         key = MediaCarousel.Elements.Content,
-        modifier = modifier.height(mediaHeight).fillMaxWidth()
+        modifier = modifier.height(mediaHeight).fillMaxWidth(),
     ) {
         content {
             AndroidView(
                 modifier =
-                    Modifier.fillMaxSize().layout { measurable, constraints ->
-                        val placeable = measurable.measure(constraints)
+                    Modifier.fillMaxSize()
+                        .approachLayout(
+                            isMeasurementApproachInProgress = { offsetProvider != null },
+                            approachMeasure = { measurable, constraints ->
+                                val placeable = measurable.measure(constraints)
+                                layout(placeable.width, placeable.height) {
+                                    placeable.placeRelative(
+                                        offsetProvider?.invoke() ?: IntOffset.Zero
+                                    )
+                                }
+                            }
+                        )
+                        .layout { measurable, constraints ->
+                            val placeable = measurable.measure(constraints)
 
-                        // Notify controller to size the carousel for the current space
-                        mediaHost.measurementInput =
-                            MeasurementInput(placeable.width, placeable.height)
-                        carouselController.setSceneContainerSize(placeable.width, placeable.height)
+                            // Notify controller to size the carousel for the current space
+                            mediaHost.measurementInput =
+                                MeasurementInput(placeable.width, placeable.height)
+                            carouselController.setSceneContainerSize(
+                                placeable.width,
+                                placeable.height
+                            )
 
-                        layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }
-                    },
+                            layout(placeable.width, placeable.height) {
+                                placeable.placeRelative(0, 0)
+                            }
+                        },
                 factory = { context ->
                     FrameLayout(context).apply {
                         layoutParams =
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt
index 3f04f37..70c0db1 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt
@@ -27,7 +27,6 @@
 /** [ElementContentPicker] implementation for the media carousel object. */
 object MediaContentPicker : StaticElementContentPicker {
 
-    const val SHADE_FRACTION = 0.66f
     override val contents =
         setOf(
             Scenes.Lockscreen,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt
index a9da733..71fa6c9 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToSplitShadeTransition.kt
@@ -25,7 +25,6 @@
 import com.android.compose.animation.scene.UserActionDistance
 import com.android.compose.animation.scene.UserActionDistanceScope
 import com.android.systemui.media.controls.ui.composable.MediaCarousel
-import com.android.systemui.media.controls.ui.composable.MediaContentPicker
 import com.android.systemui.notifications.ui.composable.Notifications
 import com.android.systemui.qs.ui.composable.QuickSettings
 import com.android.systemui.shade.ui.composable.Shade
@@ -54,13 +53,7 @@
     fractionRange(end = .33f) { fade(Shade.Elements.BackgroundScrim) }
 
     fractionRange(start = .33f) {
-        val qsTranslation =
-            ShadeHeader.Dimensions.CollapsedHeight * MediaContentPicker.SHADE_FRACTION
-        val qsExpansionDiff =
-            ShadeHeader.Dimensions.ExpandedHeight - ShadeHeader.Dimensions.CollapsedHeight
-        translate(MediaCarousel.Elements.Content, y = -(qsExpansionDiff + qsTranslation))
         fade(MediaCarousel.Elements.Content)
-
         fade(ShadeHeader.Elements.Clock)
         fade(ShadeHeader.Elements.CollapsedContentStart)
         fade(ShadeHeader.Elements.CollapsedContentEnd)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToShadeTransition.kt
index 21dfc49..b677dff 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToShadeTransition.kt
@@ -26,7 +26,6 @@
 import com.android.compose.animation.scene.UserActionDistance
 import com.android.compose.animation.scene.UserActionDistanceScope
 import com.android.systemui.media.controls.ui.composable.MediaCarousel
-import com.android.systemui.media.controls.ui.composable.MediaContentPicker
 import com.android.systemui.notifications.ui.composable.Notifications
 import com.android.systemui.qs.ui.composable.QuickSettings
 import com.android.systemui.scene.shared.model.Scenes
@@ -62,12 +61,9 @@
         fade(QuickSettings.Elements.FooterActions)
     }
 
-    val qsTranslation = ShadeHeader.Dimensions.CollapsedHeight * MediaContentPicker.SHADE_FRACTION
-    val qsExpansionDiff =
-        ShadeHeader.Dimensions.ExpandedHeight - ShadeHeader.Dimensions.CollapsedHeight
-
-    translate(QuickSettings.Elements.QuickQuickSettings, y = -qsTranslation)
-    translate(MediaCarousel.Elements.Content, y = -(qsExpansionDiff + qsTranslation))
+    val qsTranslation = -ShadeHeader.Dimensions.CollapsedHeight * 0.66f
+    translate(QuickSettings.Elements.QuickQuickSettings, y = qsTranslation)
+    translate(MediaCarousel.Elements.Content, y = qsTranslation)
     translate(Notifications.Elements.NotificationScrim, Edge.Top, false)
 }
 
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeMediaOffsetProvider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeMediaOffsetProvider.kt
new file mode 100644
index 0000000..e0b7909
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeMediaOffsetProvider.kt
@@ -0,0 +1,79 @@
+/*
+ * 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.systemui.shade.ui.composable
+
+import androidx.compose.ui.unit.IntOffset
+import com.android.systemui.qs.ui.adapter.QSSceneAdapter
+
+/**
+ * Provider for the extra offset for the Media section in the shade to accommodate for the squishing
+ * qs or qqs tiles.
+ */
+interface ShadeMediaOffsetProvider {
+
+    /** Returns current offset to be applied to the Media Carousel */
+    val offset: IntOffset
+
+    /**
+     * [ShadeMediaOffsetProvider] implementation for Quick Settings.
+     *
+     * [updateLayout] should represent an access to some state to trigger Compose to relayout to
+     * track [QSSceneAdapter] internal state changes during the transition.
+     */
+    class Qs(private val updateLayout: () -> Unit, private val qsSceneAdapter: QSSceneAdapter) :
+        ShadeMediaOffsetProvider {
+
+        override val offset: IntOffset
+            get() =
+                calculateQsOffset(
+                    updateLayout,
+                    qsSceneAdapter.qsHeight,
+                    qsSceneAdapter.squishedQsHeight
+                )
+    }
+
+    /**
+     * [ShadeMediaOffsetProvider] implementation for Quick Quick Settings.
+     *
+     * [updateLayout] should represent an access to some state to trigger Compose to relayout to
+     * track [QSSceneAdapter] internal state changes during the transition.
+     */
+    class Qqs(private val updateLayout: () -> Unit, private val qsSceneAdapter: QSSceneAdapter) :
+        ShadeMediaOffsetProvider {
+
+        override val offset: IntOffset
+            get() =
+                calculateQsOffset(
+                    updateLayout,
+                    qsSceneAdapter.qqsHeight,
+                    qsSceneAdapter.squishedQqsHeight
+                )
+    }
+
+    companion object {
+
+        protected fun calculateQsOffset(
+            updateLayout: () -> Unit,
+            qsHeight: Int,
+            qsSquishedHeight: Int
+        ): IntOffset {
+            updateLayout()
+            val distanceFromBottomToActualBottom = qsHeight - qsSquishedHeight
+            return IntOffset(0, -distanceFromBottomToActualBottom)
+        }
+    }
+}
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 0e3fcf4..16972bc 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
@@ -118,7 +118,6 @@
 
 object Shade {
     object Elements {
-        val MediaCarousel = ElementKey("ShadeMediaCarousel")
         val BackgroundScrim =
             ElementKey("ShadeBackgroundScrim", contentPicker = LowestZIndexContentPicker)
         val SplitShadeStartColumn = ElementKey("SplitShadeStartColumn")
@@ -283,6 +282,13 @@
 
     val navBarHeight = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
 
+    val mediaOffsetProvider = remember {
+        ShadeMediaOffsetProvider.Qqs(
+            { @Suppress("UNUSED_EXPRESSION") tileSquishiness },
+            viewModel.qsSceneAdapter,
+        )
+    }
+
     Box(
         modifier =
             modifier.thenIf(shouldPunchHoleBehindScrim) {
@@ -335,12 +341,12 @@
                                     )
                                 }
 
-                                MediaCarousel(
+                                ShadeMediaCarousel(
                                     isVisible = isMediaVisible,
                                     mediaHost = mediaHost,
+                                    mediaOffsetProvider = mediaOffsetProvider,
                                     modifier =
-                                        Modifier.fillMaxWidth()
-                                            .layoutId(QSMediaMeasurePolicy.LayoutId.Media),
+                                        Modifier.layoutId(QSMediaMeasurePolicy.LayoutId.Media),
                                     carouselController = mediaCarouselController,
                                 )
                             }
@@ -497,6 +503,13 @@
 
     val brightnessMirrorShowingModifier = Modifier.graphicsLayer { alpha = contentAlpha }
 
+    val mediaOffsetProvider = remember {
+        ShadeMediaOffsetProvider.Qs(
+            { @Suppress("UNUSED_EXPRESSION") tileSquishiness },
+            viewModel.qsSceneAdapter,
+        )
+    }
+
     Box {
         Box(
             modifier =
@@ -570,11 +583,13 @@
                                     squishiness = { tileSquishiness },
                                 )
                             }
-                            MediaCarousel(
+
+                            ShadeMediaCarousel(
                                 isVisible = isMediaVisible,
                                 mediaHost = mediaHost,
+                                mediaOffsetProvider = mediaOffsetProvider,
                                 modifier =
-                                    Modifier.fillMaxWidth().thenIf(
+                                    Modifier.thenIf(
                                         MediaContentPicker.shouldElevateMedia(layoutState)
                                     ) {
                                         Modifier.zIndex(1f)
@@ -620,3 +635,25 @@
         )
     }
 }
+
+@Composable
+private fun SceneScope.ShadeMediaCarousel(
+    isVisible: Boolean,
+    mediaHost: MediaHost,
+    carouselController: MediaCarouselController,
+    mediaOffsetProvider: ShadeMediaOffsetProvider,
+    modifier: Modifier = Modifier,
+) {
+    MediaCarousel(
+        modifier = modifier.fillMaxWidth(),
+        isVisible = isVisible,
+        mediaHost = mediaHost,
+        carouselController = carouselController,
+        offsetProvider =
+            if (MediaContentPicker.shouldElevateMedia(layoutState)) {
+                null
+            } else {
+                { mediaOffsetProvider.offset }
+            }
+    )
+}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
index e13ca391..ae5a84b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
@@ -120,7 +120,7 @@
 }
 
 @Deprecated(
-    "Use animateSceneFloatAsState() instead",
+    "Use animateContentFloatAsState() instead",
     replaceWith = ReplaceWith("animateContentFloatAsState(value, key, canOverflow)")
 )
 @Composable
@@ -171,7 +171,7 @@
 }
 
 @Deprecated(
-    "Use animateSceneDpAsState() instead",
+    "Use animateContentDpAsState() instead",
     replaceWith = ReplaceWith("animateContentDpAsState(value, key, canOverflow)")
 )
 @Composable
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index a43028a..712fe6b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -459,38 +459,11 @@
 
             animateTo(targetScene = targetScene, targetOffset = targetOffset)
         } else {
-            // We are doing an overscroll animation between scenes. In this case, we can also start
-            // from the idle position.
-
-            val startFromIdlePosition = swipeTransition.dragOffset == 0f
-
-            if (startFromIdlePosition) {
-                // If there is a target scene, we start the overscroll animation.
-                val result = swipes.findUserActionResultStrict(velocity)
-                if (result == null) {
-                    // We will not animate
-                    swipeTransition.snapToScene(fromScene.key)
-                    return 0f
-                }
-
-                val newSwipeTransition =
-                    SwipeTransition(
-                            layoutState = layoutState,
-                            coroutineScope = draggableHandler.coroutineScope,
-                            fromScene = fromScene,
-                            result = result,
-                            swipes = swipes,
-                            layoutImpl = draggableHandler.layoutImpl,
-                            orientation = draggableHandler.orientation,
-                        )
-                        .apply { _currentScene = swipeTransition._currentScene }
-
-                updateTransition(newSwipeTransition)
-                animateTo(targetScene = fromScene, targetOffset = 0f)
-            } else {
-                // We were between two scenes: animate to the initial scene.
-                animateTo(targetScene = fromScene, targetOffset = 0f)
+            // We are doing an overscroll preview animation between scenes.
+            check(fromScene == swipeTransition._currentScene) {
+                "canChangeScene is false but currentScene != fromScene"
             }
+            animateTo(targetScene = fromScene, targetOffset = 0f)
         }
 
         // The onStop animation consumes any remaining velocity.
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
index a30b780..79b3856 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
@@ -17,6 +17,8 @@
 package com.android.compose.animation.scene
 
 import androidx.compose.animation.core.AnimationSpec
+import androidx.compose.animation.core.Easing
+import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.SpringSpec
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.ui.geometry.Offset
@@ -140,6 +142,7 @@
     fun fractionRange(
         start: Float? = null,
         end: Float? = null,
+        easing: Easing = LinearEasing,
         builder: PropertyTransformationBuilder.() -> Unit,
     )
 }
@@ -182,6 +185,7 @@
     fun timestampRange(
         startMillis: Int? = null,
         endMillis: Int? = null,
+        easing: Easing = LinearEasing,
         builder: PropertyTransformationBuilder.() -> Unit,
     )
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
index 6515cb8..a63b19a 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.animation.core.AnimationSpec
 import androidx.compose.animation.core.DurationBasedAnimationSpec
+import androidx.compose.animation.core.Easing
 import androidx.compose.animation.core.Spring
 import androidx.compose.animation.core.SpringSpec
 import androidx.compose.animation.core.VectorConverter
@@ -163,9 +164,10 @@
     override fun fractionRange(
         start: Float?,
         end: Float?,
+        easing: Easing,
         builder: PropertyTransformationBuilder.() -> Unit
     ) {
-        range = TransformationRange(start, end)
+        range = TransformationRange(start, end, easing)
         builder()
         range = null
     }
@@ -251,6 +253,7 @@
     override fun timestampRange(
         startMillis: Int?,
         endMillis: Int?,
+        easing: Easing,
         builder: PropertyTransformationBuilder.() -> Unit
     ) {
         if (startMillis != null && (startMillis < 0 || startMillis > durationMillis)) {
@@ -263,7 +266,7 @@
 
         val start = startMillis?.let { it.toFloat() / durationMillis }
         val end = endMillis?.let { it.toFloat() / durationMillis }
-        fractionRange(start, end, builder)
+        fractionRange(start, end, easing, builder)
     }
 }
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
index 77ec891..eda8ede 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt
@@ -16,6 +16,8 @@
 
 package com.android.compose.animation.scene.transformation
 
+import androidx.compose.animation.core.Easing
+import androidx.compose.animation.core.LinearEasing
 import androidx.compose.ui.util.fastCoerceAtLeast
 import androidx.compose.ui.util.fastCoerceAtMost
 import androidx.compose.ui.util.fastCoerceIn
@@ -90,11 +92,13 @@
 data class TransformationRange(
     val start: Float,
     val end: Float,
+    val easing: Easing,
 ) {
     constructor(
         start: Float? = null,
-        end: Float? = null
-    ) : this(start ?: BoundUnspecified, end ?: BoundUnspecified)
+        end: Float? = null,
+        easing: Easing = LinearEasing,
+    ) : this(start ?: BoundUnspecified, end ?: BoundUnspecified, easing)
 
     init {
         require(!start.isSpecified() || (start in 0f..1f))
@@ -103,17 +107,20 @@
     }
 
     /** Reverse this range. */
-    fun reversed() = TransformationRange(start = reverseBound(end), end = reverseBound(start))
+    fun reversed() =
+        TransformationRange(start = reverseBound(end), end = reverseBound(start), easing = easing)
 
     /** Get the progress of this range given the global [transitionProgress]. */
     fun progress(transitionProgress: Float): Float {
-        return when {
-            start.isSpecified() && end.isSpecified() ->
-                ((transitionProgress - start) / (end - start)).fastCoerceIn(0f, 1f)
-            !start.isSpecified() && !end.isSpecified() -> transitionProgress
-            end.isSpecified() -> (transitionProgress / end).fastCoerceAtMost(1f)
-            else -> ((transitionProgress - start) / (1f - start)).fastCoerceAtLeast(0f)
-        }
+        val progress =
+            when {
+                start.isSpecified() && end.isSpecified() ->
+                    ((transitionProgress - start) / (end - start)).fastCoerceIn(0f, 1f)
+                !start.isSpecified() && !end.isSpecified() -> transitionProgress
+                end.isSpecified() -> (transitionProgress / end).fastCoerceAtMost(1f)
+                else -> ((transitionProgress - start) / (1f - start)).fastCoerceAtLeast(0f)
+            }
+        return easing.transform(progress)
     }
 
     private fun Float.isSpecified() = this != BoundUnspecified
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
index 68240b5..bed6cef 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.compose.animation.scene
 
+import androidx.compose.animation.core.CubicBezierEasing
 import androidx.compose.animation.core.SpringSpec
 import androidx.compose.animation.core.TweenSpec
 import androidx.compose.animation.core.spring
@@ -107,6 +108,13 @@
                 fractionRange(start = 0.1f, end = 0.8f) { fade(TestElements.Foo) }
                 fractionRange(start = 0.2f) { fade(TestElements.Foo) }
                 fractionRange(end = 0.9f) { fade(TestElements.Foo) }
+                fractionRange(
+                    start = 0.1f,
+                    end = 0.8f,
+                    easing = CubicBezierEasing(0.1f, 0.1f, 0f, 1f)
+                ) {
+                    fade(TestElements.Foo)
+                }
             }
         }
 
@@ -118,6 +126,11 @@
                 TransformationRange(start = 0.1f, end = 0.8f),
                 TransformationRange(start = 0.2f, end = TransformationRange.BoundUnspecified),
                 TransformationRange(start = TransformationRange.BoundUnspecified, end = 0.9f),
+                TransformationRange(
+                    start = 0.1f,
+                    end = 0.8f,
+                    CubicBezierEasing(0.1f, 0.1f, 0f, 1f)
+                ),
             )
     }
 
@@ -130,6 +143,13 @@
                 timestampRange(startMillis = 100, endMillis = 300) { fade(TestElements.Foo) }
                 timestampRange(startMillis = 200) { fade(TestElements.Foo) }
                 timestampRange(endMillis = 400) { fade(TestElements.Foo) }
+                timestampRange(
+                    startMillis = 100,
+                    endMillis = 300,
+                    easing = CubicBezierEasing(0.1f, 0.1f, 0f, 1f)
+                ) {
+                    fade(TestElements.Foo)
+                }
             }
         }
 
@@ -141,6 +161,11 @@
                 TransformationRange(start = 100 / 500f, end = 300 / 500f),
                 TransformationRange(start = 200 / 500f, end = TransformationRange.BoundUnspecified),
                 TransformationRange(start = TransformationRange.BoundUnspecified, end = 400 / 500f),
+                TransformationRange(
+                    start = 100 / 500f,
+                    end = 300 / 500f,
+                    easing = CubicBezierEasing(0.1f, 0.1f, 0f, 1f)
+                ),
             )
     }
 
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/EasingTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/EasingTest.kt
new file mode 100644
index 0000000..07901f2
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/transformation/EasingTest.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.animation.scene.transformation
+
+import androidx.compose.animation.core.CubicBezierEasing
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.size
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.unit.dp
+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.test.assertSizeIsEqualTo
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class EasingTest {
+    @get:Rule val rule = createComposeRule()
+
+    @Test
+    fun testFractionRangeEasing() {
+        val easing = CubicBezierEasing(0.1f, 0.1f, 0f, 1f)
+        rule.testTransition(
+            fromSceneContent = { Box(Modifier.size(100.dp).element(TestElements.Foo)) },
+            toSceneContent = { Box(Modifier.size(100.dp).element(TestElements.Bar)) },
+            transition = {
+                // Scale during 4 frames.
+                spec = tween(16 * 4, easing = LinearEasing)
+                fractionRange(easing = easing) {
+                    scaleSize(TestElements.Foo, width = 0f, height = 0f)
+                    scaleSize(TestElements.Bar, width = 0f, height = 0f)
+                }
+            },
+        ) {
+            // Foo is entering, is 100dp x 100dp at rest and is scaled by (2, 0.5) during the
+            // transition so it starts at 200dp x 50dp.
+            before { onElement(TestElements.Bar).assertDoesNotExist() }
+            at(0) {
+                onElement(TestElements.Foo).assertSizeIsEqualTo(100.dp, 100.dp)
+                onElement(TestElements.Bar).assertSizeIsEqualTo(0.dp, 0.dp)
+            }
+            at(16) {
+                // 25% linear progress is mapped to 68.5% eased progress
+                onElement(TestElements.Foo).assertSizeIsEqualTo(31.5.dp, 31.5.dp)
+                onElement(TestElements.Bar).assertSizeIsEqualTo(68.5.dp, 68.5.dp)
+            }
+            at(32) {
+                // 50% linear progress is mapped to 89.5% eased progress
+                onElement(TestElements.Foo).assertSizeIsEqualTo(10.5.dp, 10.5.dp)
+                onElement(TestElements.Bar).assertSizeIsEqualTo(89.5.dp, 89.5.dp)
+            }
+            at(48) {
+                // 75% linear progress is mapped to 97.8% eased progress
+                onElement(TestElements.Foo).assertSizeIsEqualTo(2.2.dp, 2.2.dp)
+                onElement(TestElements.Bar).assertSizeIsEqualTo(97.8.dp, 97.8.dp)
+            }
+            after {
+                onElement(TestElements.Foo).assertDoesNotExist()
+                onElement(TestElements.Bar).assertSizeIsEqualTo(100.dp, 100.dp)
+            }
+        }
+    }
+
+    @Test
+    fun testTimestampRangeEasing() {
+        val easing = CubicBezierEasing(0.1f, 0.1f, 0f, 1f)
+        rule.testTransition(
+            fromSceneContent = { Box(Modifier.size(100.dp).element(TestElements.Foo)) },
+            toSceneContent = { Box(Modifier.size(100.dp).element(TestElements.Bar)) },
+            transition = {
+                // Scale during 4 frames.
+                spec = tween(16 * 4, easing = LinearEasing)
+                timestampRange(easing = easing) {
+                    scaleSize(TestElements.Foo, width = 0f, height = 0f)
+                    scaleSize(TestElements.Bar, width = 0f, height = 0f)
+                }
+            },
+        ) {
+            // Foo is entering, is 100dp x 100dp at rest and is scaled by (2, 0.5) during the
+            // transition so it starts at 200dp x 50dp.
+            before { onElement(TestElements.Bar).assertDoesNotExist() }
+            at(0) {
+                onElement(TestElements.Foo).assertSizeIsEqualTo(100.dp, 100.dp)
+                onElement(TestElements.Bar).assertSizeIsEqualTo(0.dp, 0.dp)
+            }
+            at(16) {
+                // 25% linear progress is mapped to 68.5% eased progress
+                onElement(TestElements.Foo).assertSizeIsEqualTo(31.5.dp, 31.5.dp)
+                onElement(TestElements.Bar).assertSizeIsEqualTo(68.5.dp, 68.5.dp)
+            }
+            at(32) {
+                // 50% linear progress is mapped to 89.5% eased progress
+                onElement(TestElements.Foo).assertSizeIsEqualTo(10.5.dp, 10.5.dp)
+                onElement(TestElements.Bar).assertSizeIsEqualTo(89.5.dp, 89.5.dp)
+            }
+            at(48) {
+                // 75% linear progress is mapped to 97.8% eased progress
+                onElement(TestElements.Foo).assertSizeIsEqualTo(2.2.dp, 2.2.dp)
+                onElement(TestElements.Bar).assertSizeIsEqualTo(97.8.dp, 97.8.dp)
+            }
+            after {
+                onElement(TestElements.Foo).assertDoesNotExist()
+                onElement(TestElements.Bar).assertSizeIsEqualTo(100.dp, 100.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 0242c2d..e57a4cb 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
@@ -1039,6 +1039,22 @@
             assertThat(showCommunalFromOccluded).isTrue()
         }
 
+    @Test
+    fun showCommunalFromOccluded_enteredOccludedFromDreaming() =
+        testScope.runTest {
+            kosmos.setCommunalAvailable(true)
+            val showCommunalFromOccluded by collectLastValue(underTest.showCommunalFromOccluded)
+            assertThat(showCommunalFromOccluded).isFalse()
+
+            kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+                from = KeyguardState.DREAMING,
+                to = KeyguardState.OCCLUDED,
+                testScope
+            )
+
+            assertThat(showCommunalFromOccluded).isTrue()
+        }
+
     private fun smartspaceTimer(id: String, timestamp: Long = 0L): CommunalSmartspaceTimer {
         return CommunalSmartspaceTimer(
             smartspaceTargetId = id,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt
index 4a10d80..8e4876d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModelTest.kt
@@ -42,6 +42,28 @@
     val underTest = kosmos.dozingToLockscreenTransitionViewModel
 
     @Test
+    fun lockscreenAlpha() =
+        testScope.runTest {
+            val lockscreenAlpha by collectValues(underTest.lockscreenAlpha)
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            repository.sendTransitionStep(step(0.1f))
+            repository.sendTransitionStep(step(0.5f))
+            repository.sendTransitionStep(step(1f))
+            lockscreenAlpha.forEach { assertThat(it).isEqualTo(1f) }
+        }
+
+    @Test
+    fun shortcutsAlpha() =
+        testScope.runTest {
+            val shortcutsAlpha by collectValues(underTest.shortcutsAlpha)
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            repository.sendTransitionStep(step(0.5f))
+            repository.sendTransitionStep(step(1f))
+            assertThat(shortcutsAlpha[0]).isEqualTo(0f)
+            assertThat(shortcutsAlpha[1]).isEqualTo(1f)
+        }
+
+    @Test
     fun deviceEntryParentViewShows() =
         testScope.runTest {
             val deviceEntryParentViewAlpha by collectValues(underTest.deviceEntryParentViewAlpha)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index f26c39d..2dfff3f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -32,6 +32,7 @@
 import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
 import com.android.systemui.authentication.domain.interactor.authenticationInteractor
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
 import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
 import com.android.systemui.bouncer.shared.logging.BouncerUiEvent
 import com.android.systemui.classifier.FalsingCollector
@@ -109,6 +110,7 @@
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
     private val bouncerInteractor by lazy { kosmos.bouncerInteractor }
     private val faceAuthRepository by lazy { kosmos.fakeDeviceEntryFaceAuthRepository }
+    private val bouncerRepository by lazy { kosmos.fakeKeyguardBouncerRepository }
     private val sysUiState = kosmos.sysUiState
     private val falsingCollector = mock<FalsingCollector>().also { kosmos.falsingCollector = it }
     private val fakeSceneDataSource = kosmos.fakeSceneDataSource
@@ -275,6 +277,66 @@
         }
 
     @Test
+    fun switchFromLockscreenToGoneAndHideAltBouncerWhenDeviceUnlocked() =
+        testScope.runTest {
+            val alternateBouncerVisible by
+                collectLastValue(bouncerRepository.alternateBouncerVisible)
+            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+
+            bouncerRepository.setAlternateVisible(true)
+            assertThat(alternateBouncerVisible).isTrue()
+
+            prepareState(
+                authenticationMethod = AuthenticationMethodModel.Pin,
+                isDeviceUnlocked = false,
+                initialSceneKey = Scenes.Lockscreen,
+            )
+            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
+            underTest.start()
+
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+
+            assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
+            assertThat(alternateBouncerVisible).isFalse()
+        }
+
+    @Test
+    fun stayOnCurrentSceneAndHideAltBouncerWhenDeviceUnlocked_whenLeaveOpenShade() =
+        testScope.runTest {
+            val alternateBouncerVisible by
+                collectLastValue(bouncerRepository.alternateBouncerVisible)
+            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+
+            kosmos.sysuiStatusBarStateController.leaveOpen = true // leave shade open
+            bouncerRepository.setAlternateVisible(true)
+            assertThat(alternateBouncerVisible).isTrue()
+
+            val transitionState =
+                prepareState(
+                    authenticationMethod = AuthenticationMethodModel.Pin,
+                    isDeviceUnlocked = false,
+                    initialSceneKey = Scenes.Lockscreen,
+                )
+            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
+            underTest.start()
+            runCurrent()
+
+            sceneInteractor.changeScene(Scenes.QuickSettings, "switching to qs for test")
+            transitionState.value = ObservableTransitionState.Idle(Scenes.QuickSettings)
+            runCurrent()
+            assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings)
+
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+
+            assertThat(currentSceneKey).isEqualTo(Scenes.QuickSettings)
+            assertThat(alternateBouncerVisible).isFalse()
+        }
+
+    @Test
     fun switchFromBouncerToQuickSettingsWhenDeviceUnlocked_whenLeaveOpenShade() =
         testScope.runTest {
             val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
diff --git a/packages/SystemUI/res/layout/media_projection_app_selector.xml b/packages/SystemUI/res/layout/media_projection_app_selector.xml
index b77f78d..3b6a64f 100644
--- a/packages/SystemUI/res/layout/media_projection_app_selector.xml
+++ b/packages/SystemUI/res/layout/media_projection_app_selector.xml
@@ -37,6 +37,7 @@
         android:background="@*android:drawable/bottomsheet_background">
 
         <ImageView
+            android:id="@+id/media_projection_app_selector_icon"
             android:layout_width="@dimen/media_projection_app_selector_icon_size"
             android:layout_height="@dimen/media_projection_app_selector_icon_size"
             android:layout_marginTop="@*android:dimen/chooser_edge_margin_normal"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 2ad6b6a..f8303ea 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -291,6 +291,8 @@
     <string name="screenrecord_permission_dialog_warning_single_app">When you’re recording an app, anything shown or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
     <!-- Button to start a screen recording of the entire screen in the updated screen record dialog that allows to select an app to record [CHAR LIMIT=50]-->
     <string name="screenrecord_permission_dialog_continue_entire_screen">Record screen</string>
+    <!-- Title of the activity that allows to select an app to screen record [CHAR LIMIT=70] -->
+    <string name="screenrecord_app_selector_title">Choose app to record</string>
 
     <!-- Label for a switch to enable recording audio [CHAR LIMIT=NONE]-->
     <string name="screenrecord_audio_label">Record audio</string>
@@ -1362,8 +1364,8 @@
     <!-- Media projection permission dialog warning text for system services. [CHAR LIMIT=NONE] -->
     <string name="media_projection_sys_service_dialog_warning">The service providing this function will have access to all of the information that is visible on your screen or played from your device while recording or casting. This includes information such as passwords, payment details, photos, messages, and audio that you play.</string>
 
-    <!-- Title of the dialog that allows to select an app to share or record [CHAR LIMIT=NONE] -->
-    <string name="screen_share_permission_app_selector_title">Share or record an app</string>
+    <!-- Title of the activity that allows users to select an app to share or record [CHAR LIMIT=NONE] -->
+    <string name="screen_share_generic_app_selector_title">Share or record an app</string>
 
     <!-- Media projection that launched from 1P/3P apps -->
     <!-- 1P/3P app media projection permission dialog title. [CHAR LIMIT=NONE] -->
@@ -1381,6 +1383,8 @@
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen">Share screen</string>
     <!-- 1P/3P apps disabled the single app projection option. [CHAR LIMIT=NONE] -->
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled"><xliff:g id="app_name" example="Meet">%1$s</xliff:g> has disabled this option</string>
+    <!-- Title of the activity that allows users to select an app to share to a 1P/3P app [CHAR LIMIT=70] -->
+    <string name="media_projection_entry_share_app_selector_title">Choose app to share</string>
 
     <!-- Casting that launched by SysUI (i.e. when there is no app name) -->
     <!-- System casting media projection permission dialog title. [CHAR LIMIT=100] -->
@@ -1395,6 +1399,8 @@
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app">When you’re casting an app, anything shown or played in that app is visible. So be careful with things like passwords, payment details, messages, photos, and audio and video.</string>
     <!-- System casting media projection permission button to continue for SysUI casting. [CHAR LIMIT=60] -->
     <string name="media_projection_entry_cast_permission_dialog_continue_entire_screen">Cast screen</string>
+    <!-- Title of the activity that allows users to select an app to cast [CHAR LIMIT=70] -->
+    <string name="media_projection_entry_cast_app_selector_title">Choose app to cast</string>
 
     <!-- Other sharing (not recording nor casting) that launched by SysUI (currently not in use) -->
     <!-- System sharing media projection permission dialog title. [CHAR LIMIT=100] -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java
index 68d2eb3..41ad437 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/Utilities.java
@@ -26,6 +26,7 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.inputmethodservice.InputMethodService;
+import android.inputmethodservice.InputMethodService.BackDispositionMode;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
@@ -105,8 +106,8 @@
      * @return updated set of flags from InputMethodService based off {@param oldHints}
      *          Leaves original hints unmodified
      */
-    public static int calculateBackDispositionHints(int oldHints, int backDisposition,
-            boolean imeShown, boolean showImeSwitcher) {
+    public static int calculateBackDispositionHints(int oldHints,
+            @BackDispositionMode int backDisposition, boolean imeShown, boolean showImeSwitcher) {
         int hints = oldHints;
         switch (backDisposition) {
             case InputMethodService.BACK_DISPOSITION_DEFAULT:
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 6aaaf3d..fbeb715 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
@@ -184,7 +184,11 @@
         keyguardTransitionInteractor.startedKeyguardTransitionStep
             .filter { step -> step.to == KeyguardState.OCCLUDED }
             .combine(isCommunalAvailable, ::Pair)
-            .map { (step, available) -> available && step.from == KeyguardState.GLANCEABLE_HUB }
+            .map { (step, available) ->
+                available &&
+                    (step.from == KeyguardState.GLANCEABLE_HUB ||
+                        step.from == KeyguardState.DREAMING)
+            }
             .flowOn(bgDispatcher)
             .stateIn(
                 scope = applicationScope,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index 3273111..79f4568 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -33,6 +33,7 @@
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerImpl;
 import com.android.systemui.doze.DozeHost;
+import com.android.systemui.inputdevice.tutorial.KeyboardTouchpadTutorialModule;
 import com.android.systemui.keyboard.shortcut.ShortcutHelperModule;
 import com.android.systemui.keyguard.ui.composable.blueprint.DefaultBlueprintModule;
 import com.android.systemui.keyguard.ui.view.layout.blueprints.KeyguardBlueprintModule;
@@ -77,7 +78,7 @@
 import com.android.systemui.statusbar.policy.SensorPrivacyController;
 import com.android.systemui.statusbar.policy.SensorPrivacyControllerImpl;
 import com.android.systemui.toast.ToastModule;
-import com.android.systemui.touchpad.tutorial.TouchpadKeyboardTutorialModule;
+import com.android.systemui.touchpad.tutorial.TouchpadTutorialModule;
 import com.android.systemui.unfold.SysUIUnfoldStartableModule;
 import com.android.systemui.unfold.UnfoldTransitionModule;
 import com.android.systemui.util.kotlin.SysUICoroutinesModule;
@@ -122,6 +123,7 @@
         KeyboardShortcutsModule.class,
         KeyguardBlueprintModule.class,
         KeyguardSectionsModule.class,
+        KeyboardTouchpadTutorialModule.class,
         MediaModule.class,
         MediaMuteAwaitConnectionCli.StartableModule.class,
         MultiUserUtilsModule.class,
@@ -142,7 +144,7 @@
         SysUIUnfoldStartableModule.class,
         UnfoldTransitionModule.Startables.class,
         ToastModule.class,
-        TouchpadKeyboardTutorialModule.class,
+        TouchpadTutorialModule.class,
         VolumeModule.class,
         WallpaperModule.class,
         ShortcutHelperModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index b0f2c18..cbea876 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -258,13 +258,6 @@
 
     @Binds
     @IntoMap
-    @ClassKey(KeyboardTouchpadTutorialCoreStartable::class)
-    abstract fun bindKeyboardTouchpadTutorialCoreStartable(
-        listener: KeyboardTouchpadTutorialCoreStartable
-    ): CoreStartable
-
-    @Binds
-    @IntoMap
     @ClassKey(PhysicalKeyboardCoreStartable::class)
     abstract fun bindKeyboardCoreStartable(listener: PhysicalKeyboardCoreStartable): CoreStartable
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java b/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java
index 0b33614..6fd4d33 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeBrightnessHostForwarder.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.doze;
 
-import java.util.concurrent.Executor;
-
 /**
  * Forwards the currently used brightness to {@link DozeHost}.
  */
@@ -25,9 +23,8 @@
 
     private final DozeHost mHost;
 
-    public DozeBrightnessHostForwarder(DozeMachine.Service wrappedService, DozeHost host,
-            Executor bgExecutor) {
-        super(wrappedService, bgExecutor);
+    public DozeBrightnessHostForwarder(DozeMachine.Service wrappedService, DozeHost host) {
+        super(wrappedService);
         mHost = host;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 5bfcc97..cdcb03e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -253,9 +253,11 @@
     /**
      * Appends display state changed event to the logs
      * @param displayState new DozeMachine state
+     * @param afterRequest whether the request has successfully been sent else false for it's
+     *                        about to be requested
      */
-    public void traceDisplayState(int displayState) {
-        mLogger.logDisplayStateChanged(displayState);
+    public void traceDisplayState(int displayState, boolean afterRequest) {
+        mLogger.logDisplayStateChanged(displayState, afterRequest);
     }
 
     /**
@@ -402,18 +404,22 @@
     /**
      * Appends new AOD screen brightness to logs
      * @param brightness display brightness setting between 1 and 255
+     * @param afterRequest whether the request has successfully been sent else false for it's
+     *                        about to be requested
      */
-    public void traceDozeScreenBrightness(int brightness) {
-        mLogger.logDozeScreenBrightness(brightness);
+    public void traceDozeScreenBrightness(int brightness, boolean afterRequest) {
+        mLogger.logDozeScreenBrightness(brightness, afterRequest);
     }
 
     /**
      * Appends new AOD screen brightness to logs
      * @param brightness display brightness setting between {@link PowerManager#BRIGHTNESS_MIN} and
      *                   {@link PowerManager#BRIGHTNESS_MAX}
+     * @param afterRequest whether the request has successfully been sent else false for it's
+     *                        about to be requested
      */
-    public void traceDozeScreenBrightnessFloat(float brightness) {
-        mLogger.logDozeScreenBrightnessFloat(brightness);
+    public void traceDozeScreenBrightnessFloat(float brightness, boolean afterRequest) {
+        mLogger.logDozeScreenBrightnessFloat(brightness, afterRequest);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
index a31dbec..7128731 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
@@ -32,23 +32,18 @@
 import javax.inject.Inject
 
 /** Interface for logging messages to the [DozeLog]. */
-class DozeLogger @Inject constructor(
-    @DozeLog private val buffer: LogBuffer
-) {
+class DozeLogger @Inject constructor(@DozeLog private val buffer: LogBuffer) {
     fun logPickupWakeup(isWithinVibrationThreshold: Boolean) {
-        buffer.log(TAG, DEBUG, {
-            bool1 = isWithinVibrationThreshold
-        }, {
-            "PickupWakeup withinVibrationThreshold=$bool1"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            { bool1 = isWithinVibrationThreshold },
+            { "PickupWakeup withinVibrationThreshold=$bool1" }
+        )
     }
 
     fun logPulseStart(@Reason reason: Int) {
-        buffer.log(TAG, INFO, {
-            int1 = reason
-        }, {
-            "Pulse start, reason=${reasonToString(int1)}"
-        })
+        buffer.log(TAG, INFO, { int1 = reason }, { "Pulse start, reason=${reasonToString(int1)}" })
     }
 
     fun logPulseFinish() {
@@ -60,52 +55,51 @@
     }
 
     fun logDozing(isDozing: Boolean) {
-        buffer.log(TAG, INFO, {
-            bool1 = isDozing
-        }, {
-            "Dozing=$bool1"
-        })
+        buffer.log(TAG, INFO, { bool1 = isDozing }, { "Dozing=$bool1" })
     }
 
     fun logDozingChanged(isDozing: Boolean) {
-        buffer.log(TAG, INFO, {
-            bool1 = isDozing
-        }, {
-            "Dozing changed dozing=$bool1"
-        })
+        buffer.log(TAG, INFO, { bool1 = isDozing }, { "Dozing changed dozing=$bool1" })
     }
 
     fun logPowerSaveChanged(powerSaveActive: Boolean, nextState: DozeMachine.State) {
-        buffer.log(TAG, INFO, {
-            bool1 = powerSaveActive
-            str1 = nextState.name
-        }, {
-            "Power save active=$bool1 nextState=$str1"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                bool1 = powerSaveActive
+                str1 = nextState.name
+            },
+            { "Power save active=$bool1 nextState=$str1" }
+        )
     }
 
     fun logAlwaysOnSuppressedChange(isAodSuppressed: Boolean, nextState: DozeMachine.State) {
-        buffer.log(TAG, INFO, {
-            bool1 = isAodSuppressed
-            str1 = nextState.name
-        }, {
-            "Always on (AOD) suppressed changed, suppressed=$bool1 nextState=$str1"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                bool1 = isAodSuppressed
+                str1 = nextState.name
+            },
+            { "Always on (AOD) suppressed changed, suppressed=$bool1 nextState=$str1" }
+        )
     }
 
-    fun logFling(
-        expand: Boolean,
-        aboveThreshold: Boolean,
-        screenOnFromTouch: Boolean
-    ) {
-        buffer.log(TAG, DEBUG, {
-            bool1 = expand
-            bool2 = aboveThreshold
-            bool4 = screenOnFromTouch
-        }, {
-            "Fling expand=$bool1 aboveThreshold=$bool2 thresholdNeeded=$bool3 " +
-                "screenOnFromTouch=$bool4"
-        })
+    fun logFling(expand: Boolean, aboveThreshold: Boolean, screenOnFromTouch: Boolean) {
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                bool1 = expand
+                bool2 = aboveThreshold
+                bool4 = screenOnFromTouch
+            },
+            {
+                "Fling expand=$bool1 aboveThreshold=$bool2 thresholdNeeded=$bool3 " +
+                    "screenOnFromTouch=$bool4"
+            }
+        )
     }
 
     fun logEmergencyCall() {
@@ -113,280 +107,314 @@
     }
 
     fun logKeyguardBouncerChanged(isShowing: Boolean) {
-        buffer.log(TAG, INFO, {
-            bool1 = isShowing
-        }, {
-            "Keyguard bouncer changed, showing=$bool1"
-        })
+        buffer.log(TAG, INFO, { bool1 = isShowing }, { "Keyguard bouncer changed, showing=$bool1" })
     }
 
     fun logScreenOn(isPulsing: Boolean) {
-        buffer.log(TAG, INFO, {
-            bool1 = isPulsing
-        }, {
-            "Screen on, pulsing=$bool1"
-        })
+        buffer.log(TAG, INFO, { bool1 = isPulsing }, { "Screen on, pulsing=$bool1" })
     }
 
     fun logScreenOff(why: Int) {
-        buffer.log(TAG, INFO, {
-            int1 = why
-        }, {
-            "Screen off, why=$int1"
-        })
+        buffer.log(TAG, INFO, { int1 = why }, { "Screen off, why=$int1" })
     }
 
     fun logMissedTick(delay: String) {
-        buffer.log(TAG, ERROR, {
-            str1 = delay
-        }, {
-            "Missed AOD time tick by $str1"
-        })
+        buffer.log(TAG, ERROR, { str1 = delay }, { "Missed AOD time tick by $str1" })
     }
 
     fun logTimeTickScheduled(whenAt: Long, triggerAt: Long) {
-        buffer.log(TAG, DEBUG, {
-            long1 = whenAt
-            long2 = triggerAt
-        }, {
-            "Time tick scheduledAt=${DATE_FORMAT.format(Date(long1))} " +
-                "triggerAt=${DATE_FORMAT.format(Date(long2))}"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                long1 = whenAt
+                long2 = triggerAt
+            },
+            {
+                "Time tick scheduledAt=${DATE_FORMAT.format(Date(long1))} " +
+                    "triggerAt=${DATE_FORMAT.format(Date(long2))}"
+            }
+        )
     }
 
     fun logKeyguardVisibilityChange(isVisible: Boolean) {
-        buffer.log(TAG, INFO, {
-            bool1 = isVisible
-        }, {
-            "Keyguard visibility change, isVisible=$bool1"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            { bool1 = isVisible },
+            { "Keyguard visibility change, isVisible=$bool1" }
+        )
     }
 
     fun logPendingUnscheduleTimeTick(isPending: Boolean, isTimeTickScheduled: Boolean) {
-        buffer.log(TAG, INFO, {
-            bool1 = isPending
-            bool2 = isTimeTickScheduled
-        }, {
-            "Pending unschedule time tick, isPending=$bool1, isTimeTickScheduled:$bool2"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                bool1 = isPending
+                bool2 = isTimeTickScheduled
+            },
+            { "Pending unschedule time tick, isPending=$bool1, isTimeTickScheduled:$bool2" }
+        )
     }
 
     fun logDozeStateChanged(state: DozeMachine.State) {
-        buffer.log(TAG, INFO, {
-            str1 = state.name
-        }, {
-            "Doze state changed to $str1"
-        })
+        buffer.log(TAG, INFO, { str1 = state.name }, { "Doze state changed to $str1" })
     }
 
     fun logStateChangedSent(state: DozeMachine.State) {
-        buffer.log(TAG, INFO, {
-            str1 = state.name
-        }, {
-            "Doze state sent to all DozeMachineParts stateSent=$str1"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            { str1 = state.name },
+            { "Doze state sent to all DozeMachineParts stateSent=$str1" }
+        )
     }
 
     fun logDisplayStateDelayedByUdfps(delayedDisplayState: Int) {
-        buffer.log(TAG, INFO, {
-            str1 = Display.stateToString(delayedDisplayState)
-        }, {
-            "Delaying display state change to: $str1 due to UDFPS activity"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            { str1 = Display.stateToString(delayedDisplayState) },
+            { "Delaying display state change to: $str1 due to UDFPS activity" }
+        )
     }
 
-    fun logDisplayStateChanged(displayState: Int) {
-        buffer.log(TAG, INFO, {
-            str1 = Display.stateToString(displayState)
-        }, {
-            "Display state changed to $str1"
-        })
+    fun logDisplayStateChanged(displayState: Int, afterRequest: Boolean) {
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                str1 = Display.stateToString(displayState)
+                bool1 = afterRequest
+            },
+            { "Display state ${if (bool1) "changed" else "requested"} to $str1" }
+        )
     }
 
     fun logWakeDisplay(isAwake: Boolean, @Reason reason: Int) {
-        buffer.log(TAG, DEBUG, {
-            bool1 = isAwake
-            int1 = reason
-        }, {
-            "Display wakefulness changed, isAwake=$bool1, reason=${reasonToString(int1)}"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                bool1 = isAwake
+                int1 = reason
+            },
+            { "Display wakefulness changed, isAwake=$bool1, reason=${reasonToString(int1)}" }
+        )
     }
 
     fun logProximityResult(isNear: Boolean, millis: Long, @Reason reason: Int) {
-        buffer.log(TAG, DEBUG, {
-            bool1 = isNear
-            long1 = millis
-            int1 = reason
-        }, {
-            "Proximity result reason=${reasonToString(int1)} near=$bool1 millis=$long1"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                bool1 = isNear
+                long1 = millis
+                int1 = reason
+            },
+            { "Proximity result reason=${reasonToString(int1)} near=$bool1 millis=$long1" }
+        )
     }
 
     fun logPostureChanged(posture: Int, partUpdated: String) {
-        buffer.log(TAG, INFO, {
-            int1 = posture
-            str1 = partUpdated
-        }, {
-            "Posture changed, posture=${DevicePostureController.devicePostureToString(int1)}" +
-                " partUpdated=$str1"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                int1 = posture
+                str1 = partUpdated
+            },
+            {
+                "Posture changed, posture=${DevicePostureController.devicePostureToString(int1)}" +
+                    " partUpdated=$str1"
+            }
+        )
     }
 
     /**
-     * Log why a pulse was dropped and the current doze machine state. The state can be null
-     * if the DozeMachine is the middle of transitioning between states.
+     * Log why a pulse was dropped and the current doze machine state. The state can be null if the
+     * DozeMachine is the middle of transitioning between states.
      */
     fun logPulseDropped(from: String, state: DozeMachine.State?) {
-        buffer.log(TAG, INFO, {
-            str1 = from
-            str2 = state?.name
-        }, {
-            "Pulse dropped, cannot pulse from=$str1 state=$str2"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                str1 = from
+                str2 = state?.name
+            },
+            { "Pulse dropped, cannot pulse from=$str1 state=$str2" }
+        )
     }
 
     fun logSensorEventDropped(sensorEvent: Int, reason: String) {
-        buffer.log(TAG, INFO, {
-            int1 = sensorEvent
-            str1 = reason
-        }, {
-            "SensorEvent [$int1] dropped, reason=$str1"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                int1 = sensorEvent
+                str1 = reason
+            },
+            { "SensorEvent [$int1] dropped, reason=$str1" }
+        )
     }
 
     fun logPulseEvent(pulseEvent: String, dozing: Boolean, pulseReason: String) {
-        buffer.log(TAG, DEBUG, {
-            str1 = pulseEvent
-            bool1 = dozing
-            str2 = pulseReason
-        }, {
-            "Pulse-$str1 dozing=$bool1 pulseReason=$str2"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                str1 = pulseEvent
+                bool1 = dozing
+                str2 = pulseReason
+            },
+            { "Pulse-$str1 dozing=$bool1 pulseReason=$str2" }
+        )
     }
 
     fun logPulseDropped(reason: String) {
-        buffer.log(TAG, INFO, {
-            str1 = reason
-        }, {
-            "Pulse dropped, why=$str1"
-        })
+        buffer.log(TAG, INFO, { str1 = reason }, { "Pulse dropped, why=$str1" })
     }
 
     fun logPulseTouchDisabledByProx(disabled: Boolean) {
-        buffer.log(TAG, DEBUG, {
-            bool1 = disabled
-        }, {
-            "Pulse touch modified by prox, disabled=$bool1"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            { bool1 = disabled },
+            { "Pulse touch modified by prox, disabled=$bool1" }
+        )
     }
 
     fun logSensorTriggered(@Reason reason: Int) {
-        buffer.log(TAG, DEBUG, {
-            int1 = reason
-        }, {
-            "Sensor triggered, type=${reasonToString(int1)}"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            { int1 = reason },
+            { "Sensor triggered, type=${reasonToString(int1)}" }
+        )
     }
 
     fun logAlwaysOnSuppressed(state: DozeMachine.State, reason: String) {
-        buffer.log(TAG, INFO, {
-            str1 = state.name
-            str2 = reason
-        }, {
-            "Always-on state suppressed, suppressed state=$str1 reason=$str2"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                str1 = state.name
+                str2 = reason
+            },
+            { "Always-on state suppressed, suppressed state=$str1 reason=$str2" }
+        )
     }
 
     fun logImmediatelyEndDoze(reason: String) {
-        buffer.log(TAG, INFO, {
-            str1 = reason
-        }, {
-            "Doze immediately ended due to $str1"
-        })
+        buffer.log(TAG, INFO, { str1 = reason }, { "Doze immediately ended due to $str1" })
     }
 
-    fun logDozeScreenBrightness(brightness: Int) {
-        buffer.log(TAG, INFO, {
-            int1 = brightness
-        }, {
-            "Doze screen brightness set (int), brightness=$int1"
-        })
+    fun logDozeScreenBrightness(brightness: Int, afterRequest: Boolean) {
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                int1 = brightness
+                bool1 = afterRequest
+            },
+            {
+                "Doze screen brightness ${if (bool1) "set" else "requested"}" +
+                    " (int), brightness=$int1"
+            }
+        )
     }
 
-    fun logDozeScreenBrightnessFloat(brightness: Float) {
-        buffer.log(TAG, INFO, {
-            double1 = brightness.toDouble()
-        }, {
-            "Doze screen brightness set (float), brightness=$double1"
-        })
+    fun logDozeScreenBrightnessFloat(brightness: Float, afterRequest: Boolean) {
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                double1 = brightness.toDouble()
+                bool1 = afterRequest
+            },
+            {
+                "Doze screen brightness ${if (bool1) "set" else "requested"}" +
+                    " (float), brightness=$double1"
+            }
+        )
     }
 
     fun logSetAodDimmingScrim(scrimOpacity: Long) {
-        buffer.log(TAG, INFO, {
-            long1 = scrimOpacity
-        }, {
-            "Doze aod dimming scrim opacity set, opacity=$long1"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            { long1 = scrimOpacity },
+            { "Doze aod dimming scrim opacity set, opacity=$long1" }
+        )
     }
 
     fun logCarModeEnded() {
-        buffer.log(TAG, INFO, {}, {
-            "Doze car mode ended"
-        })
+        buffer.log(TAG, INFO, {}, { "Doze car mode ended" })
     }
 
     fun logCarModeStarted() {
-        buffer.log(TAG, INFO, {}, {
-            "Doze car mode started"
-        })
+        buffer.log(TAG, INFO, {}, { "Doze car mode started" })
     }
 
     fun logSensorRegisterAttempt(sensorInfo: String, successfulRegistration: Boolean) {
-        buffer.log(TAG, INFO, {
-            str1 = sensorInfo
-            bool1 = successfulRegistration
-        }, {
-            "Register sensor. Success=$bool1 sensor=$str1"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                str1 = sensorInfo
+                bool1 = successfulRegistration
+            },
+            { "Register sensor. Success=$bool1 sensor=$str1" }
+        )
     }
 
     fun logSensorUnregisterAttempt(sensorInfo: String, successfulUnregister: Boolean) {
-        buffer.log(TAG, INFO, {
-            str1 = sensorInfo
-            bool1 = successfulUnregister
-        }, {
-            "Unregister sensor. Success=$bool1 sensor=$str1"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                str1 = sensorInfo
+                bool1 = successfulUnregister
+            },
+            { "Unregister sensor. Success=$bool1 sensor=$str1" }
+        )
     }
 
     fun logSensorUnregisterAttempt(
-            sensorInfo: String,
-            successfulUnregister: Boolean,
-            reason: String
+        sensorInfo: String,
+        successfulUnregister: Boolean,
+        reason: String
     ) {
-        buffer.log(TAG, INFO, {
-            str1 = sensorInfo
-            bool1 = successfulUnregister
-            str2 = reason
-        }, {
-            "Unregister sensor. reason=$str2. Success=$bool1 sensor=$str1"
-        })
+        buffer.log(
+            TAG,
+            INFO,
+            {
+                str1 = sensorInfo
+                bool1 = successfulUnregister
+                str2 = reason
+            },
+            { "Unregister sensor. reason=$str2. Success=$bool1 sensor=$str1" }
+        )
     }
 
     fun logSkipSensorRegistration(sensor: String) {
-        buffer.log(TAG, DEBUG, {
-            str1 = sensor
-        }, {
-            "Skipping sensor registration because its already registered. sensor=$str1"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            { str1 = sensor },
+            { "Skipping sensor registration because its already registered. sensor=$str1" }
+        )
     }
 
     fun logSetIgnoreTouchWhilePulsing(ignoreTouchWhilePulsing: Boolean) {
-        buffer.log(TAG, DEBUG, {
-            bool1 = ignoreTouchWhilePulsing
-        }, {
-            "Prox changed while pulsing. setIgnoreTouchWhilePulsing=$bool1"
-        })
+        buffer.log(
+            TAG,
+            DEBUG,
+            { bool1 = ignoreTouchWhilePulsing },
+            { "Prox changed while pulsing. setIgnoreTouchWhilePulsing=$bool1" }
+        )
     }
 
     fun log(@CompileTimeConstant msg: String) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 8198ef4..e02e3fb 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -39,7 +39,6 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
 
@@ -232,7 +231,6 @@
     }
 
     void onScreenState(int state) {
-        mDozeLog.traceDisplayState(state);
         for (Part part : mParts) {
             part.onScreenState(state);
         }
@@ -516,11 +514,9 @@
 
         class Delegate implements Service {
             private final Service mDelegate;
-            private final Executor mBgExecutor;
 
-            public Delegate(Service delegate, Executor bgExecutor) {
+            public Delegate(Service delegate) {
                 mDelegate = delegate;
-                mBgExecutor = bgExecutor;
             }
 
             @Override
@@ -540,16 +536,12 @@
 
             @Override
             public void setDozeScreenBrightness(int brightness) {
-                mBgExecutor.execute(() -> {
-                    mDelegate.setDozeScreenBrightness(brightness);
-                });
+                mDelegate.setDozeScreenBrightness(brightness);
             }
 
             @Override
             public void setDozeScreenBrightnessFloat(float brightness) {
-                mBgExecutor.execute(() -> {
-                    mDelegate.setDozeScreenBrightnessFloat(brightness);
-                });
+                mDelegate.setDozeScreenBrightnessFloat(brightness);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java
index 8d44472..25c2c39 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenStatePreventingAdapter.java
@@ -22,16 +22,14 @@
 
 import com.android.systemui.statusbar.phone.DozeParameters;
 
-import java.util.concurrent.Executor;
-
 /**
  * Prevents usage of doze screen states on devices that don't support them.
  */
 public class DozeScreenStatePreventingAdapter extends DozeMachine.Service.Delegate {
 
     @VisibleForTesting
-    DozeScreenStatePreventingAdapter(DozeMachine.Service inner, Executor bgExecutor) {
-        super(inner, bgExecutor);
+    DozeScreenStatePreventingAdapter(DozeMachine.Service inner) {
+        super(inner);
     }
 
     @Override
@@ -49,8 +47,8 @@
      * return a new instance of {@link DozeScreenStatePreventingAdapter} wrapping {@code inner}.
      */
     public static DozeMachine.Service wrapIfNeeded(DozeMachine.Service inner,
-            DozeParameters params, Executor bgExecutor) {
-        return isNeeded(params) ? new DozeScreenStatePreventingAdapter(inner, bgExecutor) : inner;
+            DozeParameters params) {
+        return isNeeded(params) ? new DozeScreenStatePreventingAdapter(inner) : inner;
     }
 
     private static boolean isNeeded(DozeParameters params) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index ba38ab0..2e372ff 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -23,6 +23,7 @@
 import android.service.dreams.DreamService;
 import android.util.Log;
 
+import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.doze.dagger.DozeComponent;
 import com.android.systemui.plugins.DozeServicePlugin;
 import com.android.systemui.plugins.DozeServicePlugin.RequestDoze;
@@ -31,6 +32,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
 
@@ -43,9 +45,14 @@
     private DozeMachine mDozeMachine;
     private DozeServicePlugin mDozePlugin;
     private PluginManager mPluginManager;
+    private DozeLog mDozeLog;
+    private Executor mBgExecutor;
 
     @Inject
-    public DozeService(DozeComponent.Builder dozeComponentBuilder, PluginManager pluginManager) {
+    public DozeService(DozeComponent.Builder dozeComponentBuilder, PluginManager pluginManager,
+            DozeLog dozeLog, @UiBackground Executor bgExecutor) {
+        mDozeLog = dozeLog;
+        mBgExecutor = bgExecutor;
         mDozeComponentBuilder = dozeComponentBuilder;
         setDebug(DEBUG);
         mPluginManager = pluginManager;
@@ -143,9 +150,29 @@
 
     @Override
     public void setDozeScreenState(int state) {
+        mDozeLog.traceDisplayState(state, /* afterRequest */ false);
         super.setDozeScreenState(state);
+        mDozeLog.traceDisplayState(state, /* afterRequest */ true);
         if (mDozeMachine != null) {
             mDozeMachine.onScreenState(state);
         }
     }
+
+    @Override
+    public void setDozeScreenBrightness(int brightness) {
+        mBgExecutor.execute(() -> {
+            mDozeLog.traceDozeScreenBrightness(brightness, /* afterRequest */ false);
+            super.setDozeScreenBrightness(brightness);
+            mDozeLog.traceDozeScreenBrightness(brightness, /* afterRequest */ true);
+        });
+    }
+
+    @Override
+    public void setDozeScreenBrightnessFloat(float brightness) {
+        mBgExecutor.execute(() -> {
+            mDozeLog.traceDozeScreenBrightnessFloat(brightness, /* afterRequest */ false);
+            super.setDozeScreenBrightnessFloat(brightness);
+            mDozeLog.traceDozeScreenBrightnessFloat(brightness, /* afterRequest */ true);
+        });
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java
index f7773f1..cfc952d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapter.java
@@ -22,16 +22,14 @@
 
 import com.android.systemui.statusbar.phone.DozeParameters;
 
-import java.util.concurrent.Executor;
-
 /**
  * Prevents usage of doze screen states on devices that don't support them.
  */
 public class DozeSuspendScreenStatePreventingAdapter extends DozeMachine.Service.Delegate {
 
     @VisibleForTesting
-    DozeSuspendScreenStatePreventingAdapter(DozeMachine.Service inner, Executor bgExecutor) {
-        super(inner, bgExecutor);
+    DozeSuspendScreenStatePreventingAdapter(DozeMachine.Service inner) {
+        super(inner);
     }
 
     @Override
@@ -47,8 +45,8 @@
      * return a new instance of {@link DozeSuspendScreenStatePreventingAdapter} wrapping {@code inner}.
      */
     public static DozeMachine.Service wrapIfNeeded(DozeMachine.Service inner,
-            DozeParameters params, Executor bgExecutor) {
-        return isNeeded(params) ? new DozeSuspendScreenStatePreventingAdapter(inner, bgExecutor)
+            DozeParameters params) {
+        return isNeeded(params) ? new DozeSuspendScreenStatePreventingAdapter(inner)
                 : inner;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
index 8c3de4b..f383a04 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.hardware.Sensor;
 
-import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.doze.DozeAuthRemover;
 import com.android.systemui.doze.DozeBrightnessHostForwarder;
 import com.android.systemui.doze.DozeDockHandler;
@@ -51,7 +50,6 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
-import java.util.concurrent.Executor;
 
 /** Dagger module for use with {@link com.android.systemui.doze.dagger.DozeComponent}. */
 @Module
@@ -60,13 +58,13 @@
     @DozeScope
     @WrappedService
     static DozeMachine.Service providesWrappedService(DozeMachine.Service dozeMachineService,
-            DozeHost dozeHost, DozeParameters dozeParameters, @UiBackground Executor bgExecutor) {
+            DozeHost dozeHost, DozeParameters dozeParameters) {
         DozeMachine.Service wrappedService = dozeMachineService;
-        wrappedService = new DozeBrightnessHostForwarder(wrappedService, dozeHost, bgExecutor);
+        wrappedService = new DozeBrightnessHostForwarder(wrappedService, dozeHost);
         wrappedService = DozeScreenStatePreventingAdapter.wrapIfNeeded(
-                wrappedService, dozeParameters, bgExecutor);
+                wrappedService, dozeParameters);
         wrappedService = DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(
-                wrappedService, dozeParameters, bgExecutor);
+                wrappedService, dozeParameters);
 
         return wrappedService;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadTutorialModule.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadTutorialModule.kt
new file mode 100644
index 0000000..8e6cb07
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadTutorialModule.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.systemui.inputdevice.tutorial
+
+import android.app.Activity
+import com.android.systemui.CoreStartable
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity
+import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor
+import dagger.Binds
+import dagger.BindsOptionalOf
+import dagger.Module
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+
+@Module
+interface KeyboardTouchpadTutorialModule {
+
+    @Binds
+    @IntoMap
+    @ClassKey(KeyboardTouchpadTutorialCoreStartable::class)
+    fun bindKeyboardTouchpadTutorialCoreStartable(
+        listener: KeyboardTouchpadTutorialCoreStartable
+    ): CoreStartable
+
+    @Binds
+    @IntoMap
+    @ClassKey(KeyboardTouchpadTutorialActivity::class)
+    fun activity(impl: KeyboardTouchpadTutorialActivity): Activity
+
+    // TouchpadModule dependencies below
+    // all should be optional to not introduce touchpad dependency in all sysui variants
+
+    @BindsOptionalOf fun touchpadScreensProvider(): TouchpadTutorialScreensProvider
+
+    @BindsOptionalOf fun touchpadGesturesInteractor(): TouchpadGesturesInteractor
+}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/TouchpadTutorialScreensProvider.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/TouchpadTutorialScreensProvider.kt
new file mode 100644
index 0000000..bd3e771
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/TouchpadTutorialScreensProvider.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.systemui.inputdevice.tutorial
+
+import androidx.compose.runtime.Composable
+
+interface TouchpadTutorialScreensProvider {
+
+    @Composable fun BackGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit)
+
+    @Composable fun HomeGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/ActionKeyTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/ActionKeyTutorialScreen.kt
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/ActionKeyTutorialScreen.kt
rename to packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/ActionKeyTutorialScreen.kt
index f7f2631..c5b0ca7 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/ActionKeyTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/ActionKeyTutorialScreen.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.touchpad.tutorial.ui.composable
+package com.android.systemui.inputdevice.tutorial.ui.composable
 
 import androidx.activity.compose.BackHandler
 import androidx.compose.foundation.layout.Box
@@ -34,9 +34,9 @@
 import androidx.compose.ui.input.key.type
 import com.airbnb.lottie.compose.rememberLottieDynamicProperties
 import com.android.compose.theme.LocalAndroidColorScheme
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.FINISHED
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.NOT_STARTED
 import com.android.systemui.res.R
-import com.android.systemui.touchpad.tutorial.ui.composable.TutorialActionState.FINISHED
-import com.android.systemui.touchpad.tutorial.ui.composable.TutorialActionState.NOT_STARTED
 
 @Composable
 fun ActionKeyTutorialScreen(
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/ActionTutorialContent.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/ActionTutorialContent.kt
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/ActionTutorialContent.kt
rename to packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/ActionTutorialContent.kt
index 2b7f674..c50b7dc 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/ActionTutorialContent.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/ActionTutorialContent.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.touchpad.tutorial.ui.composable
+package com.android.systemui.inputdevice.tutorial.ui.composable
 
 import android.graphics.ColorFilter
 import android.graphics.PorterDuff
@@ -60,9 +60,9 @@
 import com.airbnb.lottie.compose.animateLottieCompositionAsState
 import com.airbnb.lottie.compose.rememberLottieComposition
 import com.airbnb.lottie.compose.rememberLottieDynamicProperty
-import com.android.systemui.touchpad.tutorial.ui.composable.TutorialActionState.FINISHED
-import com.android.systemui.touchpad.tutorial.ui.composable.TutorialActionState.IN_PROGRESS
-import com.android.systemui.touchpad.tutorial.ui.composable.TutorialActionState.NOT_STARTED
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.FINISHED
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.IN_PROGRESS
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.NOT_STARTED
 
 enum class TutorialActionState {
     NOT_STARTED,
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialComponents.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/TutorialComponents.kt
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialComponents.kt
rename to packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/TutorialComponents.kt
index f2276c8..01ad585 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialComponents.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/TutorialComponents.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.touchpad.tutorial.ui.composable
+package com.android.systemui.inputdevice.tutorial.ui.composable
 
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Row
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialScreenConfig.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/TutorialScreenConfig.kt
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialScreenConfig.kt
rename to packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/TutorialScreenConfig.kt
index d76ceb9..0406bb9 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialScreenConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/composable/TutorialScreenConfig.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.touchpad.tutorial.ui.composable
+package com.android.systemui.inputdevice.tutorial.ui.composable
 
 import androidx.annotation.RawRes
 import androidx.annotation.StringRes
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/view/KeyboardTouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/view/KeyboardTouchpadTutorialActivity.kt
new file mode 100644
index 0000000..3e382d6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/view/KeyboardTouchpadTutorialActivity.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.systemui.inputdevice.tutorial.ui.view
+
+import android.os.Bundle
+import android.view.WindowManager
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.activity.enableEdgeToEdge
+import androidx.activity.viewModels
+import androidx.compose.runtime.Composable
+import com.android.compose.theme.PlatformTheme
+import com.android.systemui.inputdevice.tutorial.TouchpadTutorialScreensProvider
+import com.android.systemui.inputdevice.tutorial.ui.viewmodel.KeyboardTouchpadTutorialViewModel
+import java.util.Optional
+import javax.inject.Inject
+
+/**
+ * Activity for out of the box experience for keyboard and touchpad. Note that it's possible that
+ * either of them are actually not connected when this is launched
+ */
+class KeyboardTouchpadTutorialActivity
+@Inject
+constructor(
+    private val viewModelFactory: KeyboardTouchpadTutorialViewModel.Factory,
+    private val touchpadTutorialScreensProvider: Optional<TouchpadTutorialScreensProvider>,
+) : ComponentActivity() {
+
+    private val vm by
+        viewModels<KeyboardTouchpadTutorialViewModel>(factoryProducer = { viewModelFactory })
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        enableEdgeToEdge()
+        setContent {
+            PlatformTheme {
+                KeyboardTouchpadTutorialContainer(vm, touchpadTutorialScreensProvider) { finish() }
+            }
+        }
+        // required to handle 3+ fingers on touchpad
+        window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        vm.onOpened()
+    }
+
+    override fun onPause() {
+        super.onPause()
+        vm.onClosed()
+    }
+}
+
+@Composable
+fun KeyboardTouchpadTutorialContainer(
+    vm: KeyboardTouchpadTutorialViewModel,
+    touchpadTutorialScreensProvider: Optional<TouchpadTutorialScreensProvider>,
+    closeTutorial: () -> Unit
+) {}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
new file mode 100644
index 0000000..39b1ec0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.systemui.inputdevice.tutorial.ui.viewmodel
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor
+import java.util.Optional
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+
+class KeyboardTouchpadTutorialViewModel(
+    private val gesturesInteractor: Optional<TouchpadGesturesInteractor>
+) : ViewModel() {
+
+    private val _screen = MutableStateFlow(Screen.BACK_GESTURE)
+    val screen: StateFlow<Screen> = _screen
+
+    fun goTo(screen: Screen) {
+        _screen.value = screen
+    }
+
+    fun onOpened() {
+        gesturesInteractor.ifPresent { it.disableGestures() }
+    }
+
+    fun onClosed() {
+        gesturesInteractor.ifPresent { it.enableGestures() }
+    }
+
+    class Factory
+    @Inject
+    constructor(private val gesturesInteractor: Optional<TouchpadGesturesInteractor>) :
+        ViewModelProvider.Factory {
+
+        @Suppress("UNCHECKED_CAST")
+        override fun <T : ViewModel> create(modelClass: Class<T>): T {
+            return KeyboardTouchpadTutorialViewModel(gesturesInteractor) as T
+        }
+    }
+}
+
+enum class Screen {
+    BACK_GESTURE,
+    HOME_GESTURE,
+    ACTION_KEY
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 1f3df95..17c5977 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -42,6 +42,7 @@
 import static com.android.systemui.DejankUtils.whitelistIpcs;
 import static com.android.systemui.Flags.notifyPowerManagerUserActivityBackground;
 import static com.android.systemui.Flags.refactorGetCurrentUser;
+import static com.android.systemui.Flags.relockWithPowerButtonImmediately;
 import static com.android.systemui.Flags.translucentOccludingActivityFix;
 import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS;
 
@@ -477,6 +478,7 @@
     private boolean mUnlockingAndWakingFromDream = false;
     private boolean mHideAnimationRun = false;
     private boolean mHideAnimationRunning = false;
+    private boolean mIsKeyguardExitAnimationCanceled = false;
 
     private SoundPool mLockSounds;
     private int mLockSoundId;
@@ -1588,10 +1590,11 @@
             setShowingLocked(!shouldWaitForProvisioning()
                     && !mLockPatternUtils.isLockScreenDisabled(
                             mSelectedUserInteractor.getSelectedUserId()),
-                    true /* forceCallbacks */);
+                    true /* forceCallbacks */, "setupLocked - keyguard service enabled");
         } else {
             // The system's keyguard is disabled or missing.
-            setShowingLocked(false /* showing */, true /* forceCallbacks */);
+            setShowingLocked(false /* showing */, true /* forceCallbacks */,
+                    "setupLocked - keyguard service disabled");
         }
 
         mKeyguardTransitions.register(
@@ -2833,9 +2836,10 @@
         playSound(mTrustedSoundId);
     }
 
-    private void updateActivityLockScreenState(boolean showing, boolean aodShowing) {
+    private void updateActivityLockScreenState(boolean showing, boolean aodShowing, String reason) {
         mUiBgExecutor.execute(() -> {
-            Log.d(TAG, "updateActivityLockScreenState(" + showing + ", " + aodShowing + ")");
+            Log.d(TAG, "updateActivityLockScreenState(" + showing + ", " + aodShowing + ", "
+                    + reason + ")");
 
             if (KeyguardWmStateRefactor.isEnabled()) {
                 // Handled in WmLockscreenVisibilityManager if flag is enabled.
@@ -2895,7 +2899,7 @@
 
             // Force if we're showing in the middle of unlocking, to ensure we end up in the
             // correct state.
-            setShowingLocked(true, hidingOrGoingAway /* force */);
+            setShowingLocked(true, hidingOrGoingAway /* force */, "handleShowInner");
             mHiding = false;
 
             if (!KeyguardWmStateRefactor.isEnabled()) {
@@ -3067,15 +3071,14 @@
                 mHiding = true;
                 mKeyguardGoingAwayRunnable.run();
             } else {
-                Log.d(TAG, "Hiding keyguard while occluded. Just hide the keyguard view and exit.");
-
                 if (!KeyguardWmStateRefactor.isEnabled()) {
                     mKeyguardViewControllerLazy.get().hide(
                             mSystemClock.uptimeMillis() + mHideAnimation.getStartOffset(),
                             mHideAnimation.getDuration());
                 }
 
-                onKeyguardExitFinished();
+                onKeyguardExitFinished("Hiding keyguard while occluded. Just hide the keyguard "
+                        + "view and exit.");
             }
 
             // It's possible that the device was unlocked (via BOUNCER or Fingerprint) while
@@ -3106,6 +3109,7 @@
         Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
                 + " fadeoutDuration=" + fadeoutDuration);
         synchronized (KeyguardViewMediator.this) {
+            mIsKeyguardExitAnimationCanceled = false;
             // Tell ActivityManager that we canceled the keyguard animation if
             // handleStartKeyguardExitAnimation was called, but we're not hiding the keyguard,
             // unless we're animating the surface behind the keyguard and will be hiding the
@@ -3125,7 +3129,8 @@
                         Slog.w(TAG, "Failed to call onAnimationFinished", e);
                     }
                 }
-                setShowingLocked(mShowing, true /* force */);
+                setShowingLocked(mShowing, true /* force */,
+                        "handleStartKeyguardExitAnimation - canceled");
                 return;
             }
             mHiding = false;
@@ -3149,9 +3154,11 @@
                                         Slog.w(TAG, "Failed to call onAnimationFinished", e);
                                     }
                                 }
-                                onKeyguardExitFinished();
-                                mKeyguardViewControllerLazy.get().hide(0 /* startTime */,
-                                        0 /* fadeoutDuration */);
+                                if (!mIsKeyguardExitAnimationCanceled) {
+                                    onKeyguardExitFinished("onRemoteAnimationFinished");
+                                    mKeyguardViewControllerLazy.get().hide(0 /* startTime */,
+                                            0 /* fadeoutDuration */);
+                                }
                                 mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
                             }
 
@@ -3288,12 +3295,12 @@
                     anim.start();
                 });
 
-                onKeyguardExitFinished();
+                onKeyguardExitFinished("remote animation disabled");
             }
         }
     }
 
-    private void onKeyguardExitFinished() {
+    private void onKeyguardExitFinished(String reason) {
         if (DEBUG) Log.d(TAG, "onKeyguardExitFinished()");
         // only play "unlock" noises if not on a call (since the incall UI
         // disables the keyguard)
@@ -3301,7 +3308,7 @@
             playSounds(false);
         }
 
-        setShowingLocked(false);
+        setShowingLocked(false, "onKeyguardExitFinished: " + reason);
         mWakeAndUnlocking = false;
         mDismissCallbackRegistry.notifyDismissSucceeded();
         resetKeyguardDonePendingLocked();
@@ -3349,6 +3356,9 @@
             // A lock is pending, meaning the keyguard exit animation was cancelled because we're
             // re-locking. We should just end the surface-behind animation without exiting the
             // keyguard. The pending lock will be handled by onFinishedGoingToSleep().
+            if (relockWithPowerButtonImmediately()) {
+                mIsKeyguardExitAnimationCanceled = true;
+            }
             finishSurfaceBehindRemoteAnimation(true /* showKeyguard */);
             maybeHandlePendingLock();
         } else {
@@ -3397,12 +3407,13 @@
                 doKeyguardLocked(null);
                 finishSurfaceBehindRemoteAnimation(true /* showKeyguard */);
                 // Ensure WM is notified that we made a decision to show
-                setShowingLocked(true /* showing */, true /* force */);
+                setShowingLocked(true /* showing */, true /* force */,
+                        "exitKeyguardAndFinishSurfaceBehindRemoteAnimation - relocked");
 
                 return;
             }
 
-            onKeyguardExitFinished();
+            onKeyguardExitFinished("exitKeyguardAndFinishSurfaceBehindRemoteAnimation");
 
             if (mKeyguardStateController.isDismissingFromSwipe() || wasShowing) {
                 Log.d(TAG, "onKeyguardExitRemoteAnimationFinished"
@@ -3459,7 +3470,7 @@
         mSurfaceBehindRemoteAnimationRequested = false;
         mKeyguardStateController.notifyKeyguardGoingAway(false);
         if (mShowing) {
-            setShowingLocked(true, true);
+            setShowingLocked(true, true, "hideSurfaceBehindKeyguard");
         }
     }
 
@@ -3805,7 +3816,7 @@
         // update lock screen state in ATMS here, otherwise ATMS tries to resume activities when
         // enabling doze state.
         if (mShowing || !mPendingLock || !mDozeParameters.canControlUnlockedScreenOff()) {
-            setShowingLocked(mShowing);
+            setShowingLocked(mShowing, "setDozing");
         }
     }
 
@@ -3815,7 +3826,7 @@
         // is 1f), then show the activity lock screen.
         if (mAnimatingScreenOff && mDozing && linear == 1f) {
             mAnimatingScreenOff = false;
-            setShowingLocked(mShowing, true);
+            setShowingLocked(mShowing, true, "onDozeAmountChanged");
         }
     }
 
@@ -3853,11 +3864,11 @@
         }
     }
 
-    void setShowingLocked(boolean showing) {
-        setShowingLocked(showing, false /* forceCallbacks */);
+    void setShowingLocked(boolean showing, String reason) {
+        setShowingLocked(showing, false /* forceCallbacks */, reason);
     }
 
-    private void setShowingLocked(boolean showing, boolean forceCallbacks) {
+    private void setShowingLocked(boolean showing, boolean forceCallbacks, String reason) {
         final boolean aodShowing = mDozing && !mWakeAndUnlocking;
         final boolean notifyDefaultDisplayCallbacks = showing != mShowing || forceCallbacks;
         final boolean updateActivityLockScreenState = showing != mShowing
@@ -3868,9 +3879,8 @@
             notifyDefaultDisplayCallbacks(showing);
         }
         if (updateActivityLockScreenState) {
-            updateActivityLockScreenState(showing, aodShowing);
+            updateActivityLockScreenState(showing, aodShowing, reason);
         }
-
     }
 
     private void notifyDefaultDisplayCallbacks(boolean showing) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
new file mode 100644
index 0000000..443e9876
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
@@ -0,0 +1,11 @@
+set noparent
+
+# Bug component: 78010
+
+amiko@google.com
+beverlyt@google.com
+bhinegardner@google.com
+chandruis@google.com
+jglazier@google.com
+mpietal@google.com
+tsuji@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
index a460d51..9d8a7a8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToLockscreenTransitionViewModel.kt
@@ -51,7 +51,8 @@
             onCancel = { 0f },
         )
 
-    val lockscreenAlpha: Flow<Float> = shortcutsAlpha
+    // Show immediately to avoid what can appear to be a flicker on device wakeup
+    val lockscreenAlpha: Flow<Float> = transitionAnimation.immediatelyTransitionTo(1f)
 
     val deviceEntryBackgroundViewAlpha: Flow<Float> =
         transitionAnimation.immediatelyTransitionTo(1f)
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt
index d6affd2..228b576 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorActivity.kt
@@ -32,6 +32,10 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.accessibility.AccessibilityEvent
+import android.widget.ImageView
+import androidx.annotation.ColorRes
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.LifecycleRegistry
@@ -52,6 +56,7 @@
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.AsyncActivityLauncher
+import java.lang.IllegalArgumentException
 import javax.inject.Inject
 
 class MediaProjectionAppSelectorActivity(
@@ -116,6 +121,7 @@
 
         super.onCreate(savedInstanceState)
         controller.init()
+        setIcon()
         // we override AppList's AccessibilityDelegate set in ResolverActivity.onCreate because in
         // our case this delegate must extend RecyclerViewAccessibilityDelegate, otherwise
         // RecyclerView scrolling is broken
@@ -298,6 +304,29 @@
     override fun createContentPreviewView(parent: ViewGroup): ViewGroup =
         recentsViewController.createView(parent)
 
+    /** Set up intent for the [ChooserActivity] */
+    private fun Intent.configureChooserIntent(
+        resources: Resources,
+        hostUserHandle: UserHandle,
+        personalProfileUserHandle: UserHandle,
+    ) {
+        // Specify the query intent to show icons for all apps on the chooser screen
+        val queryIntent = Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_LAUNCHER) }
+        putExtra(Intent.EXTRA_INTENT, queryIntent)
+
+        // Update the title of the chooser
+        putExtra(Intent.EXTRA_TITLE, resources.getString(titleResId))
+
+        // Select host app's profile tab by default
+        val selectedProfile =
+            if (hostUserHandle == personalProfileUserHandle) {
+                PROFILE_PERSONAL
+            } else {
+                PROFILE_WORK
+            }
+        putExtra(EXTRA_SELECTED_PROFILE, selectedProfile)
+    }
+
     private val hostUserHandle: UserHandle
         get() {
             val extras =
@@ -321,6 +350,54 @@
             return intent.getIntExtra(EXTRA_HOST_APP_UID, /* defaultValue= */ -1)
         }
 
+    /**
+     * The type of screen sharing being performed. Used to show the right text and icon in the
+     * activity.
+     */
+    private val screenShareType: ScreenShareType?
+        get() {
+            if (!intent.hasExtra(EXTRA_SCREEN_SHARE_TYPE)) {
+                return null
+            } else {
+                val type = intent.getStringExtra(EXTRA_SCREEN_SHARE_TYPE) ?: return null
+                return try {
+                    enumValueOf<ScreenShareType>(type)
+                } catch (e: IllegalArgumentException) {
+                    null
+                }
+            }
+        }
+
+    @get:StringRes
+    private val titleResId: Int
+        get() =
+            when (screenShareType) {
+                ScreenShareType.ShareToApp ->
+                    R.string.media_projection_entry_share_app_selector_title
+                ScreenShareType.SystemCast ->
+                    R.string.media_projection_entry_cast_app_selector_title
+                ScreenShareType.ScreenRecord -> R.string.screenrecord_app_selector_title
+                null -> R.string.screen_share_generic_app_selector_title
+            }
+
+    @get:DrawableRes
+    private val iconResId: Int
+        get() =
+            when (screenShareType) {
+                ScreenShareType.ShareToApp -> R.drawable.ic_present_to_all
+                ScreenShareType.SystemCast -> R.drawable.ic_cast_connected
+                ScreenShareType.ScreenRecord -> R.drawable.ic_screenrecord
+                null -> R.drawable.ic_present_to_all
+            }
+
+    @get:ColorRes
+    private val iconTintResId: Int?
+        get() =
+            when (screenShareType) {
+                ScreenShareType.ScreenRecord -> R.color.screenrecord_icon_color
+                else -> null
+            }
+
     companion object {
         const val TAG = "MediaProjectionAppSelectorActivity"
 
@@ -343,30 +420,18 @@
         const val EXTRA_HOST_APP_UID = "launched_from_host_uid"
         const val KEY_CAPTURE_TARGET = "capture_region"
 
-        /** Set up intent for the [ChooserActivity] */
-        private fun Intent.configureChooserIntent(
-            resources: Resources,
-            hostUserHandle: UserHandle,
-            personalProfileUserHandle: UserHandle
-        ) {
-            // Specify the query intent to show icons for all apps on the chooser screen
-            val queryIntent =
-                Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_LAUNCHER) }
-            putExtra(Intent.EXTRA_INTENT, queryIntent)
+        /**
+         * The type of screen sharing being performed.
+         *
+         * The value set for this extra should match the name of a [ScreenShareType].
+         */
+        const val EXTRA_SCREEN_SHARE_TYPE = "screen_share_type"
+    }
 
-            // Update the title of the chooser
-            val title = resources.getString(R.string.screen_share_permission_app_selector_title)
-            putExtra(Intent.EXTRA_TITLE, title)
-
-            // Select host app's profile tab by default
-            val selectedProfile =
-                if (hostUserHandle == personalProfileUserHandle) {
-                    PROFILE_PERSONAL
-                } else {
-                    PROFILE_WORK
-                }
-            putExtra(EXTRA_SELECTED_PROFILE, selectedProfile)
-        }
+    private fun setIcon() {
+        val iconView = findViewById<ImageView>(R.id.media_projection_app_selector_icon) ?: return
+        iconView.setImageResource(iconResId)
+        iconTintResId?.let { iconView.setColorFilter(this.resources.getColor(it, this.theme)) }
     }
 
     private fun setAppListAccessibilityDelegate() {
@@ -406,4 +471,14 @@
             return delegate.onRequestSendAccessibilityEvent(host, child, event)
         }
     }
+
+    /** Enum describing what type of app screen sharing is being performed. */
+    enum class ScreenShareType {
+        /** The selected app will be cast to another device. */
+        SystemCast,
+        /** The selected app will be shared to another app on the device. */
+        ShareToApp,
+        /** The selected app will be recorded. */
+        ScreenRecord,
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
index 3c83db3..18c6f53 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
@@ -73,8 +73,7 @@
 
 import dagger.Lazy;
 
-public class MediaProjectionPermissionActivity extends Activity
-        implements DialogInterface.OnClickListener {
+public class MediaProjectionPermissionActivity extends Activity {
     private static final String TAG = "MediaProjectionPermissionActivity";
     private static final float MAX_APP_NAME_SIZE_PX = 500f;
     private static final String ELLIPSIS = "\u2026";
@@ -269,7 +268,8 @@
         Consumer<BaseMediaProjectionPermissionDialogDelegate<AlertDialog>> onStartRecordingClicked =
                 dialog -> {
                     ScreenShareOption selectedOption = dialog.getSelectedScreenShareOption();
-                    grantMediaProjectionPermission(selectedOption.getMode());
+                    grantMediaProjectionPermission(
+                            selectedOption.getMode(), hasCastingCapabilities);
                 };
         Runnable onCancelClicked = () -> finish(RECORD_CANCEL, /* projection= */ null);
         if (hasCastingCapabilities) {
@@ -305,19 +305,6 @@
         }
     }
 
-    @Override
-    public void onClick(DialogInterface dialog, int which) {
-        if (which == AlertDialog.BUTTON_POSITIVE) {
-            grantMediaProjectionPermission(ENTIRE_SCREEN);
-        } else {
-            if (mDialog != null) {
-                mDialog.dismiss();
-            }
-            setResult(RESULT_CANCELED);
-            finish(RECORD_CANCEL, /* projection= */ null);
-        }
-    }
-
     private void setUpDialog(AlertDialog dialog) {
         SystemUIDialog.registerDismissListener(dialog);
         SystemUIDialog.applyFlags(dialog);
@@ -345,25 +332,21 @@
         return false;
     }
 
-    private void grantMediaProjectionPermission(int screenShareMode) {
+    private void grantMediaProjectionPermission(
+            int screenShareMode, boolean hasCastingCapabilities) {
         try {
+            IMediaProjection projection = MediaProjectionServiceHelper.createOrReuseProjection(
+                    mUid, mPackageName, mReviewGrantedConsentRequired);
             if (screenShareMode == ENTIRE_SCREEN) {
-                final IMediaProjection projection =
-                        MediaProjectionServiceHelper.createOrReuseProjection(mUid, mPackageName,
-                                mReviewGrantedConsentRequired);
                 final Intent intent = new Intent();
-                intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION,
-                        projection.asBinder());
+                setCommonIntentExtras(intent, hasCastingCapabilities, projection);
                 setResult(RESULT_OK, intent);
                 finish(RECORD_CONTENT_DISPLAY, projection);
             }
             if (screenShareMode == SINGLE_APP) {
-                IMediaProjection projection = MediaProjectionServiceHelper.createOrReuseProjection(
-                        mUid, mPackageName, mReviewGrantedConsentRequired);
                 final Intent intent = new Intent(this,
                         MediaProjectionAppSelectorActivity.class);
-                intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION,
-                        projection.asBinder());
+                setCommonIntentExtras(intent, hasCastingCapabilities, projection);
                 intent.putExtra(MediaProjectionAppSelectorActivity.EXTRA_HOST_APP_USER_HANDLE,
                         getHostUserHandle());
                 intent.putExtra(
@@ -391,6 +374,19 @@
         }
     }
 
+    private void setCommonIntentExtras(
+            Intent intent,
+            boolean hasCastingCapabilities,
+            IMediaProjection projection) throws RemoteException {
+        intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION,
+                projection.asBinder());
+        intent.putExtra(
+                MediaProjectionAppSelectorActivity.EXTRA_SCREEN_SHARE_TYPE,
+                hasCastingCapabilities
+                        ? MediaProjectionAppSelectorActivity.ScreenShareType.SystemCast.name()
+                        : MediaProjectionAppSelectorActivity.ScreenShareType.ShareToApp.name());
+    }
+
     private UserHandle getHostUserHandle() {
         return UserHandle.getUserHandleForUid(getLaunchedFromUid());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
index 13a786a..ac878c2 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
@@ -38,6 +38,7 @@
 import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.inputmethodservice.InputMethodService;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -516,7 +517,7 @@
      * @return Whether the IME is shown on top of the screen given the {@code vis} flag of
      * {@link InputMethodService} and the keyguard states.
      */
-    public boolean isImeShown(int vis) {
+    public boolean isImeShown(@ImeWindowVisibility int vis) {
         View shadeWindowView =  mNotificationShadeWindowController.getWindowRootView();
         boolean isKeyguardShowing = mKeyguardStateController.isShowing();
         boolean imeVisibleOnShade = shadeWindowView != null && shadeWindowView.isAttachedToWindow()
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index 15b1e4d..cb0bb4a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -42,6 +42,8 @@
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
 import android.inputmethodservice.InputMethodService;
+import android.inputmethodservice.InputMethodService.BackDispositionMode;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.os.RemoteException;
 import android.os.Trace;
 import android.util.Log;
@@ -424,8 +426,8 @@
     }
 
     @Override
-    public void setImeWindowStatus(int displayId, int vis, int backDisposition,
-            boolean showImeSwitcher) {
+    public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis,
+            @BackDispositionMode int backDisposition, boolean showImeSwitcher) {
         boolean imeShown = mNavBarHelper.isImeShown(vis);
         if (!imeShown) {
             // Count imperceptible changes as visible so we transition taskbar out quickly.
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
index e895d83..c706c3e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
@@ -68,6 +68,8 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Region;
+import android.inputmethodservice.InputMethodService.BackDispositionMode;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -1098,8 +1100,8 @@
     // ----- CommandQueue Callbacks -----
 
     @Override
-    public void setImeWindowStatus(int displayId, int vis, int backDisposition,
-            boolean showImeSwitcher) {
+    public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis,
+            @BackDispositionMode int backDisposition, boolean showImeSwitcher) {
         if (displayId != mDisplayId) {
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 9939075..1511f31 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -259,6 +259,13 @@
     }
 
     /**
+     * @return height with the squishiness fraction applied.
+     */
+    int getSquishedQqsHeight() {
+        return mHeader.getSquishedHeight();
+    }
+
+    /**
      * Returns the size of QS (or the QSCustomizer), regardless of the measured size of this view
      * @return size in pixels of QS (or QSCustomizer)
      */
@@ -267,6 +274,13 @@
                 : mQSPanel.getMeasuredHeight();
     }
 
+    /**
+     * @return height with the squishiness fraction applied.
+     */
+    int getSquishedQsHeight() {
+        return mQSPanel.getSquishedHeight();
+    }
+
     public void setExpansion(float expansion) {
         mQsExpansion = expansion;
         if (mQSPanelContainer != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
index a6fd35a..0b37b5b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
@@ -992,11 +992,25 @@
         return mContainer.getQqsHeight();
     }
 
+    /**
+     * @return height with the squishiness fraction applied.
+     */
+    public int getSquishedQqsHeight() {
+        return mContainer.getSquishedQqsHeight();
+    }
+
     public int getQSHeight() {
         return mContainer.getQsHeight();
     }
 
     /**
+     * @return height with the squishiness fraction applied.
+     */
+    public int getSquishedQsHeight() {
+        return mContainer.getSquishedQsHeight();
+    }
+
+    /**
      * Pass the size of the navbar when it's at the bottom of the device so it can be used as
      * padding
      * @param padding size of the bottom nav bar in px
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 032891f..d3bed27 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -733,6 +733,30 @@
         mCanCollapse = canCollapse;
     }
 
+    /**
+     * @return height with the {@link QSPanel#setSquishinessFraction(float)} applied.
+     */
+    public int getSquishedHeight() {
+        if (mFooter != null) {
+            final ViewGroup.LayoutParams footerLayoutParams = mFooter.getLayoutParams();
+            final int footerBottomMargin;
+            if (footerLayoutParams instanceof MarginLayoutParams) {
+                footerBottomMargin = ((MarginLayoutParams) footerLayoutParams).bottomMargin;
+            } else {
+                footerBottomMargin = 0;
+            }
+            // This is the distance between the top of the QSPanel and the last view in the
+            // layout (which is the effective the bottom)
+            return mFooter.getBottom() + footerBottomMargin - getTop();
+        }
+        if (mTileLayout != null) {
+            // Footer absence means that the panel is in the QQS. In this case it's just height
+            // of the tiles + paddings.
+            return mTileLayout.getTilesHeight() + getPaddingBottom() + getPaddingTop();
+        }
+        return getHeight();
+    }
+
     @Nullable
     @VisibleForTesting
     View getMediaPlaceholder() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 5a3f1c0..8fde52c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -123,4 +123,11 @@
         lp.setMarginEnd(marginEnd);
         view.setLayoutParams(lp);
     }
+
+    /**
+     * @return height with the squishiness fraction applied.
+     */
+    public int getSquishedHeight() {
+        return mHeaderQsPanel.getSquishedHeight();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
index ae2f32a..dfcf216 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
@@ -34,7 +34,6 @@
 import com.android.systemui.qs.QSContainerImpl
 import com.android.systemui.qs.QSImpl
 import com.android.systemui.qs.dagger.QSSceneComponent
-import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel.state
 import com.android.systemui.res.R
 import com.android.systemui.settings.brightness.MirrorController
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -126,12 +125,18 @@
     /** The current height of QQS in the current [qsView], or 0 if there's no view. */
     val qqsHeight: Int
 
+    /** @return height with the squishiness fraction applied. */
+    val squishedQqsHeight: Int
+
     /**
      * The current height of QS in the current [qsView], or 0 if there's no view. If customizing, it
      * will return the height allocated to the customizer.
      */
     val qsHeight: Int
 
+    /** @return height with the squishiness fraction applied. */
+    val squishedQsHeight: Int
+
     /** Compatibility for use by LockscreenShadeTransitionController. Matches default from [QS] */
     val isQsFullyCollapsed: Boolean
         get() = true
@@ -273,9 +278,15 @@
     override val qqsHeight: Int
         get() = qsImpl.value?.qqsHeight ?: 0
 
+    override val squishedQqsHeight: Int
+        get() = qsImpl.value?.squishedQqsHeight ?: 0
+
     override val qsHeight: Int
         get() = qsImpl.value?.qsHeight ?: 0
 
+    override val squishedQsHeight: Int
+        get() = qsImpl.value?.squishedQsHeight ?: 0
+
     // If value is null, there's no QS and therefore it's fully collapsed.
     override val isQsFullyCollapsed: Boolean
         get() = qsImpl.value?.isFullyCollapsed ?: true
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 3ec088c..e73664d 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -154,7 +154,6 @@
             handleKeyguardEnabledness()
             notifyKeyguardDismissCallbacks()
             refreshLockscreenEnabled()
-            handleHideAlternateBouncerOnTransitionToGone()
         } else {
             sceneLogger.logFrameworkEnabled(
                 isEnabled = false,
@@ -357,11 +356,10 @@
                                 )
                         }
                     val isOnLockscreen = renderedScenes.contains(Scenes.Lockscreen)
-                    val isOnBouncer =
-                        renderedScenes.contains(Scenes.Bouncer) ||
-                            alternateBouncerInteractor.isVisibleState()
+                    val isAlternateBouncerVisible = alternateBouncerInteractor.isVisibleState()
+                    val isOnPrimaryBouncer = renderedScenes.contains(Scenes.Bouncer)
                     if (!deviceUnlockStatus.isUnlocked) {
-                        return@mapNotNull if (isOnLockscreen || isOnBouncer) {
+                        return@mapNotNull if (isOnLockscreen || isOnPrimaryBouncer) {
                             // Already on lockscreen or bouncer, no need to change scenes.
                             null
                         } else {
@@ -373,15 +371,32 @@
                     }
 
                     if (
-                        isOnBouncer &&
+                        isOnPrimaryBouncer &&
                             deviceUnlockStatus.deviceUnlockSource == DeviceUnlockSource.TrustAgent
                     ) {
                         uiEventLogger.log(BouncerUiEvent.BOUNCER_DISMISS_EXTENDED_ACCESS)
                     }
                     when {
-                        isOnBouncer ->
-                            // When the device becomes unlocked in Bouncer, go to previous scene,
-                            // or Gone.
+                        isAlternateBouncerVisible -> {
+                            // When the device becomes unlocked when the alternate bouncer is
+                            // showing, always hide the alternate bouncer...
+                            alternateBouncerInteractor.hide()
+
+                            // ... and go to Gone or stay on the current scene
+                            if (
+                                isOnLockscreen ||
+                                    !statusBarStateController.leaveOpenOnKeyguardHide()
+                            ) {
+                                Scenes.Gone to
+                                    "device was unlocked with alternate bouncer showing" +
+                                        " and shade didn't need to be left open"
+                            } else {
+                                null
+                            }
+                        }
+                        isOnPrimaryBouncer ->
+                            // When the device becomes unlocked in primary Bouncer,
+                            // go to previous scene or Gone.
                             if (
                                 previousScene.value == Scenes.Lockscreen ||
                                     !statusBarStateController.leaveOpenOnKeyguardHide()
@@ -392,7 +407,7 @@
                             } else {
                                 val prevScene = previousScene.value
                                 (prevScene ?: Scenes.Gone) to
-                                    "device was unlocked with bouncer showing," +
+                                    "device was unlocked with primary bouncer showing," +
                                         " from sceneKey=$prevScene"
                             }
                         isOnLockscreen ->
@@ -785,14 +800,4 @@
                 .collectLatest { deviceEntryInteractor.refreshLockscreenEnabled() }
         }
     }
-
-    private fun handleHideAlternateBouncerOnTransitionToGone() {
-        applicationScope.launch {
-            sceneInteractor.transitionState
-                .map { it.isIdle(Scenes.Gone) }
-                .distinctUntilChanged()
-                .filter { it }
-                .collectLatest { alternateBouncerInteractor.hide() }
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt
index 46ac54f..f3357ee 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt
@@ -146,6 +146,10 @@
                     hostUserHandle
                 )
                 intent.putExtra(MediaProjectionAppSelectorActivity.EXTRA_HOST_APP_UID, hostUid)
+                intent.putExtra(
+                    MediaProjectionAppSelectorActivity.EXTRA_SCREEN_SHARE_TYPE,
+                    MediaProjectionAppSelectorActivity.ScreenShareType.ScreenRecord.name,
+                )
                 activityStarter.startActivity(intent, /* dismissShade= */ true)
             }
             dialog.dismiss()
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 104d4b5..65a59f5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -1339,6 +1339,10 @@
                 "NotificationPanelViewController.updateResources");
 
         if (splitShadeChanged) {
+            if (isPanelVisibleBecauseOfHeadsUp()) {
+                // workaround for b/324642496, because HUNs set state to OPENING
+                onPanelStateChanged(STATE_CLOSED);
+            }
             onSplitShadeEnabledChanged();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 50be6dc..a1477b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -37,6 +37,7 @@
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback;
 import android.inputmethodservice.InputMethodService.BackDispositionMode;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.media.INearbyMediaDevicesProvider;
 import android.media.MediaRoute2Info;
 import android.os.Binder;
@@ -257,10 +258,10 @@
          *
          * @param displayId The id of the display to notify.
          * @param vis IME visibility.
-         * @param backDisposition Disposition mode of back button. It should be one of below flags:
+         * @param backDisposition Disposition mode of back button.
          * @param showImeSwitcher {@code true} to show IME switch button.
          */
-        default void setImeWindowStatus(int displayId, int vis,
+        default void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis,
                 @BackDispositionMode int backDisposition, boolean showImeSwitcher) { }
         default void showRecentApps(boolean triggeredFromAltTab) { }
         default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { }
@@ -743,8 +744,8 @@
     }
 
     @Override
-    public void setImeWindowStatus(int displayId, int vis, int backDisposition,
-            boolean showImeSwitcher) {
+    public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis,
+            @BackDispositionMode int backDisposition, boolean showImeSwitcher) {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_SHOW_IME_BUTTON);
             SomeArgs args = SomeArgs.obtain();
@@ -1205,8 +1206,8 @@
         }
     }
 
-    private void handleShowImeButton(int displayId, int vis, int backDisposition,
-            boolean showImeSwitcher) {
+    private void handleShowImeButton(int displayId, @ImeWindowVisibility int vis,
+            @BackDispositionMode int backDisposition, boolean showImeSwitcher) {
         if (displayId == INVALID_DISPLAY) return;
 
         boolean isConcurrentMultiUserModeEnabled = UserManager.isVisibleBackgroundUsersEnabled()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
index 69ebb76..c4f539a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
@@ -5,3 +5,12 @@
 caitlinshk@google.com
 evanlaird@google.com
 pixel@google.com
+
+per-file *Biometrics* = set noparent
+per-file *Biometrics* = file:../keyguard/OWNERS
+per-file *Doze* = set noparent
+per-file *Doze* = file:../keyguard/OWNERS
+per-file *Keyboard* = set noparent
+per-file *Keyboard* = file:../keyguard/OWNERS
+per-file *Keyguard* = set noparent
+per-file *Keyguard* = file:../keyguard/OWNERS
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index ada3c52..c4fbc37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -30,6 +30,7 @@
 import static com.android.systemui.Flags.keyboardShortcutHelperRewrite;
 import static com.android.systemui.Flags.lightRevealMigration;
 import static com.android.systemui.Flags.newAodTransition;
+import static com.android.systemui.Flags.relockWithPowerButtonImmediately;
 import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL;
 import static com.android.systemui.flags.Flags.SHORTCUT_LIST_SEARCH_LAYOUT;
 import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
@@ -2352,11 +2353,13 @@
             } else if (mState == StatusBarState.KEYGUARD
                     && !mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing()
                     && mStatusBarKeyguardViewManager.isSecure()) {
-                Log.d(TAG, "showBouncerOrLockScreenIfKeyguard, showingBouncer");
-                if (SceneContainerFlag.isEnabled()) {
-                    mStatusBarKeyguardViewManager.showPrimaryBouncer(true /* scrimmed */);
-                } else {
-                    mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */);
+                if (!relockWithPowerButtonImmediately()) {
+                    Log.d(TAG, "showBouncerOrLockScreenIfKeyguard, showingBouncer");
+                    if (SceneContainerFlag.isEnabled()) {
+                        mStatusBarKeyguardViewManager.showPrimaryBouncer(true /* scrimmed */);
+                    } else {
+                        mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */);
+                    }
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index f13a593..ac10155 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -424,14 +424,12 @@
 
     @Override
     public void setDozeScreenBrightness(int brightness) {
-        mDozeLog.traceDozeScreenBrightness(brightness);
         mNotificationShadeWindowController.setDozeScreenBrightness(brightness);
     }
 
 
     @Override
     public void setDozeScreenBrightnessFloat(float brightness) {
-        mDozeLog.traceDozeScreenBrightnessFloat(brightness);
         mNotificationShadeWindowController.setDozeScreenBrightnessFloat(brightness);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadKeyboardTutorialModule.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadKeyboardTutorialModule.kt
deleted file mode 100644
index 8ba8db4..0000000
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadKeyboardTutorialModule.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.systemui.touchpad.tutorial
-
-import android.app.Activity
-import com.android.systemui.touchpad.tutorial.ui.view.TouchpadTutorialActivity
-import dagger.Binds
-import dagger.Module
-import dagger.multibindings.ClassKey
-import dagger.multibindings.IntoMap
-
-@Module
-interface TouchpadKeyboardTutorialModule {
-
-    @Binds
-    @IntoMap
-    @ClassKey(TouchpadTutorialActivity::class)
-    fun activity(impl: TouchpadTutorialActivity): Activity
-}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
new file mode 100644
index 0000000..238e8a1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt
@@ -0,0 +1,73 @@
+/*
+ * 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.systemui.touchpad.tutorial
+
+import android.app.Activity
+import androidx.compose.runtime.Composable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.inputdevice.tutorial.TouchpadTutorialScreensProvider
+import com.android.systemui.model.SysUiState
+import com.android.systemui.settings.DisplayTracker
+import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor
+import com.android.systemui.touchpad.tutorial.ui.composable.BackGestureTutorialScreen
+import com.android.systemui.touchpad.tutorial.ui.composable.HomeGestureTutorialScreen
+import com.android.systemui.touchpad.tutorial.ui.view.TouchpadTutorialActivity
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+import kotlinx.coroutines.CoroutineScope
+
+@Module
+interface TouchpadTutorialModule {
+
+    @Binds
+    @IntoMap
+    @ClassKey(TouchpadTutorialActivity::class)
+    fun activity(impl: TouchpadTutorialActivity): Activity
+
+    companion object {
+        @Provides
+        fun touchpadScreensProvider(): TouchpadTutorialScreensProvider {
+            return ScreensProvider
+        }
+
+        @SysUISingleton
+        @Provides
+        fun touchpadGesturesInteractor(
+            sysUiState: SysUiState,
+            displayTracker: DisplayTracker,
+            @Background backgroundScope: CoroutineScope
+        ): TouchpadGesturesInteractor {
+            return TouchpadGesturesInteractor(sysUiState, displayTracker, backgroundScope)
+        }
+    }
+}
+
+private object ScreensProvider : TouchpadTutorialScreensProvider {
+    @Composable
+    override fun BackGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) {
+        BackGestureTutorialScreen(onDoneButtonClicked, onBack)
+    }
+
+    @Composable
+    override fun HomeGesture(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) {
+        HomeGestureTutorialScreen(onDoneButtonClicked, onBack)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt
index b6c2ae7..df95232 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt
@@ -16,22 +16,16 @@
 
 package com.android.systemui.touchpad.tutorial.domain.interactor
 
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.model.SysUiState
 import com.android.systemui.settings.DisplayTracker
 import com.android.systemui.shared.system.QuickStepContract
-import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 
-@SysUISingleton
-class TouchpadGesturesInteractor
-@Inject
-constructor(
+class TouchpadGesturesInteractor(
     private val sysUiState: SysUiState,
     private val displayTracker: DisplayTracker,
-    @Background private val backgroundScope: CoroutineScope
+    private val backgroundScope: CoroutineScope
 ) {
     fun disableGestures() {
         setGesturesState(disabled = true)
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
index 5980e1d..1c8041f 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/BackGestureTutorialScreen.kt
@@ -21,6 +21,8 @@
 import androidx.compose.runtime.remember
 import com.airbnb.lottie.compose.rememberLottieDynamicProperties
 import com.android.compose.theme.LocalAndroidColorScheme
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig
+import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty
 import com.android.systemui.res.R
 import com.android.systemui.touchpad.tutorial.ui.gesture.BackGestureMonitor
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
index dfe9c0d..57d7c84 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/GestureTutorialScreen.kt
@@ -28,6 +28,9 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.input.pointer.pointerInteropFilter
 import androidx.compose.ui.platform.LocalContext
+import com.android.systemui.inputdevice.tutorial.ui.composable.ActionTutorialContent
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.FINISHED
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState.IN_PROGRESS
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
index ed3110c..0a6283a 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/HomeGestureTutorialScreen.kt
@@ -21,6 +21,8 @@
 import androidx.compose.runtime.remember
 import com.airbnb.lottie.compose.rememberLottieDynamicProperties
 import com.android.compose.theme.LocalAndroidColorScheme
+import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig
+import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty
 import com.android.systemui.res.R
 import com.android.systemui.touchpad.tutorial.ui.gesture.GestureState
 import com.android.systemui.touchpad.tutorial.ui.gesture.HomeGestureMonitor
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt
index 14355fa..65b452a 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt
@@ -34,6 +34,7 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.unit.dp
+import com.android.systemui.inputdevice.tutorial.ui.composable.DoneButton
 import com.android.systemui.res.R
 
 @Composable
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
index 48e6397..256c5b5 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
@@ -27,7 +27,7 @@
 import androidx.lifecycle.Lifecycle.State.STARTED
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.theme.PlatformTheme
-import com.android.systemui.touchpad.tutorial.ui.composable.ActionKeyTutorialScreen
+import com.android.systemui.inputdevice.tutorial.ui.composable.ActionKeyTutorialScreen
 import com.android.systemui.touchpad.tutorial.ui.composable.BackGestureTutorialScreen
 import com.android.systemui.touchpad.tutorial.ui.composable.HomeGestureTutorialScreen
 import com.android.systemui.touchpad.tutorial.ui.composable.TutorialSelectionScreen
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
index 5d8b6f1..d39daaf 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
@@ -79,13 +79,15 @@
             localBluetoothManager: LocalBluetoothManager?,
             @Application coroutineScope: CoroutineScope,
             @Background coroutineContext: CoroutineContext,
+            volumeLogger: VolumeLogger
         ): AudioSharingRepository =
             if (Flags.enableLeAudioSharing() && localBluetoothManager != null) {
                 AudioSharingRepositoryImpl(
                     contentResolver,
                     localBluetoothManager,
                     coroutineScope,
-                    coroutineContext
+                    coroutineContext,
+                    volumeLogger
                 )
             } else {
                 AudioSharingRepositoryEmptyImpl()
diff --git a/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt b/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt
index 869a82a..d6b159e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt
@@ -16,7 +16,8 @@
 
 package com.android.systemui.volume.shared
 
-import com.android.settingslib.volume.data.repository.AudioRepositoryImpl
+import com.android.settingslib.volume.shared.AudioLogger
+import com.android.settingslib.volume.shared.AudioSharingLogger
 import com.android.settingslib.volume.shared.model.AudioStream
 import com.android.settingslib.volume.shared.model.AudioStreamModel
 import com.android.systemui.dagger.SysUISingleton
@@ -30,7 +31,7 @@
 /** Logs general System UI volume events. */
 @SysUISingleton
 class VolumeLogger @Inject constructor(@VolumeLog private val logBuffer: LogBuffer) :
-    AudioRepositoryImpl.Logger {
+    AudioLogger, AudioSharingLogger {
 
     override fun onSetVolumeRequested(audioStream: AudioStream, volume: Int) {
         logBuffer.log(
@@ -55,4 +56,35 @@
             { "Volume update received: stream=$str1 volume=$int1" }
         )
     }
+
+    override fun onAudioSharingStateChanged(state: Boolean) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { bool1 = state },
+            { "Audio sharing state update: state=$bool1" }
+        )
+    }
+
+    override fun onSecondaryGroupIdChanged(groupId: Int) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { int1 = groupId },
+            { "Secondary group id in audio sharing update: groupId=$int1" }
+        )
+    }
+
+    override fun onVolumeMapChanged(map: Map<Int, Int>) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { str1 = map.toString() },
+            { "Volume map update: map=$str1" }
+        )
+    }
+
+    override fun onSetDeviceVolumeRequested(volume: Int) {
+        logBuffer.log(TAG, LogLevel.DEBUG, { int1 = volume }, { "Set device volume: volume=$int1" })
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 9ca0591..50efc21 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -34,6 +34,8 @@
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.inputmethodservice.InputMethodService;
+import android.inputmethodservice.InputMethodService.BackDispositionMode;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.util.Log;
 import android.view.Display;
 import android.view.KeyEvent;
@@ -378,8 +380,8 @@
             }
 
             @Override
-            public void setImeWindowStatus(int displayId, int vis, int backDisposition,
-                    boolean showImeSwitcher) {
+            public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis,
+                    @BackDispositionMode int backDisposition, boolean showImeSwitcher) {
                 if (displayId == mDisplayTracker.getDefaultDisplayId()
                         && (vis & InputMethodService.IME_VISIBLE) != 0) {
                     oneHanded.stopOneHanded(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java
index 419f7ed..299c384 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java
@@ -29,31 +29,22 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.concurrent.Executor;
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DozeScreenStatePreventingAdapterTest extends SysuiTestCase {
 
-    private Executor mExecutor;
     private DozeMachine.Service mInner;
     private DozeScreenStatePreventingAdapter mWrapper;
 
     @Before
     public void setup() throws Exception {
-        mExecutor = new FakeExecutor(new FakeSystemClock());
         mInner = mock(DozeMachine.Service.class);
-        mWrapper = new DozeScreenStatePreventingAdapter(
-                mInner,
-                mExecutor
-        );
+        mWrapper = new DozeScreenStatePreventingAdapter(mInner);
     }
 
     @Test
@@ -98,7 +89,7 @@
         when(params.getDisplayStateSupported()).thenReturn(false);
 
         assertEquals(DozeScreenStatePreventingAdapter.class,
-                DozeScreenStatePreventingAdapter.wrapIfNeeded(mInner, params, mExecutor)
+                DozeScreenStatePreventingAdapter.wrapIfNeeded(mInner, params)
                         .getClass());
     }
 
@@ -107,7 +98,6 @@
         DozeParameters params = mock(DozeParameters.class);
         when(params.getDisplayStateSupported()).thenReturn(true);
 
-        assertSame(mInner, DozeScreenStatePreventingAdapter.wrapIfNeeded(mInner, params,
-                mExecutor));
+        assertSame(mInner, DozeScreenStatePreventingAdapter.wrapIfNeeded(mInner, params));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
index 5a89710..0d6a9ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
@@ -29,28 +29,22 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.concurrent.Executor;
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DozeSuspendScreenStatePreventingAdapterTest extends SysuiTestCase {
 
-    private Executor mExecutor;
     private DozeMachine.Service mInner;
     private DozeSuspendScreenStatePreventingAdapter mWrapper;
 
     @Before
     public void setup() throws Exception {
-        mExecutor = new FakeExecutor(new FakeSystemClock());
         mInner = mock(DozeMachine.Service.class);
-        mWrapper = new DozeSuspendScreenStatePreventingAdapter(mInner, mExecutor);
+        mWrapper = new DozeSuspendScreenStatePreventingAdapter(mInner);
     }
 
     @Test
@@ -101,7 +95,7 @@
         when(params.getDozeSuspendDisplayStateSupported()).thenReturn(false);
 
         assertEquals(DozeSuspendScreenStatePreventingAdapter.class,
-                DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params, mExecutor)
+                DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params)
                         .getClass());
     }
 
@@ -110,7 +104,6 @@
         DozeParameters params = mock(DozeParameters.class);
         when(params.getDozeSuspendDisplayStateSupported()).thenReturn(true);
 
-        assertSame(mInner, DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params,
-                mExecutor));
+        assertSame(mInner, DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(mInner, params));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index e3a38a8..37f1a3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -443,7 +443,7 @@
         mViewMediator.onSystemReady();
         TestableLooper.get(this).processAllMessages();
 
-        mViewMediator.setShowingLocked(false);
+        mViewMediator.setShowingLocked(false, "");
         TestableLooper.get(this).processAllMessages();
 
         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
@@ -463,7 +463,7 @@
         mViewMediator.onSystemReady();
         TestableLooper.get(this).processAllMessages();
 
-        mViewMediator.setShowingLocked(false);
+        mViewMediator.setShowingLocked(false, "");
         TestableLooper.get(this).processAllMessages();
 
         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
@@ -570,7 +570,7 @@
         // When showing and provisioned
         mViewMediator.onSystemReady();
         when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true);
-        mViewMediator.setShowingLocked(true);
+        mViewMediator.setShowingLocked(true, "");
 
         // and a SIM becomes locked and requires a PIN
         mViewMediator.mUpdateCallback.onSimStateChanged(
@@ -579,7 +579,7 @@
                 TelephonyManager.SIM_STATE_PIN_REQUIRED);
 
         // and the keyguard goes away
-        mViewMediator.setShowingLocked(false);
+        mViewMediator.setShowingLocked(false, "");
         when(mKeyguardStateController.isShowing()).thenReturn(false);
         mViewMediator.mUpdateCallback.onKeyguardVisibilityChanged(false);
 
@@ -595,7 +595,7 @@
         // When showing and provisioned
         mViewMediator.onSystemReady();
         when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true);
-        mViewMediator.setShowingLocked(false);
+        mViewMediator.setShowingLocked(false, "");
 
         // and a SIM becomes locked and requires a PIN
         mViewMediator.mUpdateCallback.onSimStateChanged(
@@ -604,7 +604,7 @@
                 TelephonyManager.SIM_STATE_PIN_REQUIRED);
 
         // and the keyguard goes away
-        mViewMediator.setShowingLocked(false);
+        mViewMediator.setShowingLocked(false, "");
         when(mKeyguardStateController.isShowing()).thenReturn(false);
         mViewMediator.mUpdateCallback.onKeyguardVisibilityChanged(false);
 
@@ -843,7 +843,7 @@
         mViewMediator.onSystemReady();
         TestableLooper.get(this).processAllMessages();
 
-        mViewMediator.setShowingLocked(false);
+        mViewMediator.setShowingLocked(false, "");
         TestableLooper.get(this).processAllMessages();
 
         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
@@ -863,7 +863,7 @@
         mViewMediator.onSystemReady();
         TestableLooper.get(this).processAllMessages();
 
-        mViewMediator.setShowingLocked(false);
+        mViewMediator.setShowingLocked(false, "");
         TestableLooper.get(this).processAllMessages();
 
         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
@@ -978,7 +978,7 @@
     @Test
     @TestableLooper.RunWithLooper(setAsMainLooper = true)
     public void testDoKeyguardWhileInteractive_resets() {
-        mViewMediator.setShowingLocked(true);
+        mViewMediator.setShowingLocked(true, "");
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         TestableLooper.get(this).processAllMessages();
 
@@ -992,7 +992,7 @@
     @Test
     @TestableLooper.RunWithLooper(setAsMainLooper = true)
     public void testDoKeyguardWhileNotInteractive_showsInsteadOfResetting() {
-        mViewMediator.setShowingLocked(true);
+        mViewMediator.setShowingLocked(true, "");
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         TestableLooper.get(this).processAllMessages();
 
@@ -1051,7 +1051,7 @@
         mViewMediator.onSystemReady();
         processAllMessagesAndBgExecutorMessages();
 
-        mViewMediator.setShowingLocked(true);
+        mViewMediator.setShowingLocked(true, "");
 
         RemoteAnimationTarget[] apps = new RemoteAnimationTarget[]{
                 mock(RemoteAnimationTarget.class)
@@ -1123,7 +1123,7 @@
     @Test
     @TestableLooper.RunWithLooper(setAsMainLooper = true)
     public void testNotStartingKeyguardWhenFlagIsDisabled() {
-        mViewMediator.setShowingLocked(false);
+        mViewMediator.setShowingLocked(false, "");
         when(mKeyguardStateController.isShowing()).thenReturn(false);
 
         mViewMediator.onDreamingStarted();
@@ -1133,7 +1133,7 @@
     @Test
     @TestableLooper.RunWithLooper(setAsMainLooper = true)
     public void testStartingKeyguardWhenFlagIsEnabled() {
-        mViewMediator.setShowingLocked(true);
+        mViewMediator.setShowingLocked(true, "");
         when(mKeyguardStateController.isShowing()).thenReturn(true);
 
         mViewMediator.onDreamingStarted();
@@ -1174,7 +1174,7 @@
         TestableLooper.get(this).processAllMessages();
 
         // WHEN keyguard visibility becomes FALSE
-        mViewMediator.setShowingLocked(false);
+        mViewMediator.setShowingLocked(false, "");
         keyguardUpdateMonitorCallback.onKeyguardVisibilityChanged(false);
         TestableLooper.get(this).processAllMessages();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 6916bbd..d10ea1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -15,7 +15,9 @@
 package com.android.systemui.statusbar;
 
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
+import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_ADJUST_NOTHING;
 import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
+import static android.inputmethodservice.InputMethodService.IME_ACTIVE;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT;
 
@@ -194,9 +196,11 @@
 
     @Test
     public void testShowImeButton() {
-        mCommandQueue.setImeWindowStatus(DEFAULT_DISPLAY, 1, 2, true);
+        mCommandQueue.setImeWindowStatus(DEFAULT_DISPLAY, IME_ACTIVE,
+                BACK_DISPOSITION_ADJUST_NOTHING, true);
         waitForIdleSync();
-        verify(mCallbacks).setImeWindowStatus(eq(DEFAULT_DISPLAY), eq(1), eq(2), eq(true));
+        verify(mCallbacks).setImeWindowStatus(eq(DEFAULT_DISPLAY), eq(IME_ACTIVE),
+                eq(BACK_DISPOSITION_ADJUST_NOTHING), eq(true));
     }
 
     @Test
@@ -204,11 +208,13 @@
         // First show in default display to update the "last updated ime display"
         testShowImeButton();
 
-        mCommandQueue.setImeWindowStatus(SECONDARY_DISPLAY, 1, 2, true);
+        mCommandQueue.setImeWindowStatus(SECONDARY_DISPLAY, IME_ACTIVE,
+                BACK_DISPOSITION_ADJUST_NOTHING, true);
         waitForIdleSync();
-        verify(mCallbacks).setImeWindowStatus(eq(DEFAULT_DISPLAY), eq(0),
+        verify(mCallbacks).setImeWindowStatus(eq(DEFAULT_DISPLAY), eq(0) /* vis */,
                 eq(BACK_DISPOSITION_DEFAULT), eq(false));
-        verify(mCallbacks).setImeWindowStatus(eq(SECONDARY_DISPLAY), eq(1), eq(2), eq(true));
+        verify(mCallbacks).setImeWindowStatus(eq(SECONDARY_DISPLAY), eq(IME_ACTIVE),
+                eq(BACK_DISPOSITION_ADJUST_NOTHING), eq(true));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt
index b6194e3..bbe753e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt
@@ -27,7 +27,9 @@
 class FakeQSSceneAdapter(
     private val inflateDelegate: suspend (Context) -> View,
     override val qqsHeight: Int = 0,
+    override val squishedQqsHeight: Int = 0,
     override val qsHeight: Int = 0,
+    override val squishedQsHeight: Int = 0,
 ) : QSSceneAdapter {
     private val _customizerState = MutableStateFlow<CustomizerState>(CustomizerState.Hidden)
 
diff --git a/services/Android.bp b/services/Android.bp
index ded7379..0006455 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -120,6 +120,7 @@
         ":services.backup-sources",
         ":services.companion-sources",
         ":services.contentcapture-sources",
+        ":services.appfunctions-sources",
         ":services.contentsuggestions-sources",
         ":services.contextualsearch-sources",
         ":services.coverage-sources",
@@ -217,6 +218,7 @@
         "services.autofill",
         "services.backup",
         "services.companion",
+        "services.appfunctions",
         "services.contentcapture",
         "services.contentsuggestions",
         "services.contextualsearch",
diff --git a/services/appfunctions/Android.bp b/services/appfunctions/Android.bp
new file mode 100644
index 0000000..f8ee823
--- /dev/null
+++ b/services/appfunctions/Android.bp
@@ -0,0 +1,25 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+    name: "services.appfunctions-sources",
+    srcs: ["java/**/*.java"],
+    path: "java",
+    visibility: ["//frameworks/base/services"],
+}
+
+java_library_static {
+    name: "services.appfunctions",
+    defaults: ["platform_service_defaults"],
+    srcs: [
+        ":services.appfunctions-sources",
+        "java/**/*.logtags",
+    ],
+    libs: ["services.core"],
+}
diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerService.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerService.java
new file mode 100644
index 0000000..f30e770
--- /dev/null
+++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerService.java
@@ -0,0 +1,45 @@
+/*
+ * 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.appfunctions;
+
+import static android.app.appfunctions.flags.Flags.enableAppFunctionManager;
+
+import android.app.appfunctions.IAppFunctionManager;
+import android.content.Context;
+
+import com.android.server.SystemService;
+
+/**
+ * Service that manages app functions.
+ */
+public class AppFunctionManagerService extends SystemService {
+
+    public AppFunctionManagerService(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onStart() {
+        if (enableAppFunctionManager()) {
+            publishBinderService(Context.APP_FUNCTION_SERVICE, new AppFunctionManagerStub());
+        }
+    }
+
+    private static class AppFunctionManagerStub extends IAppFunctionManager.Stub {
+
+    }
+}
diff --git a/services/core/java/com/android/server/AlarmManagerInternal.java b/services/core/java/com/android/server/AlarmManagerInternal.java
index b7f2b8d..191137a 100644
--- a/services/core/java/com/android/server/AlarmManagerInternal.java
+++ b/services/core/java/com/android/server/AlarmManagerInternal.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.annotation.CurrentTimeMillisLong;
+import android.annotation.UserIdInt;
 import android.app.PendingIntent;
 
 import com.android.server.SystemClockTime.TimeConfidence;
@@ -36,6 +37,16 @@
     /** Returns true if AlarmManager is delaying alarms due to device idle. */
     boolean isIdling();
 
+    /**
+     * Returns the time at which the next alarm for the given user is going to trigger, or 0 if
+     * there is none.
+     *
+     * <p>This value is UTC wall clock time in milliseconds, as returned by
+     * {@link System#currentTimeMillis()} for example.
+     * @see android.app.AlarmManager.AlarmClockInfo#getTriggerTime()
+     */
+    long getNextAlarmTriggerTimeForUser(@UserIdInt int userId);
+
     public void removeAlarmsForUid(int uid);
 
     public void registerInFlightListener(InFlightListener callback);
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index e57fe13..bdba6bc 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -131,6 +131,7 @@
 import com.android.internal.util.ObjectUtils;
 import com.android.internal.util.Preconditions;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.server.AlarmManagerInternal;
 import com.android.server.FactoryResetter;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
@@ -247,6 +248,12 @@
     private static final int USER_COMPLETED_EVENT_DELAY_MS = 5 * 1000;
 
     /**
+     * If a user has an alarm in the next this many milliseconds, avoid stopping it due to
+     * scheduled background stopping.
+     */
+    private static final long TIME_BEFORE_USERS_ALARM_TO_AVOID_STOPPING_MS = 60 * 60_000; // 60 mins
+
+    /**
      * Maximum number of users we allow to be running at a time, including system user.
      *
      * <p>This parameter only affects how many background users will be stopped when switching to a
@@ -2418,6 +2425,12 @@
     void processScheduledStopOfBackgroundUser(Integer userIdInteger) {
         final int userId = userIdInteger;
         Slogf.d(TAG, "Considering stopping background user %d due to inactivity", userId);
+
+        if (avoidStoppingUserDueToUpcomingAlarm(userId)) {
+            // We want this user running soon for alarm-purposes, so don't stop it now. Reschedule.
+            scheduleStopOfBackgroundUser(userId);
+            return;
+        }
         synchronized (mLock) {
             if (getCurrentOrTargetUserIdLU() == userId) {
                 return;
@@ -2437,6 +2450,18 @@
         }
     }
 
+    /**
+     * Returns whether we should avoid stopping the user now due to it having an alarm set to fire
+     * soon.
+     */
+    private boolean avoidStoppingUserDueToUpcomingAlarm(@UserIdInt int userId) {
+        final long alarmWallclockMs
+                = mInjector.getAlarmManagerInternal().getNextAlarmTriggerTimeForUser(userId);
+        return System.currentTimeMillis() <  alarmWallclockMs
+                && (alarmWallclockMs
+                    < System.currentTimeMillis() + TIME_BEFORE_USERS_ALARM_TO_AVOID_STOPPING_MS);
+    }
+
     private void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
         TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG);
         t.traceBegin("timeoutUserSwitch-" + oldUserId + "-to-" + newUserId);
@@ -3908,6 +3933,10 @@
             return mPowerManagerInternal;
         }
 
+        AlarmManagerInternal getAlarmManagerInternal() {
+            return LocalServices.getService(AlarmManagerInternal.class);
+        }
+
         KeyguardManager getKeyguardManager() {
             return mService.mContext.getSystemService(KeyguardManager.class);
         }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
index 079b724..ec1993a 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
 import static android.content.Context.DEVICE_ID_DEFAULT;
+import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.INVALID_DISPLAY;
 
@@ -32,6 +33,8 @@
 import android.content.ServiceConnection;
 import android.content.pm.PackageManagerInternal;
 import android.inputmethodservice.InputMethodService;
+import android.inputmethodservice.InputMethodService.BackDispositionMode;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Process;
@@ -99,24 +102,16 @@
     /**
      * A set of status bits regarding the active IME.
      *
-     * <p>This value is a combination of following two bits:</p>
-     * <dl>
-     * <dt>{@link InputMethodService#IME_ACTIVE}</dt>
-     * <dd>
-     *   If this bit is ON, connected IME is ready to accept touch/key events.
-     * </dd>
-     * <dt>{@link InputMethodService#IME_VISIBLE}</dt>
-     * <dd>
-     *   If this bit is ON, some of IME view, e.g. software input, candidate view, is visible.
-     * </dd>
-     * </dl>
-     * <em>Do not update this value outside of {@link #setImeWindowStatus(IBinder, int, int)} and
-     * {@link InputMethodBindingController#unbindCurrentMethod()}.</em>
+     * <em>Do not update this value outside of {@link #setImeWindowVis} and
+     * {@link InputMethodBindingController#unbindCurrentMethod}.</em>
      */
-    @GuardedBy("ImfLock.class") private int mImeWindowVis;
-
+    @ImeWindowVisibility
     @GuardedBy("ImfLock.class")
-    private int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
+    private int mImeWindowVis;
+
+    @BackDispositionMode
+    @GuardedBy("ImfLock.class")
+    private int mBackDisposition = BACK_DISPOSITION_DEFAULT;
 
     @Nullable private CountDownLatch mLatchForTesting;
 
@@ -718,22 +713,24 @@
     }
 
     @GuardedBy("ImfLock.class")
-    void setImeWindowVis(int imeWindowVis) {
+    void setImeWindowVis(@ImeWindowVisibility int imeWindowVis) {
         mImeWindowVis = imeWindowVis;
     }
 
+    @ImeWindowVisibility
     @GuardedBy("ImfLock.class")
     int getImeWindowVis() {
         return mImeWindowVis;
     }
 
+    @BackDispositionMode
     @GuardedBy("ImfLock.class")
     int getBackDisposition() {
         return mBackDisposition;
     }
 
     @GuardedBy("ImfLock.class")
-    void setBackDisposition(int backDisposition) {
+    void setBackDisposition(@BackDispositionMode int backDisposition) {
         mBackDisposition = backDisposition;
     }
 }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 8afbd56..3654283 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -86,6 +86,8 @@
 import android.content.res.Resources;
 import android.hardware.input.InputManager;
 import android.inputmethodservice.InputMethodService;
+import android.inputmethodservice.InputMethodService.BackDispositionMode;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.media.AudioManagerInternal;
 import android.net.Uri;
 import android.os.Binder;
@@ -2618,7 +2620,8 @@
     }
 
     @GuardedBy("ImfLock.class")
-    private boolean shouldShowImeSwitcherLocked(int visibility, @UserIdInt int userId) {
+    private boolean shouldShowImeSwitcherLocked(@ImeWindowVisibility int visibility,
+            @UserIdInt int userId) {
         if (!mShowOngoingImeSwitcherForPhones) return false;
         // When the IME switcher dialog is shown, the IME switcher button should be hidden.
         // TODO(b/305849394): Make mMenuController multi-user aware.
@@ -2722,8 +2725,8 @@
     @BinderThread
     @GuardedBy("ImfLock.class")
     @SuppressWarnings("deprecation")
-    private void setImeWindowStatusLocked(int vis, int backDisposition,
-            @NonNull UserData userData) {
+    private void setImeWindowStatusLocked(@ImeWindowVisibility int vis,
+            @BackDispositionMode int backDisposition, @NonNull UserData userData) {
         final int topFocusedDisplayId = mWindowManagerInternal.getTopFocusedDisplayId();
 
         final int userId = userData.mUserId;
@@ -2772,7 +2775,7 @@
         final int userId = resolveImeUserIdFromDisplayIdLocked(displayId);
         if (disableImeIcon) {
             final var bindingController = getInputMethodBindingController(userId);
-            updateSystemUiLocked(0, bindingController.getBackDisposition(), userId);
+            updateSystemUiLocked(0 /* vis */, bindingController.getBackDisposition(), userId);
         } else {
             updateSystemUiLocked(userId);
         }
@@ -2787,7 +2790,8 @@
     }
 
     @GuardedBy("ImfLock.class")
-    private void updateSystemUiLocked(int vis, int backDisposition, @UserIdInt int userId) {
+    private void updateSystemUiLocked(@ImeWindowVisibility int vis,
+            @BackDispositionMode int backDisposition, @UserIdInt int userId) {
         // To minimize app compat risk, ignore background users' request for single-user mode.
         // TODO(b/357178609): generalize the logic and remove this special rule.
         if (!mConcurrentMultiUserModeEnabled && userId != mCurrentImeUserId) {
@@ -6812,7 +6816,8 @@
 
         @BinderThread
         @Override
-        public void setImeWindowStatusAsync(int vis, int backDisposition) {
+        public void setImeWindowStatusAsync(@ImeWindowVisibility int vis,
+                @BackDispositionMode int backDisposition) {
             synchronized (ImfLock.class) {
                 if (!calledWithValidTokenLocked(mToken, mUserData)) {
                     return;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
index c77b768..202543c 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -614,242 +614,61 @@
         }
     }
 
-    @VisibleForTesting
-    public static class ControllerImpl {
-
-        @NonNull
-        private final DynamicRotationList mSwitchingAwareRotationList;
-        @NonNull
-        private final StaticRotationList mSwitchingUnawareRotationList;
-        /** List of input methods and subtypes. */
-        @Nullable
-        private final RotationList mRotationList;
-        /** List of input methods and subtypes suitable for hardware keyboards. */
-        @Nullable
-        private final RotationList mHardwareRotationList;
-
-        /**
-         * Whether there was a user action since the last input method and subtype switch.
-         * Used to determine the switching behaviour for {@link #MODE_AUTO}.
-         */
-        private boolean mUserActionSinceSwitch;
-
-        @NonNull
-        public static ControllerImpl createFrom(@Nullable ControllerImpl currentInstance,
-                @NonNull List<ImeSubtypeListItem> sortedEnabledItems,
-                @NonNull List<ImeSubtypeListItem> hardwareKeyboardItems) {
-            final var switchingAwareImeSubtypes = filterImeSubtypeList(sortedEnabledItems,
-                    true /* supportsSwitchingToNextInputMethod */);
-            final var switchingUnawareImeSubtypes = filterImeSubtypeList(sortedEnabledItems,
-                    false /* supportsSwitchingToNextInputMethod */);
-
-            final DynamicRotationList switchingAwareRotationList;
-            if (currentInstance != null && Objects.equals(
-                    currentInstance.mSwitchingAwareRotationList.mImeSubtypeList,
-                    switchingAwareImeSubtypes)) {
-                // Can reuse the current instance.
-                switchingAwareRotationList = currentInstance.mSwitchingAwareRotationList;
-            } else {
-                switchingAwareRotationList = new DynamicRotationList(switchingAwareImeSubtypes);
-            }
-
-            final StaticRotationList switchingUnawareRotationList;
-            if (currentInstance != null && Objects.equals(
-                    currentInstance.mSwitchingUnawareRotationList.mImeSubtypeList,
-                    switchingUnawareImeSubtypes)) {
-                // Can reuse the current instance.
-                switchingUnawareRotationList = currentInstance.mSwitchingUnawareRotationList;
-            } else {
-                switchingUnawareRotationList = new StaticRotationList(switchingUnawareImeSubtypes);
-            }
-
-            final RotationList rotationList;
-            if (!Flags.imeSwitcherRevamp()) {
-                rotationList = null;
-            } else if (currentInstance != null && currentInstance.mRotationList != null
-                    && Objects.equals(
-                            currentInstance.mRotationList.mItems, sortedEnabledItems)) {
-                // Can reuse the current instance.
-                rotationList = currentInstance.mRotationList;
-            } else {
-                rotationList = new RotationList(sortedEnabledItems);
-            }
-
-            final RotationList hardwareRotationList;
-            if (!Flags.imeSwitcherRevamp()) {
-                hardwareRotationList = null;
-            } else if (currentInstance != null && currentInstance.mHardwareRotationList != null
-                    && Objects.equals(
-                            currentInstance.mHardwareRotationList.mItems, hardwareKeyboardItems)) {
-                // Can reuse the current instance.
-                hardwareRotationList = currentInstance.mHardwareRotationList;
-            } else {
-                hardwareRotationList = new RotationList(hardwareKeyboardItems);
-            }
-
-            return new ControllerImpl(switchingAwareRotationList, switchingUnawareRotationList,
-                    rotationList, hardwareRotationList);
-        }
-
-        private ControllerImpl(@NonNull DynamicRotationList switchingAwareRotationList,
-                @NonNull StaticRotationList switchingUnawareRotationList,
-                @Nullable RotationList rotationList,
-                @Nullable RotationList hardwareRotationList) {
-            mSwitchingAwareRotationList = switchingAwareRotationList;
-            mSwitchingUnawareRotationList = switchingUnawareRotationList;
-            mRotationList = rotationList;
-            mHardwareRotationList = hardwareRotationList;
-        }
-
-        @Nullable
-        public ImeSubtypeListItem getNextInputMethod(boolean onlyCurrentIme,
-                @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
-                @SwitchMode int mode, boolean forward) {
-            if (imi == null) {
-                return null;
-            }
-            if (Flags.imeSwitcherRevamp() && mRotationList != null) {
-                return mRotationList.next(imi, subtype, onlyCurrentIme,
-                        isRecency(mode, forward), forward);
-            } else if (imi.supportsSwitchingToNextInputMethod()) {
-                return mSwitchingAwareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi,
-                        subtype);
-            } else {
-                return mSwitchingUnawareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi,
-                        subtype);
-            }
-        }
-
-        @Nullable
-        public ImeSubtypeListItem getNextInputMethodForHardware(boolean onlyCurrentIme,
-                @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
-                @SwitchMode int mode, boolean forward) {
-            if (Flags.imeSwitcherRevamp() && mHardwareRotationList != null) {
-                return mHardwareRotationList.next(imi, subtype, onlyCurrentIme,
-                        isRecency(mode, forward), forward);
-            }
-            return null;
-        }
-
-        /**
-         * Called when the user took an action that should update the recency of the current
-         * input method and subtype in the switching list.
-         *
-         * @param imi     the currently selected input method.
-         * @param subtype the currently selected input method subtype, if any.
-         * @return {@code true} if the recency was updated, otherwise {@code false}.
-         * @see android.inputmethodservice.InputMethodServiceInternal#notifyUserActionIfNecessary()
-         */
-        public boolean onUserActionLocked(@NonNull InputMethodInfo imi,
-                @Nullable InputMethodSubtype subtype) {
-            boolean recencyUpdated = false;
-            if (Flags.imeSwitcherRevamp()) {
-                if (mRotationList != null) {
-                    recencyUpdated |= mRotationList.setMostRecent(imi, subtype);
-                }
-                if (mHardwareRotationList != null) {
-                    recencyUpdated |= mHardwareRotationList.setMostRecent(imi, subtype);
-                }
-                if (recencyUpdated) {
-                    mUserActionSinceSwitch = true;
-                }
-            } else if (imi.supportsSwitchingToNextInputMethod()) {
-                mSwitchingAwareRotationList.onUserAction(imi, subtype);
-            }
-            return recencyUpdated;
-        }
-
-        /** Called when the input method and subtype was changed. */
-        public void onInputMethodSubtypeChanged() {
-            mUserActionSinceSwitch = false;
-        }
-
-        /**
-         * Whether the given mode and direction result in recency or static order.
-         *
-         * <p>{@link #MODE_AUTO} resolves to the recency order for the first forwards switch
-         * after an {@link #onUserActionLocked user action}, and otherwise to the static order.</p>
-         *
-         * @param mode    the switching mode.
-         * @param forward the switching direction.
-         * @return {@code true} for the recency order, otherwise {@code false}.
-         */
-        private boolean isRecency(@SwitchMode int mode, boolean forward) {
-            if (mode == MODE_AUTO && mUserActionSinceSwitch && forward) {
-                return true;
-            } else {
-                return mode == MODE_RECENT;
-            }
-        }
-
-        @NonNull
-        private static List<ImeSubtypeListItem> filterImeSubtypeList(
-                @NonNull List<ImeSubtypeListItem> items,
-                boolean supportsSwitchingToNextInputMethod) {
-            final ArrayList<ImeSubtypeListItem> result = new ArrayList<>();
-            final int numItems = items.size();
-            for (int i = 0; i < numItems; i++) {
-                final ImeSubtypeListItem item = items.get(i);
-                if (item.mImi.supportsSwitchingToNextInputMethod()
-                        == supportsSwitchingToNextInputMethod) {
-                    result.add(item);
-                }
-            }
-            return result;
-        }
-
-        protected void dump(@NonNull Printer pw, @NonNull String prefix) {
-            pw.println(prefix + "mSwitchingAwareRotationList:");
-            mSwitchingAwareRotationList.dump(pw, prefix + "  ");
-            pw.println(prefix + "mSwitchingUnawareRotationList:");
-            mSwitchingUnawareRotationList.dump(pw, prefix + "  ");
-            if (Flags.imeSwitcherRevamp()) {
-                if (mRotationList != null) {
-                    pw.println(prefix + "mRotationList:");
-                    mRotationList.dump(pw, prefix + "  ");
-                }
-                if (mHardwareRotationList != null) {
-                    pw.println(prefix + "mHardwareRotationList:");
-                    mHardwareRotationList.dump(pw, prefix + "  ");
-                }
-                pw.println(prefix + "User action since last switch: " + mUserActionSinceSwitch);
-            }
-        }
-    }
-
     @NonNull
-    private ControllerImpl mController;
-
-    InputMethodSubtypeSwitchingController() {
-        mController = ControllerImpl.createFrom(null, Collections.emptyList(),
-                Collections.emptyList());
-    }
+    private DynamicRotationList mSwitchingAwareRotationList =
+            new DynamicRotationList(Collections.emptyList());
+    @NonNull
+    private StaticRotationList mSwitchingUnawareRotationList =
+            new StaticRotationList(Collections.emptyList());
+    /** List of input methods and subtypes. */
+    @NonNull
+    private RotationList mRotationList = new RotationList(Collections.emptyList());
+    /** List of input methods and subtypes suitable for hardware keyboards. */
+    @NonNull
+    private RotationList mHardwareRotationList = new RotationList(Collections.emptyList());
 
     /**
-     * Called when the user took an action that should update the recency of the current
-     * input method and subtype in the switching list.
-     *
-     * @param imi     the currently selected input method.
-     * @param subtype the currently selected input method subtype, if any.
-     * @see android.inputmethodservice.InputMethodServiceInternal#notifyUserActionIfNecessary()
+     * Whether there was a user action since the last input method and subtype switch.
+     * Used to determine the switching behaviour for {@link #MODE_AUTO}.
      */
-    public void onUserActionLocked(@NonNull InputMethodInfo imi,
-            @Nullable InputMethodSubtype subtype) {
-        mController.onUserActionLocked(imi, subtype);
-    }
+    private boolean mUserActionSinceSwitch;
 
-    /** Called when the input method and subtype was changed. */
-    public void onInputMethodSubtypeChanged() {
-        mController.onInputMethodSubtypeChanged();
-    }
+    /**
+     * Updates the list of input methods and subtypes used for switching. If the given items are
+     * equal to the existing ones (regardless of recency order), the update is skipped and the
+     * current recency order is kept. Otherwise, the recency order is reset.
+     *
+     * @param sortedEnabledItems    the sorted list of enabled input methods and subtypes.
+     * @param hardwareKeyboardItems the unsorted list of enabled input method and subtypes
+     *                              suitable for hardware keyboards.
+     */
+    @VisibleForTesting
+    void update(@NonNull List<ImeSubtypeListItem> sortedEnabledItems,
+            @NonNull List<ImeSubtypeListItem> hardwareKeyboardItems) {
+        final var switchingAwareImeSubtypes = filterImeSubtypeList(sortedEnabledItems,
+                true /* supportsSwitchingToNextInputMethod */);
+        final var switchingUnawareImeSubtypes = filterImeSubtypeList(sortedEnabledItems,
+                false /* supportsSwitchingToNextInputMethod */);
 
-    public void resetCircularListLocked(@NonNull Context context,
-            @NonNull InputMethodSettings settings) {
-        mController = ControllerImpl.createFrom(mController,
-                getSortedInputMethodAndSubtypeList(
-                        false /* includeAuxiliarySubtypes */, false /* isScreenLocked */,
-                        false /* forImeMenu */, context, settings),
-                getInputMethodAndSubtypeListForHardwareKeyboard(context, settings));
+        if (!Objects.equals(mSwitchingAwareRotationList.mImeSubtypeList,
+                switchingAwareImeSubtypes)) {
+            mSwitchingAwareRotationList = new DynamicRotationList(switchingAwareImeSubtypes);
+        }
+
+        if (!Objects.equals(mSwitchingUnawareRotationList.mImeSubtypeList,
+                switchingUnawareImeSubtypes)) {
+            mSwitchingUnawareRotationList = new StaticRotationList(switchingUnawareImeSubtypes);
+        }
+
+        if (Flags.imeSwitcherRevamp()
+                && !Objects.equals(mRotationList.mItems, sortedEnabledItems)) {
+            mRotationList = new RotationList(sortedEnabledItems);
+        }
+
+        if (Flags.imeSwitcherRevamp()
+                && !Objects.equals(mHardwareRotationList.mItems, hardwareKeyboardItems)) {
+            mHardwareRotationList = new RotationList(hardwareKeyboardItems);
+        }
     }
 
     /**
@@ -869,7 +688,19 @@
     public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme,
             @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
             @SwitchMode int mode, boolean forward) {
-        return mController.getNextInputMethod(onlyCurrentIme, imi, subtype, mode, forward);
+        if (imi == null) {
+            return null;
+        }
+        if (Flags.imeSwitcherRevamp()) {
+            return mRotationList.next(imi, subtype, onlyCurrentIme,
+                    isRecency(mode, forward), forward);
+        } else if (imi.supportsSwitchingToNextInputMethod()) {
+            return mSwitchingAwareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi,
+                    subtype);
+        } else {
+            return mSwitchingUnawareRotationList.getNextInputMethodLocked(onlyCurrentIme, imi,
+                    subtype);
+        }
     }
 
     /**
@@ -890,11 +721,98 @@
     public ImeSubtypeListItem getNextInputMethodForHardware(boolean onlyCurrentIme,
             @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype,
             @SwitchMode int mode, boolean forward) {
-        return mController.getNextInputMethodForHardware(onlyCurrentIme, imi, subtype, mode,
-                forward);
+        if (Flags.imeSwitcherRevamp()) {
+            return mHardwareRotationList.next(imi, subtype, onlyCurrentIme,
+                    isRecency(mode, forward), forward);
+        }
+        return null;
     }
 
-    public void dump(@NonNull Printer pw, @NonNull String prefix) {
-        mController.dump(pw, prefix);
+    /**
+     * Called when the user took an action that should update the recency of the current
+     * input method and subtype in the switching list.
+     *
+     * @param imi     the currently selected input method.
+     * @param subtype the currently selected input method subtype, if any.
+     * @return {@code true} if the recency was updated, otherwise {@code false}.
+     * @see android.inputmethodservice.InputMethodServiceInternal#notifyUserActionIfNecessary()
+     */
+    public boolean onUserActionLocked(@NonNull InputMethodInfo imi,
+            @Nullable InputMethodSubtype subtype) {
+        boolean recencyUpdated = false;
+        if (Flags.imeSwitcherRevamp()) {
+            recencyUpdated |= mRotationList.setMostRecent(imi, subtype);
+            recencyUpdated |= mHardwareRotationList.setMostRecent(imi, subtype);
+            if (recencyUpdated) {
+                mUserActionSinceSwitch = true;
+            }
+        } else if (imi.supportsSwitchingToNextInputMethod()) {
+            mSwitchingAwareRotationList.onUserAction(imi, subtype);
+        }
+        return recencyUpdated;
+    }
+
+    /** Called when the input method and subtype was changed. */
+    public void onInputMethodSubtypeChanged() {
+        mUserActionSinceSwitch = false;
+    }
+
+    /**
+     * Whether the given mode and direction result in recency or static order.
+     *
+     * <p>{@link #MODE_AUTO} resolves to the recency order for the first forwards switch
+     * after an {@link #onUserActionLocked user action}, and otherwise to the static order.</p>
+     *
+     * @param mode    the switching mode.
+     * @param forward the switching direction.
+     * @return {@code true} for the recency order, otherwise {@code false}.
+     */
+    private boolean isRecency(@SwitchMode int mode, boolean forward) {
+        if (mode == MODE_AUTO && mUserActionSinceSwitch && forward) {
+            return true;
+        } else {
+            return mode == MODE_RECENT;
+        }
+    }
+
+    @NonNull
+    private static List<ImeSubtypeListItem> filterImeSubtypeList(
+            @NonNull List<ImeSubtypeListItem> items,
+            boolean supportsSwitchingToNextInputMethod) {
+        final ArrayList<ImeSubtypeListItem> result = new ArrayList<>();
+        final int numItems = items.size();
+        for (int i = 0; i < numItems; i++) {
+            final ImeSubtypeListItem item = items.get(i);
+            if (item.mImi.supportsSwitchingToNextInputMethod()
+                    == supportsSwitchingToNextInputMethod) {
+                result.add(item);
+            }
+        }
+        return result;
+    }
+
+    void dump(@NonNull Printer pw, @NonNull String prefix) {
+        pw.println(prefix + "mSwitchingAwareRotationList:");
+        mSwitchingAwareRotationList.dump(pw, prefix + "  ");
+        pw.println(prefix + "mSwitchingUnawareRotationList:");
+        mSwitchingUnawareRotationList.dump(pw, prefix + "  ");
+        if (Flags.imeSwitcherRevamp()) {
+            pw.println(prefix + "mRotationList:");
+            mRotationList.dump(pw, prefix + "  ");
+            pw.println(prefix + "mHardwareRotationList:");
+            mHardwareRotationList.dump(pw, prefix + "  ");
+            pw.println(prefix + "User action since last switch: " + mUserActionSinceSwitch);
+        }
+    }
+
+    InputMethodSubtypeSwitchingController() {
+    }
+
+    public void resetCircularListLocked(@NonNull Context context,
+            @NonNull InputMethodSettings settings) {
+        update(getSortedInputMethodAndSubtypeList(
+                        false /* includeAuxiliarySubtypes */, false /* isScreenLocked */,
+                        false /* forImeMenu */, context, settings),
+                getInputMethodAndSubtypeListForHardwareKeyboard(context, settings));
     }
 }
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index b28da55b..1a2a196 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -360,7 +360,13 @@
             IWakeLockCallback callback, int newFlags, String newTag, String newPackageName,
             int newOwnerUid, int newOwnerPid, WorkSource newWorkSource, String newHistoryTag,
             IWakeLockCallback newCallback) {
-
+        // Todo(b/359154665): We do this because the newWorkSource can potentially be updated
+        // before the request is processed on the notifier thread. This would generally happen is
+        // the Worksource's set method is called, which as of this comment happens only in
+        // PowerManager#setWorksource and WifiManager#WifiLock#setWorksource. Both these places
+        // need to be updated and the WorkSource#set should be deprecated to avoid falling into
+        // such traps
+        newWorkSource = (newWorkSource == null) ? null : new WorkSource(newWorkSource);
         final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
         final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
         if (workSource != null && newWorkSource != null
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index a4a29a0..2faa68a 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -20,6 +20,8 @@
 import android.app.ITransientNotificationCallback;
 import android.content.ComponentName;
 import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback;
+import android.inputmethodservice.InputMethodService.BackDispositionMode;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.UserHandle;
@@ -54,13 +56,12 @@
      * Used by InputMethodManagerService to notify the IME status.
      *
      * @param displayId The display to which the IME is bound to.
-     * @param vis Bit flags about the IME visibility.
-     *            (e.g. {@link android.inputmethodservice.InputMethodService#IME_ACTIVE})
-     * @param backDisposition Bit flags about the IME back disposition.
-     *         (e.g. {@link android.inputmethodservice.InputMethodService#BACK_DISPOSITION_DEFAULT})
+     * @param vis The IME visibility.
+     * @param backDisposition The IME back disposition.
      * @param showImeSwitcher {@code true} when the IME switcher button should be shown.
      */
-    void setImeWindowStatus(int displayId, int vis, int backDisposition, boolean showImeSwitcher);
+    void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis,
+            @BackDispositionMode int backDisposition, boolean showImeSwitcher);
 
     /**
      * See {@link android.app.StatusBarManager#setIcon(String, int, int, String)}.
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index c3601b3c..e71f9ea 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -26,6 +26,7 @@
 import static android.app.StatusBarManager.NavBarMode;
 import static android.app.StatusBarManager.SessionFlags;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.ViewRootImpl.CLIENT_TRANSIENT;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
@@ -60,6 +61,8 @@
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
 import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback;
+import android.inputmethodservice.InputMethodService.BackDispositionMode;
+import android.inputmethodservice.InputMethodService.ImeWindowVisibility;
 import android.media.INearbyMediaDevicesProvider;
 import android.media.MediaRoute2Info;
 import android.net.Uri;
@@ -534,8 +537,8 @@
         }
 
         @Override
-        public void setImeWindowStatus(int displayId, int vis, int backDisposition,
-                boolean showImeSwitcher) {
+        public void setImeWindowStatus(int displayId, @ImeWindowVisibility int vis,
+                @BackDispositionMode int backDisposition, boolean showImeSwitcher) {
             StatusBarManagerService.this.setImeWindowStatus(displayId, vis, backDisposition,
                     showImeSwitcher);
         }
@@ -1351,8 +1354,8 @@
     }
 
     @Override
-    public void setImeWindowStatus(int displayId, final int vis, final int backDisposition,
-            final boolean showImeSwitcher) {
+    public void setImeWindowStatus(int displayId, @ImeWindowVisibility final int vis,
+            @BackDispositionMode final int backDisposition, final boolean showImeSwitcher) {
         enforceStatusBar();
 
         if (SPEW) {
@@ -1418,8 +1421,10 @@
         private String mPackageName = "none";
         private int mDisabled1 = 0;
         private int mDisabled2 = 0;
+        @ImeWindowVisibility
         private int mImeWindowVis = 0;
-        private int mImeBackDisposition = 0;
+        @BackDispositionMode
+        private int mImeBackDisposition = BACK_DISPOSITION_DEFAULT;
         private boolean mShowImeSwitcher = false;
         private LetterboxDetails[] mLetterboxDetails = new LetterboxDetails[0];
 
@@ -1462,7 +1467,8 @@
             return mDisabled1 == disabled1 && mDisabled2 == disabled2;
         }
 
-        private void setImeWindowState(final int vis, final int backDisposition,
+        private void setImeWindowState(@ImeWindowVisibility final int vis,
+                @BackDispositionMode final int backDisposition,
                 final boolean showImeSwitcher) {
             mImeWindowVis = vis;
             mImeBackDisposition = backDisposition;
diff --git a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
index 2755a80..9b142f28 100644
--- a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
+++ b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
@@ -109,10 +109,10 @@
     }
 
     @Override
-    public boolean onCameraOpened(@NonNull ActivityRecord cameraActivity,
+    public void onCameraOpened(@NonNull ActivityRecord cameraActivity,
             @NonNull String cameraId) {
         if (!isTreatmentEnabledForActivity(cameraActivity)) {
-            return false;
+            return;
         }
         final int existingCameraCompatMode = cameraActivity.mAppCompatController
                 .getAppCompatCameraOverrides()
@@ -124,11 +124,9 @@
             cameraActivity.mAppCompatController.getAppCompatCameraOverrides()
                     .setFreeformCameraCompatMode(newCameraCompatMode);
             forceUpdateActivityAndTask(cameraActivity);
-            return true;
         } else {
             mIsCameraCompatTreatmentPending = false;
         }
-        return false;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/CameraStateMonitor.java b/services/core/java/com/android/server/wm/CameraStateMonitor.java
index 068fc00..63c90ff 100644
--- a/services/core/java/com/android/server/wm/CameraStateMonitor.java
+++ b/services/core/java/com/android/server/wm/CameraStateMonitor.java
@@ -73,16 +73,6 @@
 
     private final ArrayList<CameraCompatStateListener> mCameraStateListeners = new ArrayList<>();
 
-    /**
-     * {@link CameraCompatStateListener} which returned {@code true} on the last {@link
-     * CameraCompatStateListener#onCameraOpened(ActivityRecord, String)}, if any.
-     *
-     * <p>This allows the {@link CameraStateMonitor} to notify a particular listener when camera
-     * closes, so they can revert any changes.
-     */
-    @Nullable
-    private CameraCompatStateListener mCurrentListenerForCameraActivity;
-
     private final CameraManager.AvailabilityCallback mAvailabilityCallback =
             new  CameraManager.AvailabilityCallback() {
                 @Override
@@ -167,12 +157,7 @@
             @NonNull String cameraId) {
         for (int i = 0; i < mCameraStateListeners.size(); i++) {
             CameraCompatStateListener listener = mCameraStateListeners.get(i);
-            boolean activeCameraTreatment = listener.onCameraOpened(
-                    cameraActivity, cameraId);
-            if (activeCameraTreatment) {
-                mCurrentListenerForCameraActivity = listener;
-                break;
-            }
+            listener.onCameraOpened(cameraActivity, cameraId);
         }
     }
 
@@ -226,19 +211,30 @@
                 return;
             }
 
-            if (mCurrentListenerForCameraActivity != null) {
-                boolean closeSuccessful =
-                        mCurrentListenerForCameraActivity.onCameraClosed(cameraId);
-                if (closeSuccessful) {
-                    mCameraIdPackageBiMapping.removeCameraId(cameraId);
-                    mCurrentListenerForCameraActivity = null;
-                } else {
-                    rescheduleRemoveCameraActivity(cameraId);
-                }
+            final boolean closeSuccessfulForAllListeners = notifyListenersCameraClosed(cameraId);
+            if (closeSuccessfulForAllListeners) {
+                // Finish cleaning up.
+                mCameraIdPackageBiMapping.removeCameraId(cameraId);
+            } else {
+                // Not ready to process closure yet - the camera activity might be refreshing.
+                // Try again later.
+                rescheduleRemoveCameraActivity(cameraId);
             }
         }
     }
 
+    /**
+     * @return {@code false} if any listeners have reported issues processing the close.
+     */
+    private boolean notifyListenersCameraClosed(@NonNull String cameraId) {
+        boolean closeSuccessfulForAllListeners = true;
+        for (int i = 0; i < mCameraStateListeners.size(); i++) {
+            closeSuccessfulForAllListeners &= mCameraStateListeners.get(i).onCameraClosed(cameraId);
+        }
+
+        return closeSuccessfulForAllListeners;
+    }
+
     // TODO(b/335165310): verify that this works in multi instance and permission dialogs.
     /**
      * Finds a visible activity with the given package name.
@@ -286,11 +282,9 @@
     interface CameraCompatStateListener {
         /**
          * Notifies the compat listener that an activity has opened camera.
-         *
-         * @return true if the treatment has been applied.
          */
         // TODO(b/336474959): try to decouple `cameraId` from the listeners.
-        boolean onCameraOpened(@NonNull ActivityRecord cameraActivity, @NonNull String cameraId);
+        void onCameraOpened(@NonNull ActivityRecord cameraActivity, @NonNull String cameraId);
         /**
          * Notifies the compat listener that camera is closed.
          *
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index e50a089..762180b 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -298,7 +298,7 @@
     }
 
     @Override
-    public boolean onCameraOpened(@NonNull ActivityRecord cameraActivity,
+    public void onCameraOpened(@NonNull ActivityRecord cameraActivity,
             @NonNull String cameraId) {
         mCameraTask = cameraActivity.getTask();
         // Checking whether an activity in fullscreen rather than the task as this camera
@@ -306,7 +306,7 @@
         if (cameraActivity.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
             recomputeConfigurationForCameraCompatIfNeeded(cameraActivity);
             mDisplayContent.updateOrientation();
-            return true;
+            return;
         }
         // Checking that the whole app is in multi-window mode as we shouldn't show toast
         // for the activity embedding case.
@@ -320,7 +320,6 @@
                         (String) packageManager.getApplicationLabel(
                                 packageManager.getApplicationInfo(cameraActivity.packageName,
                                         /* flags */ 0)));
-                return true;
             } catch (PackageManager.NameNotFoundException e) {
                 ProtoLog.e(WM_DEBUG_ORIENTATION,
                         "DisplayRotationCompatPolicy: Multi-window toast not shown as "
@@ -328,7 +327,6 @@
                         cameraActivity.packageName);
             }
         }
-        return false;
     }
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/WindowAnimationSpec.java b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
index 34b9913..2c58c61 100644
--- a/services/core/java/com/android/server/wm/WindowAnimationSpec.java
+++ b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
@@ -97,10 +97,10 @@
 
     /**
      * @return If a window animation has outsets applied to it.
-     * @see Animation#hasExtension()
+     * @see Animation#getExtensionEdges()
      */
     public boolean hasExtension() {
-        return mAnimation.hasExtension();
+        return mAnimation.getExtensionEdges() != 0;
     }
 
     @Override
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index f1e94de..a5085fc 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -211,7 +211,6 @@
         "android.system.suspend-V1-ndk",
         "server_configurable_flags",
         "service.incremental",
-        "android.companion.virtualdevice.flags-aconfig-cc",
     ],
 
     static_libs: [
diff --git a/services/core/jni/com_android_server_companion_virtual_InputController.cpp b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
index 9ec5ae5..6f72760 100644
--- a/services/core/jni/com_android_server_companion_virtual_InputController.cpp
+++ b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
@@ -19,273 +19,22 @@
 #include <android-base/unique_fd.h>
 #include <android/input.h>
 #include <android/keycodes.h>
-#include <android_companion_virtualdevice_flags.h>
-#include <errno.h>
-#include <fcntl.h>
 #include <input/Input.h>
 #include <input/VirtualInputDevice.h>
-#include <linux/uinput.h>
-#include <math.h>
 #include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedUtfChars.h>
-#include <utils/Log.h>
 
-#include <map>
-#include <set>
 #include <string>
 
 using android::base::unique_fd;
 
 namespace android {
 
-namespace vd_flags = android::companion::virtualdevice::flags;
-
 static constexpr jlong INVALID_PTR = 0;
 
-enum class DeviceType {
-    KEYBOARD,
-    MOUSE,
-    TOUCHSCREEN,
-    DPAD,
-    STYLUS,
-    ROTARY_ENCODER,
-};
-
-static unique_fd invalidFd() {
-    return unique_fd(-1);
-}
-
-/** Creates a new uinput device and assigns a file descriptor. */
-static unique_fd openUinput(const char* readableName, jint vendorId, jint productId,
-                            const char* phys, DeviceType deviceType, jint screenHeight,
-                            jint screenWidth) {
-    unique_fd fd(TEMP_FAILURE_RETRY(::open("/dev/uinput", O_WRONLY | O_NONBLOCK)));
-    if (fd < 0) {
-        ALOGE("Error creating uinput device: %s", strerror(errno));
-        return invalidFd();
-    }
-
-    ioctl(fd, UI_SET_PHYS, phys);
-
-    ioctl(fd, UI_SET_EVBIT, EV_KEY);
-    ioctl(fd, UI_SET_EVBIT, EV_SYN);
-    switch (deviceType) {
-        case DeviceType::DPAD:
-            for (const auto& [_, keyCode] : VirtualDpad::DPAD_KEY_CODE_MAPPING) {
-                ioctl(fd, UI_SET_KEYBIT, keyCode);
-            }
-            break;
-        case DeviceType::KEYBOARD:
-            for (const auto& [_, keyCode] : VirtualKeyboard::KEY_CODE_MAPPING) {
-                ioctl(fd, UI_SET_KEYBIT, keyCode);
-            }
-            break;
-        case DeviceType::MOUSE:
-            ioctl(fd, UI_SET_EVBIT, EV_REL);
-            ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
-            ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT);
-            ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE);
-            ioctl(fd, UI_SET_KEYBIT, BTN_BACK);
-            ioctl(fd, UI_SET_KEYBIT, BTN_FORWARD);
-            ioctl(fd, UI_SET_RELBIT, REL_X);
-            ioctl(fd, UI_SET_RELBIT, REL_Y);
-            ioctl(fd, UI_SET_RELBIT, REL_WHEEL);
-            ioctl(fd, UI_SET_RELBIT, REL_HWHEEL);
-            if (vd_flags::high_resolution_scroll()) {
-                ioctl(fd, UI_SET_RELBIT, REL_WHEEL_HI_RES);
-                ioctl(fd, UI_SET_RELBIT, REL_HWHEEL_HI_RES);
-            }
-            break;
-        case DeviceType::TOUCHSCREEN:
-            ioctl(fd, UI_SET_EVBIT, EV_ABS);
-            ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH);
-            ioctl(fd, UI_SET_ABSBIT, ABS_MT_SLOT);
-            ioctl(fd, UI_SET_ABSBIT, ABS_MT_POSITION_X);
-            ioctl(fd, UI_SET_ABSBIT, ABS_MT_POSITION_Y);
-            ioctl(fd, UI_SET_ABSBIT, ABS_MT_TRACKING_ID);
-            ioctl(fd, UI_SET_ABSBIT, ABS_MT_TOOL_TYPE);
-            ioctl(fd, UI_SET_ABSBIT, ABS_MT_TOUCH_MAJOR);
-            ioctl(fd, UI_SET_ABSBIT, ABS_MT_PRESSURE);
-            ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT);
-            break;
-        case DeviceType::STYLUS:
-            ioctl(fd, UI_SET_EVBIT, EV_ABS);
-            ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH);
-            ioctl(fd, UI_SET_KEYBIT, BTN_STYLUS);
-            ioctl(fd, UI_SET_KEYBIT, BTN_STYLUS2);
-            ioctl(fd, UI_SET_KEYBIT, BTN_TOOL_PEN);
-            ioctl(fd, UI_SET_KEYBIT, BTN_TOOL_RUBBER);
-            ioctl(fd, UI_SET_ABSBIT, ABS_X);
-            ioctl(fd, UI_SET_ABSBIT, ABS_Y);
-            ioctl(fd, UI_SET_ABSBIT, ABS_TILT_X);
-            ioctl(fd, UI_SET_ABSBIT, ABS_TILT_Y);
-            ioctl(fd, UI_SET_ABSBIT, ABS_PRESSURE);
-            ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT);
-            break;
-        case DeviceType::ROTARY_ENCODER:
-            ioctl(fd, UI_SET_EVBIT, EV_REL);
-            ioctl(fd, UI_SET_RELBIT, REL_WHEEL);
-            if (vd_flags::high_resolution_scroll()) {
-                ioctl(fd, UI_SET_RELBIT, REL_WHEEL_HI_RES);
-            }
-            break;
-        default:
-            ALOGE("Invalid input device type %d", static_cast<int32_t>(deviceType));
-            return invalidFd();
-    }
-
-    int version;
-    if (ioctl(fd, UI_GET_VERSION, &version) == 0 && version >= 5) {
-        uinput_setup setup;
-        memset(&setup, 0, sizeof(setup));
-        strlcpy(setup.name, readableName, UINPUT_MAX_NAME_SIZE);
-        setup.id.version = 1;
-        setup.id.bustype = BUS_VIRTUAL;
-        setup.id.vendor = vendorId;
-        setup.id.product = productId;
-        if (deviceType == DeviceType::TOUCHSCREEN) {
-            uinput_abs_setup xAbsSetup;
-            xAbsSetup.code = ABS_MT_POSITION_X;
-            xAbsSetup.absinfo.maximum = screenWidth - 1;
-            xAbsSetup.absinfo.minimum = 0;
-            if (ioctl(fd, UI_ABS_SETUP, &xAbsSetup) != 0) {
-                ALOGE("Error creating touchscreen uinput x axis: %s", strerror(errno));
-                return invalidFd();
-            }
-            uinput_abs_setup yAbsSetup;
-            yAbsSetup.code = ABS_MT_POSITION_Y;
-            yAbsSetup.absinfo.maximum = screenHeight - 1;
-            yAbsSetup.absinfo.minimum = 0;
-            if (ioctl(fd, UI_ABS_SETUP, &yAbsSetup) != 0) {
-                ALOGE("Error creating touchscreen uinput y axis: %s", strerror(errno));
-                return invalidFd();
-            }
-            uinput_abs_setup majorAbsSetup;
-            majorAbsSetup.code = ABS_MT_TOUCH_MAJOR;
-            majorAbsSetup.absinfo.maximum = screenWidth - 1;
-            majorAbsSetup.absinfo.minimum = 0;
-            if (ioctl(fd, UI_ABS_SETUP, &majorAbsSetup) != 0) {
-                ALOGE("Error creating touchscreen uinput major axis: %s", strerror(errno));
-                return invalidFd();
-            }
-            uinput_abs_setup pressureAbsSetup;
-            pressureAbsSetup.code = ABS_MT_PRESSURE;
-            pressureAbsSetup.absinfo.maximum = 255;
-            pressureAbsSetup.absinfo.minimum = 0;
-            if (ioctl(fd, UI_ABS_SETUP, &pressureAbsSetup) != 0) {
-                ALOGE("Error creating touchscreen uinput pressure axis: %s", strerror(errno));
-                return invalidFd();
-            }
-            uinput_abs_setup slotAbsSetup;
-            slotAbsSetup.code = ABS_MT_SLOT;
-            slotAbsSetup.absinfo.maximum = MAX_POINTERS - 1;
-            slotAbsSetup.absinfo.minimum = 0;
-            if (ioctl(fd, UI_ABS_SETUP, &slotAbsSetup) != 0) {
-                ALOGE("Error creating touchscreen uinput slots: %s", strerror(errno));
-                return invalidFd();
-            }
-            uinput_abs_setup trackingIdAbsSetup;
-            trackingIdAbsSetup.code = ABS_MT_TRACKING_ID;
-            trackingIdAbsSetup.absinfo.maximum = MAX_POINTERS - 1;
-            trackingIdAbsSetup.absinfo.minimum = 0;
-            if (ioctl(fd, UI_ABS_SETUP, &trackingIdAbsSetup) != 0) {
-                ALOGE("Error creating touchscreen uinput tracking ids: %s", strerror(errno));
-                return invalidFd();
-            }
-        } else if (deviceType == DeviceType::STYLUS) {
-            uinput_abs_setup xAbsSetup;
-            xAbsSetup.code = ABS_X;
-            xAbsSetup.absinfo.maximum = screenWidth - 1;
-            xAbsSetup.absinfo.minimum = 0;
-            if (ioctl(fd, UI_ABS_SETUP, &xAbsSetup) != 0) {
-                ALOGE("Error creating stylus uinput x axis: %s", strerror(errno));
-                return invalidFd();
-            }
-            uinput_abs_setup yAbsSetup;
-            yAbsSetup.code = ABS_Y;
-            yAbsSetup.absinfo.maximum = screenHeight - 1;
-            yAbsSetup.absinfo.minimum = 0;
-            if (ioctl(fd, UI_ABS_SETUP, &yAbsSetup) != 0) {
-                ALOGE("Error creating stylus uinput y axis: %s", strerror(errno));
-                return invalidFd();
-            }
-            uinput_abs_setup tiltXAbsSetup;
-            tiltXAbsSetup.code = ABS_TILT_X;
-            tiltXAbsSetup.absinfo.maximum = 90;
-            tiltXAbsSetup.absinfo.minimum = -90;
-            if (ioctl(fd, UI_ABS_SETUP, &tiltXAbsSetup) != 0) {
-                ALOGE("Error creating stylus uinput tilt x axis: %s", strerror(errno));
-                return invalidFd();
-            }
-            uinput_abs_setup tiltYAbsSetup;
-            tiltYAbsSetup.code = ABS_TILT_Y;
-            tiltYAbsSetup.absinfo.maximum = 90;
-            tiltYAbsSetup.absinfo.minimum = -90;
-            if (ioctl(fd, UI_ABS_SETUP, &tiltYAbsSetup) != 0) {
-                ALOGE("Error creating stylus uinput tilt y axis: %s", strerror(errno));
-                return invalidFd();
-            }
-            uinput_abs_setup pressureAbsSetup;
-            pressureAbsSetup.code = ABS_PRESSURE;
-            pressureAbsSetup.absinfo.maximum = 255;
-            pressureAbsSetup.absinfo.minimum = 0;
-            if (ioctl(fd, UI_ABS_SETUP, &pressureAbsSetup) != 0) {
-                ALOGE("Error creating touchscreen uinput pressure axis: %s", strerror(errno));
-                return invalidFd();
-            }
-        }
-        if (ioctl(fd, UI_DEV_SETUP, &setup) != 0) {
-            ALOGE("Error creating uinput device: %s", strerror(errno));
-            return invalidFd();
-        }
-    } else {
-        // UI_DEV_SETUP was not introduced until version 5. Try setting up manually.
-        ALOGI("Falling back to version %d manual setup", version);
-        uinput_user_dev fallback;
-        memset(&fallback, 0, sizeof(fallback));
-        strlcpy(fallback.name, readableName, UINPUT_MAX_NAME_SIZE);
-        fallback.id.version = 1;
-        fallback.id.bustype = BUS_VIRTUAL;
-        fallback.id.vendor = vendorId;
-        fallback.id.product = productId;
-        if (deviceType == DeviceType::TOUCHSCREEN) {
-            fallback.absmin[ABS_MT_POSITION_X] = 0;
-            fallback.absmax[ABS_MT_POSITION_X] = screenWidth - 1;
-            fallback.absmin[ABS_MT_POSITION_Y] = 0;
-            fallback.absmax[ABS_MT_POSITION_Y] = screenHeight - 1;
-            fallback.absmin[ABS_MT_TOUCH_MAJOR] = 0;
-            fallback.absmax[ABS_MT_TOUCH_MAJOR] = screenWidth - 1;
-            fallback.absmin[ABS_MT_PRESSURE] = 0;
-            fallback.absmax[ABS_MT_PRESSURE] = 255;
-        } else if (deviceType == DeviceType::STYLUS) {
-            fallback.absmin[ABS_X] = 0;
-            fallback.absmax[ABS_X] = screenWidth - 1;
-            fallback.absmin[ABS_Y] = 0;
-            fallback.absmax[ABS_Y] = screenHeight - 1;
-            fallback.absmin[ABS_TILT_X] = -90;
-            fallback.absmax[ABS_TILT_X] = 90;
-            fallback.absmin[ABS_TILT_Y] = -90;
-            fallback.absmax[ABS_TILT_Y] = 90;
-            fallback.absmin[ABS_PRESSURE] = 0;
-            fallback.absmax[ABS_PRESSURE] = 255;
-        }
-        if (TEMP_FAILURE_RETRY(write(fd, &fallback, sizeof(fallback))) != sizeof(fallback)) {
-            ALOGE("Error creating uinput device: %s", strerror(errno));
-            return invalidFd();
-        }
-    }
-
-    if (ioctl(fd, UI_DEV_CREATE) != 0) {
-        ALOGE("Error creating uinput device: %s", strerror(errno));
-        return invalidFd();
-    }
-
-    return fd;
-}
-
 static unique_fd openUinputJni(JNIEnv* env, jstring name, jint vendorId, jint productId,
-                               jstring phys, DeviceType deviceType, int screenHeight,
-                               int screenWidth) {
+                               jstring phys, DeviceType deviceType, jint screenHeight,
+                               jint screenWidth) {
     ScopedUtfChars readableName(env, name);
     ScopedUtfChars readablePhys(env, phys);
     return openUinput(readableName.c_str(), vendorId, productId, readablePhys.c_str(), deviceType,
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 622c36c..09c54cb 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import static android.app.appfunctions.flags.Flags.enableAppFunctionManager;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
@@ -120,6 +121,7 @@
 import com.android.server.ambientcontext.AmbientContextManagerService;
 import com.android.server.app.GameManagerService;
 import com.android.server.appbinding.AppBindingService;
+import com.android.server.appfunctions.AppFunctionManagerService;
 import com.android.server.apphibernation.AppHibernationService;
 import com.android.server.appop.AppOpMigrationHelper;
 import com.android.server.appop.AppOpMigrationHelperImpl;
@@ -1727,6 +1729,12 @@
             mSystemServiceManager.startService(LogcatManagerService.class);
             t.traceEnd();
 
+            t.traceBegin("StartAppFunctionManager");
+            if (enableAppFunctionManager()) {
+                mSystemServiceManager.startService(AppFunctionManagerService.class);
+            }
+            t.traceEnd();
+
         } catch (Throwable e) {
             Slog.e("System", "******************************************");
             Slog.e("System", "************ Failure starting core service");
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
index a27ad9a..770451c 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
@@ -44,7 +44,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ControllerImpl;
 import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
 
 import org.junit.Rule;
@@ -178,19 +177,20 @@
         return items;
     }
 
-    private void assertNextInputMethod(@NonNull ControllerImpl controller, boolean onlyCurrentIme,
-            @NonNull ImeSubtypeListItem currentItem, @Nullable ImeSubtypeListItem nextItem) {
+    private void assertNextInputMethod(@NonNull InputMethodSubtypeSwitchingController controller,
+            boolean onlyCurrentIme, @NonNull ImeSubtypeListItem currentItem,
+            @Nullable ImeSubtypeListItem nextItem) {
         InputMethodSubtype subtype = null;
         if (currentItem.mSubtypeName != null) {
             subtype = createTestSubtype(currentItem.mSubtypeName.toString());
         }
-        final ImeSubtypeListItem nextIme = controller.getNextInputMethod(onlyCurrentIme,
+        final ImeSubtypeListItem nextIme = controller.getNextInputMethodLocked(onlyCurrentIme,
                 currentItem.mImi, subtype, MODE_STATIC, true /* forward */);
         assertEquals(nextItem, nextIme);
     }
 
-    private void assertRotationOrder(@NonNull ControllerImpl controller, boolean onlyCurrentIme,
-            ImeSubtypeListItem... expectedRotationOrderOfImeSubtypeList) {
+    private void assertRotationOrder(@NonNull InputMethodSubtypeSwitchingController controller,
+            boolean onlyCurrentIme, ImeSubtypeListItem... expectedRotationOrderOfImeSubtypeList) {
         final int numItems = expectedRotationOrderOfImeSubtypeList.length;
         for (int i = 0; i < numItems; i++) {
             final int nextIndex = (i + 1) % numItems;
@@ -200,7 +200,7 @@
         }
     }
 
-    private boolean onUserAction(@NonNull ControllerImpl controller,
+    private boolean onUserAction(@NonNull InputMethodSubtypeSwitchingController controller,
             @NonNull ImeSubtypeListItem subtypeListItem) {
         InputMethodSubtype subtype = null;
         if (subtypeListItem.mSubtypeName != null) {
@@ -228,8 +228,8 @@
         final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(6);
         final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(7);
 
-        final ControllerImpl controller = ControllerImpl.createFrom(
-                null /* currentInstance */, enabledItems, new ArrayList<>());
+        final var controller = new InputMethodSubtypeSwitchingController();
+        controller.update(enabledItems, new ArrayList<>());
 
         // switching-aware loop
         assertRotationOrder(controller, false /* onlyCurrentIme */,
@@ -286,8 +286,8 @@
         final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(6);
         final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(7);
 
-        final ControllerImpl controller = ControllerImpl.createFrom(
-                null /* currentInstance */, enabledItems, new ArrayList<>());
+        final var controller = new InputMethodSubtypeSwitchingController();
+        controller.update(enabledItems, new ArrayList<>());
 
         // === switching-aware loop ===
         assertRotationOrder(controller, false /* onlyCurrentIme */,
@@ -336,11 +336,10 @@
 
         // Rotation order should be preserved when created with the same subtype list.
         final List<ImeSubtypeListItem> sameEnabledItems = createEnabledImeSubtypes();
-        final ControllerImpl newController = ControllerImpl.createFrom(controller,
-                sameEnabledItems, new ArrayList<>());
-        assertRotationOrder(newController, false /* onlyCurrentIme */,
+        controller.update(sameEnabledItems, new ArrayList<>());
+        assertRotationOrder(controller, false /* onlyCurrentIme */,
                 subtypeAwareIme, latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
-        assertRotationOrder(newController, false /* onlyCurrentIme */,
+        assertRotationOrder(controller, false /* onlyCurrentIme */,
                 switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
                 switchUnawareJapaneseIme_ja_jp);
 
@@ -348,11 +347,10 @@
         final List<ImeSubtypeListItem> differentEnabledItems = List.of(
                 latinIme_en_us, latinIme_fr, subtypeAwareIme, switchingUnawareLatinIme_en_uk,
                 switchUnawareJapaneseIme_ja_jp, subtypeUnawareIme);
-        final ControllerImpl anotherController = ControllerImpl.createFrom(controller,
-                differentEnabledItems, new ArrayList<>());
-        assertRotationOrder(anotherController, false /* onlyCurrentIme */,
+        controller.update(differentEnabledItems, new ArrayList<>());
+        assertRotationOrder(controller, false /* onlyCurrentIme */,
                 latinIme_en_us, latinIme_fr, subtypeAwareIme);
-        assertRotationOrder(anotherController, false /* onlyCurrentIme */,
+        assertRotationOrder(controller, false /* onlyCurrentIme */,
                 switchingUnawareLatinIme_en_uk, switchUnawareJapaneseIme_ja_jp, subtypeUnawareIme);
     }
 
@@ -520,8 +518,8 @@
         final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian);
         final var hardwareSimpleIme = List.of(hardwareSimple);
 
-        final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
-                hardwareItems);
+        final var controller = new InputMethodSubtypeSwitchingController();
+        controller.update(items, hardwareItems);
 
         final int mode = MODE_STATIC;
 
@@ -583,8 +581,8 @@
         final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian);
         final var hardwareSimpleIme = List.of(hardwareSimple);
 
-        final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
-                hardwareItems);
+        final var controller = new InputMethodSubtypeSwitchingController();
+        controller.update(items, hardwareItems);
 
         final int mode = MODE_RECENT;
 
@@ -666,8 +664,8 @@
         final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian);
         final var hardwareSimpleIme = List.of(hardwareSimple);
 
-        final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
-                hardwareItems);
+        final var controller = new InputMethodSubtypeSwitchingController();
+        controller.update(items, hardwareItems);
 
         final int mode = MODE_AUTO;
 
@@ -777,92 +775,73 @@
         final var hardwareLatinIme = List.of(hardwareEnglish, hardwareFrench, hardwareItalian);
         final var hardwareSimpleIme = List.of(hardwareSimple);
 
-        final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
-                hardwareItems);
+        final var controller = new InputMethodSubtypeSwitchingController();
+        controller.update(items, hardwareItems);
 
         final int mode = MODE_RECENT;
 
         // Recency order is initialized to static order.
         assertNextOrder(controller, false /* forHardware */, mode,
                 items, List.of(latinIme, simpleIme));
-
         assertNextOrder(controller, true /* forHardware */, mode,
                 hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
 
         // User action on french IME.
         assertTrue("Recency updated for french IME", onUserAction(controller, french));
 
-        final var equalItems = new ArrayList<>(items);
-        final var otherItems = new ArrayList<>(items);
-        otherItems.remove(simple);
-
-        final var equalController = ControllerImpl.createFrom(controller, equalItems,
-                hardwareItems);
-        final var otherController = ControllerImpl.createFrom(controller, otherItems,
-                hardwareItems);
-
         final var recencyItems = List.of(french, english, italian, simple);
         final var recencyLatinIme = List.of(french, english, italian);
         final var recencySimpleIme = List.of(simple);
 
+        final var equalItems = new ArrayList<>(items);
+        controller.update(equalItems, hardwareItems);
+
+        // The order of non-hardware items remains unchanged when updated with equal items.
         assertNextOrder(controller, false /* forHardware */, mode,
                 recencyItems, List.of(recencyLatinIme, recencySimpleIme));
-
-        // The order of equal non-hardware items is unchanged.
-        assertNextOrder(equalController, false /* forHardware */, mode,
-                recencyItems, List.of(recencyLatinIme, recencySimpleIme));
-
-        // The order of other hardware items is reset.
-        assertNextOrder(otherController, false /* forHardware */, mode,
-                latinIme, List.of(latinIme));
-
-        // The order of hardware remains unchanged.
+        // The order of hardware items remains unchanged when only non-hardware items are updated.
         assertNextOrder(controller, true /* forHardware */, mode,
                 hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
 
-        assertNextOrder(equalController, true /* forHardware */, mode,
-                hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
+        final var otherItems = new ArrayList<>(items);
+        otherItems.remove(simple);
+        controller.update(otherItems, hardwareItems);
 
-        assertNextOrder(otherController, true /* forHardware */, mode,
+        // The order of non-hardware items is reset when updated with other items.
+        assertNextOrder(controller, false /* forHardware */, mode,
+                latinIme, List.of(latinIme));
+        // The order of hardware items remains unchanged when only non-hardware items are updated.
+        assertNextOrder(controller, true /* forHardware */, mode,
                 hardwareItems, List.of(hardwareLatinIme, hardwareSimpleIme));
 
         assertTrue("Recency updated for french hardware IME",
                 onUserAction(controller, hardwareFrench));
 
-        final var equalHardwareItems = new ArrayList<>(hardwareItems);
-        final var otherHardwareItems = new ArrayList<>(hardwareItems);
-        otherHardwareItems.remove(hardwareSimple);
-
-        final var equalHardwareController = ControllerImpl.createFrom(controller, items,
-                equalHardwareItems);
-        final var otherHardwareController = ControllerImpl.createFrom(controller, items,
-                otherHardwareItems);
-
         final var recencyHardwareItems =
                 List.of(hardwareFrench, hardwareEnglish, hardwareItalian, hardwareSimple);
         final var recencyHardwareLatinIme =
                 List.of(hardwareFrench, hardwareEnglish, hardwareItalian);
         final var recencyHardwareSimpleIme = List.of(hardwareSimple);
 
-        // The order of non-hardware items remains unchanged.
+        final var equalHardwareItems = new ArrayList<>(hardwareItems);
+        controller.update(otherItems, equalHardwareItems);
+
+        // The order of non-hardware items remains unchanged when only hardware items are updated.
         assertNextOrder(controller, false /* forHardware */, mode,
-                recencyItems, List.of(recencyLatinIme, recencySimpleIme));
-
-        assertNextOrder(equalHardwareController, false /* forHardware */, mode,
-                recencyItems, List.of(recencyLatinIme, recencySimpleIme));
-
-        assertNextOrder(otherHardwareController, false /* forHardware */, mode,
-                recencyItems, List.of(recencyLatinIme, recencySimpleIme));
-
+                latinIme, List.of(latinIme));
+        // The order of hardware items remains unchanged when updated with equal items.
         assertNextOrder(controller, true /* forHardware */, mode,
                 recencyHardwareItems, List.of(recencyHardwareLatinIme, recencyHardwareSimpleIme));
 
-        // The order of equal hardware items is unchanged.
-        assertNextOrder(equalHardwareController, true /* forHardware */, mode,
-                recencyHardwareItems, List.of(recencyHardwareLatinIme, recencyHardwareSimpleIme));
+        final var otherHardwareItems = new ArrayList<>(hardwareItems);
+        otherHardwareItems.remove(hardwareSimple);
+        controller.update(otherItems, otherHardwareItems);
 
-        // The order of other hardware items is reset.
-        assertNextOrder(otherHardwareController, true /* forHardware */, mode,
+        // The order of non-hardware items remains unchanged when only hardware items are updated.
+        assertNextOrder(controller, false /* forHardware */, mode,
+                latinIme, List.of(latinIme));
+        // The order of hardware items is reset when updated with other items.
+        assertNextOrder(controller, true /* forHardware */, mode,
                 hardwareLatinIme, List.of(hardwareLatinIme));
     }
 
@@ -882,8 +861,8 @@
         addTestImeSubtypeListItems(hardwareItems, "hardwareSwitchUnaware", "hardwareSwitchUnaware",
                 null, false /* supportsSwitchingToNextInputMethod*/);
 
-        final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
-                hardwareItems);
+        final var controller = new InputMethodSubtypeSwitchingController();
+        controller.update(items, hardwareItems);
 
         for (int mode = MODE_STATIC; mode <= MODE_AUTO; mode++) {
             assertNextOrder(controller, false /* forHardware */, false /* onlyCurrentIme */,
@@ -910,8 +889,7 @@
         addTestImeSubtypeListItems(hardwareItems, "HardwareIme", "HardwareIme",
                 List.of("en", "fr"), true /* supportsSwitchingToNextInputMethod */);
 
-        final var controller = ControllerImpl.createFrom(null /* currentInstance */, List.of(),
-                List.of());
+        final var controller = new InputMethodSubtypeSwitchingController();
 
         assertNextItemNoAction(controller, false /* forHardware */, items,
                 null /* expectedNext */);
@@ -940,8 +918,8 @@
         addTestImeSubtypeListItems(unknownHardwareItems, "HardwareUnknownIme", "HardwareUnknownIme",
                 List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */);
 
-        final var controller = ControllerImpl.createFrom(null /* currentInstance */,
-                items, hardwareItems);
+        final var controller = new InputMethodSubtypeSwitchingController();
+        controller.update(items, hardwareItems);
 
         assertNextItemNoAction(controller, false /* forHardware */, items,
                 null /* expectedNext */);
@@ -979,8 +957,8 @@
         addTestImeSubtypeListItems(unknownHardwareItems, "HardwareUnknownIme", "HardwareUnknownIme",
                 List.of("en", "fr", "it"), true /* supportsSwitchingToNextInputMethod */);
 
-        final var controller = ControllerImpl.createFrom(null /* currentInstance */, items,
-                hardwareItems);
+        final var controller = new InputMethodSubtypeSwitchingController();
+        controller.update(items, hardwareItems);
 
         assertTrue("Recency updated for french IME", onUserAction(controller, french));
 
@@ -1118,8 +1096,9 @@
      * @param allItems    the list of items across all IMEs.
      * @param perImeItems the list of lists of items per IME.
      */
-    private static void assertNextOrder(@NonNull ControllerImpl controller, boolean forHardware,
-            @SwitchMode int mode, boolean forward, @NonNull List<ImeSubtypeListItem> allItems,
+    private static void assertNextOrder(@NonNull InputMethodSubtypeSwitchingController controller,
+            boolean forHardware, @SwitchMode int mode, boolean forward,
+            @NonNull List<ImeSubtypeListItem> allItems,
             @NonNull List<List<ImeSubtypeListItem>> perImeItems) {
         assertNextOrder(controller, forHardware, false /* onlyCurrentIme */, mode,
                 forward, allItems);
@@ -1142,8 +1121,8 @@
      * @param allItems    the list of items across all IMEs.
      * @param perImeItems the list of lists of items per IME.
      */
-    private static void assertNextOrder(@NonNull ControllerImpl controller, boolean forHardware,
-            @SwitchMode int mode, @NonNull List<ImeSubtypeListItem> allItems,
+    private static void assertNextOrder(@NonNull InputMethodSubtypeSwitchingController controller,
+            boolean forHardware, @SwitchMode int mode, @NonNull List<ImeSubtypeListItem> allItems,
             @NonNull List<List<ImeSubtypeListItem>> perImeItems) {
         assertNextOrder(controller, forHardware, false /* onlyCurrentIme */, mode,
                 true /* forward */, allItems);
@@ -1170,7 +1149,7 @@
      * @param forward        whether to search forwards or backwards in the list.
      * @param items          the list of items to verify, in the expected order.
      */
-    private static void assertNextOrder(@NonNull ControllerImpl controller,
+    private static void assertNextOrder(@NonNull InputMethodSubtypeSwitchingController controller,
             boolean forHardware, boolean onlyCurrentIme, @SwitchMode int mode, boolean forward,
             @NonNull List<ImeSubtypeListItem> items) {
         final int numItems = items.size();
@@ -1214,7 +1193,7 @@
      * @param item           the item to find the next value from.
      * @param expectedNext   the expected next value.
      */
-    private static void assertNextItem(@NonNull ControllerImpl controller,
+    private static void assertNextItem(@NonNull InputMethodSubtypeSwitchingController controller,
             boolean forHardware, boolean onlyCurrentIme, @SwitchMode int mode, boolean forward,
             @NonNull ImeSubtypeListItem item, @Nullable ImeSubtypeListItem expectedNext) {
         final var nextItem = getNextItem(controller, forHardware, onlyCurrentIme, mode, forward,
@@ -1234,15 +1213,16 @@
      * @return the next item found, otherwise {@code null}.
      */
     @Nullable
-    private static ImeSubtypeListItem getNextItem(@NonNull ControllerImpl controller,
-            boolean forHardware, boolean onlyCurrentIme, @SwitchMode int mode, boolean forward,
+    private static ImeSubtypeListItem getNextItem(
+            @NonNull InputMethodSubtypeSwitchingController controller, boolean forHardware,
+            boolean onlyCurrentIme, @SwitchMode int mode, boolean forward,
             @NonNull ImeSubtypeListItem item) {
         final var subtype = item.mSubtypeName != null
                 ? createTestSubtype(item.mSubtypeName.toString()) : null;
         return forHardware
                 ? controller.getNextInputMethodForHardware(
                         onlyCurrentIme, item.mImi, subtype, mode, forward)
-                : controller.getNextInputMethod(
+                : controller.getNextInputMethodLocked(
                         onlyCurrentIme, item.mImi, subtype, mode, forward);
     }
 
@@ -1255,8 +1235,9 @@
      * @param items        the list of items to verify.
      * @param expectedNext the expected next item.
      */
-    private void assertNextItemNoAction(@NonNull ControllerImpl controller, boolean forHardware,
-            @NonNull List<ImeSubtypeListItem> items, @Nullable ImeSubtypeListItem expectedNext) {
+    private void assertNextItemNoAction(@NonNull InputMethodSubtypeSwitchingController controller,
+            boolean forHardware, @NonNull List<ImeSubtypeListItem> items,
+            @Nullable ImeSubtypeListItem expectedNext) {
         for (var item : items) {
             for (int mode = MODE_STATIC; mode <= MODE_AUTO; mode++) {
                 assertNextItem(controller, forHardware, false /* onlyCurrentIme */, mode,
diff --git a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
index d45e312..fc4d8d8 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
@@ -61,7 +61,6 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.util.concurrent.Executor;
@@ -264,8 +263,8 @@
                 BatteryStats.WAKE_TYPE_PARTIAL, false);
 
         verifyNoMoreInteractions(mWakeLockLog, mBatteryStats);
-        WorkSource worksourceOld = Mockito.mock(WorkSource.class);
-        WorkSource worksourceNew = Mockito.mock(WorkSource.class);
+        WorkSource worksourceOld = new WorkSource(/*uid=*/ 1);
+        WorkSource worksourceNew = new WorkSource(/*uid=*/ 2);
 
         mNotifier.onWakeLockChanging(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
                 "my.package.name", uid, pid, worksourceOld, /* historyTag= */ null,
@@ -309,6 +308,40 @@
         verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, -1);
     }
 
+    @Test
+    public void
+            test_notifierProcessesWorkSourceDeepCopy_OnWakelockChanging() throws RemoteException {
+        when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true);
+        createNotifier();
+        clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager);
+        IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() {
+            @Override public void onStateChanged(boolean enabled) throws RemoteException {
+                throw new RemoteException("Just testing");
+            }
+        };
+
+        final int uid = 1234;
+        final int pid = 5678;
+        mTestLooper.dispatchAll();
+        WorkSource worksourceOld = new WorkSource(/*uid=*/ 1);
+        WorkSource worksourceNew =  new WorkSource(/*uid=*/ 2);
+
+        mNotifier.onWakeLockChanging(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, worksourceOld, /* historyTag= */ null,
+                exceptingCallback,
+                PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, worksourceNew, /* newHistoryTag= */ null,
+                exceptingCallback);
+        // The newWorksource is modified before notifier could process it.
+        worksourceNew.set(/*uid=*/ 3);
+
+        mTestLooper.dispatchAll();
+        verify(mBatteryStats).noteChangeWakelockFromSource(worksourceOld, pid,
+                "wakelockTag", null, BatteryStats.WAKE_TYPE_PARTIAL,
+                new WorkSource(/*uid=*/ 2), pid, "wakelockTag", null,
+                BatteryStats.WAKE_TYPE_FULL, false);
+    }
+
 
     @Test
     public void testOnWakeLockListener_FullWakeLock_ProcessesOnHandler() throws RemoteException {
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index a8e350b..1db46bf 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -105,6 +105,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.server.AlarmManagerInternal;
 import com.android.server.FgThread;
 import com.android.server.SystemService;
 import com.android.server.am.UserState.KeyEvictedCallback;
@@ -124,6 +125,7 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -730,6 +732,39 @@
                 mUserController.getRunningUsersLU());
     }
 
+    /** Test scheduling stopping of background users - reschedule if user with a scheduled alarm. */
+    @Test
+    public void testScheduleStopOfBackgroundUser_rescheduleIfAlarm() throws Exception {
+        mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_SCHEDULE_STOP_OF_BACKGROUND_USER);
+
+        mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
+                /* maxRunningUsers= */ 10, /* delayUserDataLocking= */ false,
+                /* backgroundUserScheduledStopTimeSecs= */ 2);
+
+        setUpAndStartUserInBackground(TEST_USER_ID);
+        assertEquals(newHashSet(SYSTEM_USER_ID, TEST_USER_ID),
+                new HashSet<>(mUserController.getRunningUsersLU()));
+
+        // Initially, the background user has an alarm that will fire soon. So don't stop the user.
+        when(mInjector.mAlarmManagerInternal.getNextAlarmTriggerTimeForUser(eq(TEST_USER_ID)))
+                .thenReturn(System.currentTimeMillis() + Duration.ofMinutes(2).toMillis());
+        assertAndProcessScheduledStopBackgroundUser(true, TEST_USER_ID);
+        assertEquals(newHashSet(SYSTEM_USER_ID, TEST_USER_ID),
+                new HashSet<>(mUserController.getRunningUsersLU()));
+
+        // Now, that alarm is gone and the next alarm isn't for a long time. Do stop the user.
+        when(mInjector.mAlarmManagerInternal.getNextAlarmTriggerTimeForUser(eq(TEST_USER_ID)))
+                .thenReturn(System.currentTimeMillis() + Duration.ofDays(1).toMillis());
+        assertAndProcessScheduledStopBackgroundUser(true, TEST_USER_ID);
+        assertEquals(newHashSet(SYSTEM_USER_ID),
+                new HashSet<>(mUserController.getRunningUsersLU()));
+
+        // No-one is scheduled to stop anymore.
+        assertAndProcessScheduledStopBackgroundUser(false, null);
+        verify(mInjector.mAlarmManagerInternal, never())
+                .getNextAlarmTriggerTimeForUser(eq(SYSTEM_USER_ID));
+    }
+
     /**
      * Process queued SCHEDULED_STOP_BACKGROUND_USER_MSG message, if expected.
      * @param userId the user we are checking to see whether it is scheduled.
@@ -1747,6 +1782,7 @@
         private final WindowManagerService mWindowManagerMock;
         private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
         private final PowerManagerInternal mPowerManagerInternal;
+        private final AlarmManagerInternal mAlarmManagerInternal;
         private final KeyguardManager mKeyguardManagerMock;
         private final LockPatternUtils mLockPatternUtilsMock;
 
@@ -1769,6 +1805,7 @@
             mActivityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
             mStorageManagerMock = mock(IStorageManager.class);
             mPowerManagerInternal = mock(PowerManagerInternal.class);
+            mAlarmManagerInternal = mock(AlarmManagerInternal.class);
             mKeyguardManagerMock = mock(KeyguardManager.class);
             when(mKeyguardManagerMock.isDeviceSecure(anyInt())).thenReturn(true);
             mLockPatternUtilsMock = mock(LockPatternUtils.class);
@@ -1839,6 +1876,11 @@
         }
 
         @Override
+        AlarmManagerInternal getAlarmManagerInternal() {
+            return mAlarmManagerInternal;
+        }
+
+        @Override
         KeyguardManager getKeyguardManager() {
             return mKeyguardManagerMock;
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java b/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java
index 12f5714f..d223272 100644
--- a/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/CameraStateMonitorTests.java
@@ -43,10 +43,10 @@
 import java.util.concurrent.Executor;
 
 /**
- * Tests for {@link DisplayRotationCompatPolicy}.
+ * Tests for {@link CameraStateMonitor}.
  *
  * Build/Install/Run:
- *  atest WmTests:DisplayRotationCompatPolicyTests
+ *  atest WmTests:CameraStateMonitorTests
  */
 @SmallTest
 @Presubmit
@@ -68,23 +68,14 @@
     private ActivityRecord mActivity;
     private Task mTask;
 
-    // Simulates a listener which will not react to the change on a particular activity.
-    private final FakeCameraCompatStateListener mNotInterestedListener =
-            new FakeCameraCompatStateListener(
-                    /*onCameraOpenedReturnValue=*/ false,
-                    /*simulateUnsuccessfulCloseOnce=*/ false);
     // Simulates a listener which will react to the change on a particular activity - for example
     // put the activity in a camera compat mode.
-    private final FakeCameraCompatStateListener mInterestedListener =
-            new FakeCameraCompatStateListener(
-                    /*onCameraOpenedReturnValue=*/ true,
-                    /*simulateUnsuccessfulCloseOnce=*/ false);
+    private final FakeCameraCompatStateListener mListener =
+            new FakeCameraCompatStateListener(/* simulateUnsuccessfulCloseOnce= */ false);
     // Simulates a listener which for some reason cannot process `onCameraClosed` event once it
     // first arrives - this means that the update needs to be postponed.
     private final FakeCameraCompatStateListener mListenerCannotClose =
-            new FakeCameraCompatStateListener(
-                    /*onCameraOpenedReturnValue=*/ true,
-                    /*simulateUnsuccessfulCloseOnce=*/ true);
+            new FakeCameraCompatStateListener(/* simulateUnsuccessfulCloseOnce= */ true);
 
     @Before
     public void setUp() throws Exception {
@@ -129,44 +120,31 @@
     @After
     public void tearDown() {
         // Remove all listeners.
-        mCameraStateMonitor.removeCameraStateListener(mNotInterestedListener);
-        mCameraStateMonitor.removeCameraStateListener(mInterestedListener);
+        mCameraStateMonitor.removeCameraStateListener(mListener);
         mCameraStateMonitor.removeCameraStateListener(mListenerCannotClose);
 
         // Reset the listener's state.
-        mNotInterestedListener.resetCounters();
-        mInterestedListener.resetCounters();
+        mListener.resetCounters();
         mListenerCannotClose.resetCounters();
     }
 
     @Test
     public void testOnCameraOpened_listenerAdded_notifiesCameraOpened() {
-        mCameraStateMonitor.addCameraStateListener(mNotInterestedListener);
+        mCameraStateMonitor.addCameraStateListener(mListener);
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
-        assertEquals(1, mNotInterestedListener.mOnCameraOpenedCounter);
+        assertEquals(1, mListener.mOnCameraOpenedCounter);
     }
 
     @Test
-    public void testOnCameraOpened_listenerReturnsFalse_doesNotNotifyCameraClosed() {
-        mCameraStateMonitor.addCameraStateListener(mNotInterestedListener);
-        // Listener returns false on `onCameraOpened`.
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
-
-        mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
-
-        assertEquals(0, mNotInterestedListener.mOnCameraClosedCounter);
-    }
-
-    @Test
-    public void testOnCameraOpened_listenerReturnsTrue_notifyCameraClosed() {
-        mCameraStateMonitor.addCameraStateListener(mInterestedListener);
+    public void testOnCameraOpened_cameraClosed_notifyCameraClosed() {
+        mCameraStateMonitor.addCameraStateListener(mListener);
         // Listener returns true on `onCameraOpened`.
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
 
         mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
 
-        assertEquals(1, mInterestedListener.mOnCameraClosedCounter);
+        assertEquals(1, mListener.mOnCameraClosedCounter);
     }
 
     @Test
@@ -182,32 +160,22 @@
 
     @Test
     public void testReconnectedToDifferentCamera_notifiesListener() {
-        mCameraStateMonitor.addCameraStateListener(mInterestedListener);
+        mCameraStateMonitor.addCameraStateListener(mListener);
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_2, TEST_PACKAGE_1);
 
-        assertEquals(2, mInterestedListener.mOnCameraOpenedCounter);
+        assertEquals(2, mListener.mOnCameraOpenedCounter);
     }
 
     @Test
     public void testDifferentAppConnectedToCamera_notifiesListener() {
-        mCameraStateMonitor.addCameraStateListener(mInterestedListener);
+        mCameraStateMonitor.addCameraStateListener(mListener);
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_2);
 
-        assertEquals(2, mInterestedListener.mOnCameraOpenedCounter);
-    }
-
-    @Test
-    public void testCameraAlreadyClosed_notifiesListenerOnce() {
-        mCameraStateMonitor.addCameraStateListener(mInterestedListener);
-        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
-        mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
-        mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1);
-
-        assertEquals(1, mInterestedListener.mOnCameraClosedCounter);
+        assertEquals(2, mListener.mOnCameraOpenedCounter);
     }
 
     private void configureActivity(@NonNull String packageName) {
@@ -232,7 +200,6 @@
         int mOnCameraOpenedCounter = 0;
         int mOnCameraClosedCounter = 0;
 
-        boolean mOnCameraOpenedReturnValue = true;
         private boolean mOnCameraClosedReturnValue = true;
 
         /**
@@ -242,17 +209,14 @@
          *                                      subsequent calls. This fake implementation tests the
          *                                      retry mechanism in {@link CameraStateMonitor}.
          */
-        FakeCameraCompatStateListener(boolean onCameraOpenedReturnValue,
-                boolean simulateUnsuccessfulCloseOnce) {
-            mOnCameraOpenedReturnValue = onCameraOpenedReturnValue;
+        FakeCameraCompatStateListener(boolean simulateUnsuccessfulCloseOnce) {
             mOnCameraClosedReturnValue = !simulateUnsuccessfulCloseOnce;
         }
 
         @Override
-        public boolean onCameraOpened(@NonNull ActivityRecord cameraActivity,
+        public void onCameraOpened(@NonNull ActivityRecord cameraActivity,
                 @NonNull String cameraId) {
             mOnCameraOpenedCounter++;
-            return mOnCameraOpenedReturnValue;
         }
 
         @Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
index 771e290..e57e36d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
@@ -59,6 +59,7 @@
 
         TestWindowContainer(WindowManagerService wm) {
             super(wm);
+            setVisibleRequested(true);
         }
 
         @Override
diff --git a/tests/FlickerTests/ActivityEmbedding/Android.bp b/tests/FlickerTests/ActivityEmbedding/Android.bp
index e09fbf6..c681ce9 100644
--- a/tests/FlickerTests/ActivityEmbedding/Android.bp
+++ b/tests/FlickerTests/ActivityEmbedding/Android.bp
@@ -24,6 +24,9 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Begin to cleanup after CL merges
+
 filegroup {
     name: "FlickerTestsOtherCommon-src",
     srcs: ["src/**/ActivityEmbeddingTestBase.kt"],
@@ -82,3 +85,123 @@
         ":FlickerTestsOtherCommon-src",
     ],
 }
+
+// End to cleanup after CL merges
+////////////////////////////////////////////////////////////////////////////////
+
+android_test {
+    name: "FlickerTestsActivityEmbedding",
+    defaults: ["FlickerTestsDefault"],
+    manifest: "AndroidManifest.xml",
+    package_name: "com.android.server.wm.flicker",
+    instrumentation_target_package: "com.android.server.wm.flicker",
+    test_config_template: "AndroidTestTemplate.xml",
+    srcs: ["src/**/*"],
+    static_libs: [
+        "FlickerTestsBase",
+        "FlickerTestsOtherCommon",
+    ],
+    data: ["trace_config/*"],
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Begin breakdowns for FlickerTestsActivityEmbedding module
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-CatchAll",
+    base: "FlickerTestsActivityEmbedding",
+    exclude_filters: [
+        "com.android.server.wm.flicker.activityembedding.close.CloseSecondaryActivityInSplitTest",
+        "com.android.server.wm.flicker.activityembedding.layoutchange.HorizontalSplitChangeRatioTest",
+        "com.android.server.wm.flicker.activityembedding.open.MainActivityStartsSecondaryWithAlwaysExpandTest",
+        "com.android.server.wm.flicker.activityembedding.open.OpenActivityEmbeddingPlaceholderSplitTest",
+        "com.android.server.wm.flicker.activityembedding.open.OpenActivityEmbeddingSecondaryToSplitTest",
+        "com.android.server.wm.flicker.activityembedding.open.OpenThirdActivityOverSplitTest",
+        "com.android.server.wm.flicker.activityembedding.open.OpenTrampolineActivityTest",
+        "com.android.server.wm.flicker.activityembedding.pip.SecondaryActivityEnterPipTest",
+        "com.android.server.wm.flicker.activityembedding.rotation.RotateSplitNoChangeTest",
+        "com.android.server.wm.flicker.activityembedding.rtl.RTLStartSecondaryWithPlaceholderTest",
+        "com.android.server.wm.flicker.activityembedding.splitscreen.EnterSystemSplitTest",
+    ],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-Close-CloseSecondaryActivityInSplitTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.close.CloseSecondaryActivityInSplitTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-LayoutChange-HorizontalSplitChangeRatioTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.layoutchange.HorizontalSplitChangeRatioTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-Open-MainActivityStartsSecondaryWithAlwaysExpandTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.open.MainActivityStartsSecondaryWithAlwaysExpandTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-Open-OpenActivityEmbeddingPlaceholderSplitTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.open.OpenActivityEmbeddingPlaceholderSplitTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-Open-OpenActivityEmbeddingSecondaryToSplitTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.open.OpenActivityEmbeddingSecondaryToSplitTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-Open-OpenThirdActivityOverSplitTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.open.OpenThirdActivityOverSplitTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-Open-OpenTrampolineActivityTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.open.OpenTrampolineActivityTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-Pip-SecondaryActivityEnterPipTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.pip.SecondaryActivityEnterPipTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-Rotation-RotateSplitNoChangeTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.rotation.RotateSplitNoChangeTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-Rtl-RTLStartSecondaryWithPlaceholderTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.rtl.RTLStartSecondaryWithPlaceholderTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsActivityEmbedding-SplitScreen-EnterSystemSplitTest",
+    base: "FlickerTestsActivityEmbedding",
+    include_filters: ["com.android.server.wm.flicker.activityembedding.splitscreen.EnterSystemSplitTest"],
+    test_suites: ["device-tests"],
+}
+
+// End breakdowns for FlickerTestsActivityEmbedding module
+////////////////////////////////////////////////////////////////////////////////
diff --git a/tests/FlickerTests/AppLaunch/Android.bp b/tests/FlickerTests/AppLaunch/Android.bp
index 72a9065..b61739f 100644
--- a/tests/FlickerTests/AppLaunch/Android.bp
+++ b/tests/FlickerTests/AppLaunch/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_windowing_animations_transitions",
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
     // all of the 'license_kinds' from "frameworks_base_license"
@@ -23,6 +24,9 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Begin to cleanup after CL merges
+
 filegroup {
     name: "FlickerTestsAppLaunchCommon-src",
     srcs: ["src/**/common/*"],
@@ -69,3 +73,122 @@
     ],
     data: ["trace_config/*"],
 }
+
+// End to cleanup after CL merges
+////////////////////////////////////////////////////////////////////////////////
+
+android_test {
+    name: "FlickerTestsAppLaunch",
+    defaults: ["FlickerTestsDefault"],
+    manifest: "AndroidManifest.xml",
+    test_config_template: "AndroidTestTemplate.xml",
+    srcs: ["src/**/*"],
+    static_libs: [
+        "FlickerTestsBase",
+        "FlickerTestsAppLaunchCommon",
+    ],
+    data: ["trace_config/*"],
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Begin breakdowns for FlickerTestsAppLaunch module
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-CatchAll",
+    base: "FlickerTestsAppLaunch",
+    exclude_filters: [
+        "com.android.server.wm.flicker.launch.TaskTransitionTest",
+        "com.android.server.wm.flicker.launch.ActivityTransitionTest",
+        "com.android.server.wm.flicker.launch.OpenAppFromIconColdTest",
+        "com.android.server.wm.flicker.launch.OpenAppFromIntentColdAfterCameraTest",
+        "com.android.server.wm.flicker.launch.OpenAppFromIntentColdTest",
+        "com.android.server.wm.flicker.launch.OpenAppFromIntentWarmTest",
+        "com.android.server.wm.flicker.launch.OpenAppFromLockscreenViaIntentTest",
+        "com.android.server.wm.flicker.launch.OpenAppFromOverviewTest",
+        "com.android.server.wm.flicker.launch.OpenCameraFromHomeOnDoubleClickPowerButtonTest",
+        "com.android.server.wm.flicker.launch.OpenTransferSplashscreenAppFromLauncherTransition",
+        "com.android.server.wm.flicker.launch.OverrideTaskTransitionTest",
+        "com.android.server.wm.flicker.launch.TaskTransitionTest",
+    ],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-ActivityTransitionTest",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.ActivityTransitionTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-OpenAppFromIconColdTest",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromIconColdTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-OpenAppFromIntentColdAfterCameraTest",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromIntentColdAfterCameraTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-OpenAppFromIntentColdTest",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromIntentColdTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-OpenAppFromIntentWarmTest",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromIntentWarmTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-OpenAppFromLockscreenViaIntentTest",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromLockscreenViaIntentTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-OpenAppFromOverviewTest",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.OpenAppFromOverviewTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-OpenCameraFromHomeOnDoubleClickPowerButtonTest",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.OpenCameraFromHomeOnDoubleClickPowerButtonTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-OpenTransferSplashscreenAppFromLauncherTransition",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.OpenTransferSplashscreenAppFromLauncherTransition"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-OverrideTaskTransitionTest",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.OverrideTaskTransitionTest"],
+    test_suites: ["device-tests"],
+}
+
+test_module_config {
+    name: "FlickerTestsAppLaunch-TaskTransitionTest",
+    base: "FlickerTestsAppLaunch",
+    include_filters: ["com.android.server.wm.flicker.launch.TaskTransitionTest"],
+    test_suites: ["device-tests"],
+}
+
+// End breakdowns for FlickerTestsAppLaunch module
+////////////////////////////////////////////////////////////////////////////////
diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
index fad94d4..7d0c596 100644
--- a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
@@ -126,30 +126,35 @@
                                 .setMessage("My Test Debug Log Message %b")
                                 .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_DEBUG)
                                 .setGroupId(1)
+                                .setLocation("com/test/MyTestClass.java:123")
                 ).addMessages(
                         Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
                                 .setMessageId(2)
                                 .setMessage("My Test Verbose Log Message %b")
                                 .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_VERBOSE)
                                 .setGroupId(1)
+                                .setLocation("com/test/MyTestClass.java:342")
                 ).addMessages(
                         Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
                                 .setMessageId(3)
                                 .setMessage("My Test Warn Log Message %b")
                                 .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_WARN)
                                 .setGroupId(1)
+                                .setLocation("com/test/MyTestClass.java:563")
                 ).addMessages(
                         Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
                                 .setMessageId(4)
                                 .setMessage("My Test Error Log Message %b")
                                 .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_ERROR)
                                 .setGroupId(1)
+                                .setLocation("com/test/MyTestClass.java:156")
                 ).addMessages(
                         Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
                                 .setMessageId(5)
                                 .setMessage("My Test WTF Log Message %b")
                                 .setLevel(ProtologCommon.ProtoLogLevel.PROTOLOG_LEVEL_WTF)
                                 .setGroupId(1)
+                                .setLocation("com/test/MyTestClass.java:192")
                 );
 
         ViewerConfigInputStreamProvider viewerConfigInputStreamProvider = Mockito.mock(
@@ -465,6 +470,26 @@
                 .isEqualTo("My test message :: test, 2, 4, 6, 0.400000, true");
     }
 
+    @Test
+    public  void supportsLocationInformation() throws IOException {
+        PerfettoTraceMonitor traceMonitor =
+                PerfettoTraceMonitor.newBuilder().enableProtoLog(true).build();
+        try {
+            traceMonitor.start();
+            mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
+                    LogDataType.BOOLEAN, new Object[]{true});
+        } finally {
+            traceMonitor.stop(mWriter);
+        }
+
+        final ResultReader reader = new ResultReader(mWriter.write(), mTraceConfig);
+        final ProtoLogTrace protolog = reader.readProtoLogTrace();
+
+        Truth.assertThat(protolog.messages).hasSize(1);
+        Truth.assertThat(protolog.messages.get(0).getLocation())
+                .isEqualTo("com/test/MyTestClass.java:123");
+    }
+
     private long addMessageToConfig(ProtologCommon.ProtoLogLevel logLevel, String message) {
         final long messageId = new Random().nextLong();
         mViewerConfigBuilder.addMessages(Protolog.ProtoLogViewerConfig.MessageData.newBuilder()