Merge "Added UserManagerInternal.getDisplayAssignedToUser(userId)."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 1d92778..9a4323a 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -25,6 +25,6 @@
 
 hidden_api_txt_exclude_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/exclude.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
 
-ktfmt_hook = ${REPO_ROOT}/external/ktfmt/ktfmt.py --check -i ${REPO_ROOT}/frameworks/base/ktfmt_includes.txt ${PREUPLOAD_FILES}
+ktfmt_hook = ${REPO_ROOT}/external/ktfmt/ktfmt.py --check -i ${REPO_ROOT}/frameworks/base/packages/SystemUI/ktfmt_includes.txt ${PREUPLOAD_FILES}
 
 ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py -f ${PREUPLOAD_FILES}
diff --git a/apct-tests/perftests/surfaceflinger/AndroidTest.xml b/apct-tests/perftests/surfaceflinger/AndroidTest.xml
index 0f3a068..53e5d99 100644
--- a/apct-tests/perftests/surfaceflinger/AndroidTest.xml
+++ b/apct-tests/perftests/surfaceflinger/AndroidTest.xml
@@ -44,7 +44,7 @@
         <option name="hidden-api-checks" value="false"/>
 
         <!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
-        <option name="device-listeners" value="android.device.collectors.PerfettoListener,android.device.collectors.SimpleperfListener" />
+        <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener,android.device.collectors.SimpleperfListener" />
 
         <!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
         <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
@@ -58,7 +58,15 @@
         <option name="instrumentation-arg" key="arguments" value="&quot;&quot;" />
         <option name="instrumentation-arg" key="events_to_record" value="instructions,cpu-cycles,raw-l3d-cache-refill,sched:sched_waking" />
         <option name="instrumentation-arg" key="processes_to_record" value="surfaceflinger" />
-        <option name="instrumentation-arg" key="symbols_to_report" value="&quot;android::SurfaceFlinger::commit(long, long, long)&quot;" />
+        <option name="instrumentation-arg" key="symbols_to_report" value="&quot;android::SurfaceFlinger::commit(;android::SurfaceFlinger::composite(&quot;" />
+
+        <!-- ProcLoadListener related arguments -->
+        <!-- Wait for device last minute threshold to reach 3 with 2 minute timeout before starting the test run -->
+        <option name="instrumentation-arg" key="procload-collector:per_run" value="true" />
+        <option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
+        <option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
+        <option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
+
     </test>
 
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
index f4d0c05..45d164c 100644
--- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
+++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java
@@ -16,6 +16,7 @@
 
 package android.surfaceflinger;
 
+import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
@@ -23,14 +24,19 @@
 
 import androidx.test.ext.junit.rules.ActivityScenarioRule;
 import androidx.test.filters.LargeTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
+import java.util.Random;
+
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class SurfaceFlingerPerfTest {
@@ -48,19 +54,175 @@
     public void setup() {
         mActivityRule.getScenario().onActivity(activity -> mActivity = activity);
     }
+
+    @After
+    public void teardown() {
+        mSurfaceControls.forEach(SurfaceControl::release);
+        mByfferTrackers.forEach(BufferFlinger::freeBuffers);
+    }
+
+
+    private ArrayList<BufferFlinger> mByfferTrackers = new ArrayList<>();
+    private BufferFlinger createBufferTracker(int color) {
+        BufferFlinger bufferTracker = new BufferFlinger(BUFFER_COUNT, color);
+        mByfferTrackers.add(bufferTracker);
+        return bufferTracker;
+    }
+
+    private ArrayList<SurfaceControl> mSurfaceControls = new ArrayList<>();
+    private SurfaceControl createSurfaceControl() throws InterruptedException {
+        SurfaceControl sc = mActivity.createChildSurfaceControl();
+        mSurfaceControls.add(sc);
+        return sc;
+    }
+
     @Test
-    public void submitSingleBuffer() throws Exception {
-        SurfaceControl sc = mActivity.getChildSurfaceControl();
+    public void singleBuffer() throws Exception {
+        SurfaceControl sc = createSurfaceControl();
+        BufferFlinger bufferTracker = createBufferTracker(Color.GREEN);
         SurfaceControl.Transaction t = new SurfaceControl.Transaction();
-        BufferFlinger bufferflinger = new BufferFlinger(BUFFER_COUNT, Color.GREEN);
-        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        bufferTracker.addBuffer(t, sc);
         t.show(sc);
 
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
-            bufferflinger.addBuffer(t, sc);
+            bufferTracker.addBuffer(t, sc);
             t.apply();
         }
-        bufferflinger.freeBuffers();
     }
-}
 
+    static int getRandomColorComponent() {
+        return new Random().nextInt(155) + 100;
+    }
+
+    @Test
+    public void multipleBuffers() throws Exception {
+        final int MAX_BUFFERS = 10;
+
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        for (int i = 0; i < MAX_BUFFERS; i++) {
+            SurfaceControl sc = createSurfaceControl();
+            BufferFlinger bufferTracker = createBufferTracker(Color.argb(getRandomColorComponent(),
+                    getRandomColorComponent(), getRandomColorComponent(),
+                    getRandomColorComponent()));
+            bufferTracker.addBuffer(t, sc);
+            t.setPosition(sc, i * 10, i * 10);
+            t.show(sc);
+        }
+        t.apply(true);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < MAX_BUFFERS; i++) {
+                mByfferTrackers.get(i).addBuffer(t, mSurfaceControls.get(i));
+            }
+            t.apply();
+        }
+    }
+
+    @Test
+    public void multipleOpaqueBuffers() throws Exception {
+        final int MAX_BUFFERS = 10;
+
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        for (int i = 0; i < MAX_BUFFERS; i++) {
+            SurfaceControl sc = createSurfaceControl();
+            BufferFlinger bufferTracker = createBufferTracker(Color.rgb(getRandomColorComponent(),
+                    getRandomColorComponent(), getRandomColorComponent()));
+            bufferTracker.addBuffer(t, sc);
+            t.setOpaque(sc, true);
+            t.setPosition(sc, i * 10, i * 10);
+            t.show(sc);
+        }
+        t.apply(true);
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            for (int i = 0; i < MAX_BUFFERS; i++) {
+                mByfferTrackers.get(i).addBuffer(t, mSurfaceControls.get(i));
+            }
+            t.apply();
+        }
+    }
+
+    @Test
+    public void geometryChanges() throws Exception {
+        final int MAX_POSITION = 10;
+        final float MAX_SCALE = 2.0f;
+
+        SurfaceControl sc = createSurfaceControl();
+        BufferFlinger bufferTracker = createBufferTracker(Color.GREEN);
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        bufferTracker.addBuffer(t, sc);
+        t.show(sc).apply(true);
+
+        int step = 0;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            step = ++step % MAX_POSITION;
+            t.setPosition(sc, step, step);
+            float scale = ((step * MAX_SCALE) / MAX_POSITION) + 0.5f;
+            t.setScale(sc, scale, scale);
+            t.apply();
+        }
+    }
+
+    @Test
+    public void geometryWithBufferChanges() throws Exception {
+        final int MAX_POSITION = 10;
+
+        SurfaceControl sc = createSurfaceControl();
+        BufferFlinger bufferTracker = createBufferTracker(Color.GREEN);
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        bufferTracker.addBuffer(t, sc);
+        t.show(sc).apply(true);
+
+        int step = 0;
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            step = ++step % MAX_POSITION;
+            t.setPosition(sc, step, step);
+            float scale = ((step * 2.0f) / MAX_POSITION) + 0.5f;
+            t.setScale(sc, scale, scale);
+            bufferTracker.addBuffer(t, sc);
+            t.apply();
+        }
+    }
+
+    @Test
+    public void addRemoveLayers() throws Exception {
+        SurfaceControl sc = createSurfaceControl();
+        BufferFlinger bufferTracker = createBufferTracker(Color.GREEN);
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            SurfaceControl childSurfaceControl =  new SurfaceControl.Builder()
+                    .setName("childLayer").setBLASTLayer().build();
+            bufferTracker.addBuffer(t, childSurfaceControl);
+            t.reparent(childSurfaceControl, sc);
+            t.apply();
+            t.remove(childSurfaceControl).apply();
+        }
+    }
+
+    @Test
+    public void displayScreenshot() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Bitmap screenshot =
+                    InstrumentationRegistry.getInstrumentation().getUiAutomation().takeScreenshot();
+            screenshot.recycle();
+        }
+    }
+
+    @Test
+    public void layerScreenshot() throws Exception {
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            Bitmap screenshot =
+                    InstrumentationRegistry.getInstrumentation().getUiAutomation().takeScreenshot(
+                            mActivity.getWindow());
+            screenshot.recycle();
+        }
+    }
+
+}
diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java
index a9b2a31..832a0cd 100644
--- a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java
+++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java
@@ -43,7 +43,7 @@
         setContentView(mTestSurfaceView);
     }
 
-    public SurfaceControl getChildSurfaceControl() throws InterruptedException {
+    public SurfaceControl createChildSurfaceControl() throws InterruptedException {
         return mTestSurfaceView.getChildSurfaceControlHelper();
     }
 
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index f49cdbf..ab0ac5a 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -1312,6 +1312,9 @@
          * Calling this method will override any requirements previously defined
          * by {@link #setRequiredNetwork(NetworkRequest)}; you typically only
          * want to call one of these methods.
+         * <p> Starting in Android version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
+         * {@link JobScheduler} may try to shift the execution of jobs requiring
+         * {@link #NETWORK_TYPE_ANY} to when there is access to an un-metered network.
          * <p class="note">
          * When your job executes in
          * {@link JobService#onStartJob(JobParameters)}, be sure to use the
@@ -1742,6 +1745,7 @@
          *     <li>Bypass Doze, app standby, and battery saver network restrictions</li>
          *     <li>Be less likely to be killed than regular jobs</li>
          *     <li>Be subject to background location throttling</li>
+         *     <li>Be exempt from delay to optimize job execution</li>
          * </ol>
          *
          * <p>
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
index 632ecb2c..dfdb290 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
@@ -45,8 +45,23 @@
  * </p>
  * <p>
  * The framework will be intelligent about when it executes jobs, and attempt to batch
- * and defer them as much as possible. Typically if you don't specify a deadline on a job, it
+ * and defer them as much as possible. Typically, if you don't specify a deadline on a job, it
  * can be run at any moment depending on the current state of the JobScheduler's internal queue.
+ * </p>
+ * <p>
+ * Starting in Android version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
+ * JobScheduler may try to optimize job execution by shifting execution to times with more available
+ * system resources in order to lower user impact. Factors in system health include sufficient
+ * battery, idle, charging, and access to an un-metered network. Jobs will initially be treated as
+ * if they have all these requirements, but as their deadlines approach, restrictions will become
+ * less strict. Requested requirements will not be affected by this change.
+ * </p>
+ *
+ * {@see android.app.job.JobInfo.Builder#setRequiresBatteryNotLow(boolean)}
+ * {@see android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)}
+ * {@see android.app.job.JobInfo.Builder#setRequiresCharging(boolean)}
+ * {@see android.app.job.JobInfo.Builder#setRequiredNetworkType(int)}
+ *
  * <p>
  * While a job is running, the system holds a wakelock on behalf of your app.  For this reason,
  * you do not need to take any action to guarantee that the device stays awake for the
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ef8ae70..a87f2e2 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6134,6 +6134,11 @@
     field public static final int ROLE_OUTPUT = 2; // 0x2
   }
 
+  public class AudioDeviceVolumeManager {
+    ctor public AudioDeviceVolumeManager(@NonNull android.content.Context);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolume(@NonNull android.media.VolumeInfo, @NonNull android.media.AudioDeviceAttributes);
+  }
+
   public final class AudioFocusInfo implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public android.media.AudioAttributes getAttributes();
@@ -6453,6 +6458,33 @@
     method public void onSpatializerOutputChanged(@NonNull android.media.Spatializer, @IntRange(from=0) int);
   }
 
+  public final class VolumeInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public static android.media.VolumeInfo getDefaultVolumeInfo();
+    method public int getMaxVolumeIndex();
+    method public int getMinVolumeIndex();
+    method public int getStreamType();
+    method @Nullable public android.media.audiopolicy.AudioVolumeGroup getVolumeGroup();
+    method public int getVolumeIndex();
+    method public boolean hasStreamType();
+    method public boolean hasVolumeGroup();
+    method public boolean isMuted();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.VolumeInfo> CREATOR;
+    field public static final int INDEX_NOT_SET = -100; // 0xffffff9c
+  }
+
+  public static final class VolumeInfo.Builder {
+    ctor public VolumeInfo.Builder(int);
+    ctor public VolumeInfo.Builder(@NonNull android.media.audiopolicy.AudioVolumeGroup);
+    ctor public VolumeInfo.Builder(@NonNull android.media.VolumeInfo);
+    method @NonNull public android.media.VolumeInfo build();
+    method @NonNull public android.media.VolumeInfo.Builder setMaxVolumeIndex(int);
+    method @NonNull public android.media.VolumeInfo.Builder setMinVolumeIndex(int);
+    method @NonNull public android.media.VolumeInfo.Builder setMuted(boolean);
+    method @NonNull public android.media.VolumeInfo.Builder setVolumeIndex(int);
+  }
+
 }
 
 package android.media.audiofx {
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index b9ad595..7215987 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -753,7 +753,7 @@
 
     /**
      * Returns the vibration pattern for notifications posted to this channel. Will be ignored if
-     * vibration is not enabled ({@link #shouldVibrate()}.
+     * vibration is not enabled ({@link #shouldVibrate()}).
      */
     public long[] getVibrationPattern() {
         return mVibration;
diff --git a/core/java/android/hardware/biometrics/IBiometricContextListener.aidl b/core/java/android/hardware/biometrics/IBiometricContextListener.aidl
index 55cab52..2e8e763 100644
--- a/core/java/android/hardware/biometrics/IBiometricContextListener.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricContextListener.aidl
@@ -23,5 +23,8 @@
  * @hide
  */
 oneway interface IBiometricContextListener {
-    void onDozeChanged(boolean isDozing);
+    // Called when doze or awake (screen on) status changes.
+    // These may be called while the device is still transitioning to the new state
+    // (i.e. about to become awake or enter doze)
+    void onDozeChanged(boolean isDozing, boolean isAwake);
 }
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 43a6be5..fb8f84a 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -469,7 +469,15 @@
      * 2) The per-application switch (i.e. Settings.Global.ANGLE_GL_DRIVER_SELECTION_PKGS and
      *    Settings.Global.ANGLE_GL_DRIVER_SELECTION_VALUES; which corresponds to the
      *    “angle_gl_driver_selection_pkgs” and “angle_gl_driver_selection_values” settings); if it
-     *    forces a choice; otherwise ...
+     *    forces a choice;
+     *      - Workaround Note: ANGLE and Vulkan currently have issues with applications that use YUV
+     *        target functionality.  The ANGLE broadcast receiver code will apply a "deferlist" at
+     *        the first boot of a newly-flashed device.  However, there is a gap in time between
+     *        when applications can start and when the deferlist is applied.  For now, assume that
+     *        if ANGLE is the system driver and Settings.Global.ANGLE_GL_DRIVER_SELECTION_PKGS is
+     *        empty, that the deferlist has not yet been applied.  In this case, select the Legacy
+     *        driver.
+     *    otherwise ...
      * 3) Use ANGLE if isAngleEnabledByGameMode() returns true; otherwise ...
      * 4) The global switch (i.e. use the system driver, whether ANGLE or legacy;
      *    a.k.a. mAngleIsSystemDriver, which is set by the device’s “ro.hardware.egl” property)
@@ -509,9 +517,16 @@
         final List<String> optInValues = getGlobalSettingsString(
                 contentResolver, bundle, Settings.Global.ANGLE_GL_DRIVER_SELECTION_VALUES);
         Log.v(TAG, "Currently set values for:");
-        Log.v(TAG, "  angle_gl_driver_selection_pkgs = " + optInPackages);
+        Log.v(TAG, "    angle_gl_driver_selection_pkgs =" + optInPackages);
         Log.v(TAG, "  angle_gl_driver_selection_values =" + optInValues);
 
+        // If ANGLE is the system driver AND the deferlist has not yet been applied, select the
+        // Legacy driver
+        if (mAngleIsSystemDriver && optInPackages.size() <= 1) {
+            Log.v(TAG, "Ignoring angle_gl_driver_selection_* until deferlist has been applied");
+            return ANGLE_GL_DRIVER_TO_USE_LEGACY;
+        }
+
         // Make sure we have good settings to use
         if (optInPackages.size() != optInValues.size()) {
             Log.w(TAG,
diff --git a/core/java/android/os/VibrationAttributes.java b/core/java/android/os/VibrationAttributes.java
index 06930bb..392bf4e 100644
--- a/core/java/android/os/VibrationAttributes.java
+++ b/core/java/android/os/VibrationAttributes.java
@@ -145,7 +145,8 @@
      */
     @IntDef(prefix = { "FLAG_" }, flag = true, value = {
             FLAG_BYPASS_INTERRUPTION_POLICY,
-            FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF
+            FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF,
+            FLAG_INVALIDATE_SETTINGS_CACHE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Flag{}
@@ -182,7 +183,7 @@
      *
      * @hide
      */
-    public static final int FLAG_INVALIDATE_SETTINGS_CACHE = 0x3;
+    public static final int FLAG_INVALIDATE_SETTINGS_CACHE = 0x4;
 
     /**
      * All flags supported by vibrator service, update it when adding new flag.
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index bca100a..20f01ae 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -68,6 +68,12 @@
     public static final String SETTINGS_APP_LOCALE_OPT_IN_ENABLED =
             "settings_app_locale_opt_in_enabled";
 
+    /**
+     * Launch the Volume panel in SystemUI.
+     * @hide
+     */
+    public static final String SETTINGS_VOLUME_PANEL_IN_SYSTEMUI =
+            "settings_volume_panel_in_systemui";
 
     /** @hide */
     public static final String SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS =
@@ -110,6 +116,12 @@
      */
     public static final String SETTINGS_NEW_KEYBOARD_UI = "settings_new_keyboard_ui";
 
+    /**
+     * Enable the new pages which is implemented with SPA.
+     * @hide
+     */
+    public static final String SETTINGS_ENABLE_SPA = "settings_enable_spa";
+
     private static final Map<String, String> DEFAULT_FLAGS;
 
     static {
@@ -134,6 +146,7 @@
         DEFAULT_FLAGS.put("settings_search_always_expand", "true");
         DEFAULT_FLAGS.put(SETTINGS_ALLOW_INTENT_REDIRECTION_FOR_CLONE_PROFILE, "false");
         DEFAULT_FLAGS.put(SETTINGS_APP_LOCALE_OPT_IN_ENABLED, "true");
+        DEFAULT_FLAGS.put(SETTINGS_VOLUME_PANEL_IN_SYSTEMUI, "false");
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true");
         DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "true");
         DEFAULT_FLAGS.put(SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE, "true");
@@ -141,6 +154,7 @@
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_CLEAR_CALLING, "false");
         DEFAULT_FLAGS.put(SETTINGS_ACCESSIBILITY_SIMPLE_CURSOR, "false");
         DEFAULT_FLAGS.put(SETTINGS_NEW_KEYBOARD_UI, "false");
+        DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA, "false");
     }
 
     private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 6825f03..f93b8b7 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -226,8 +226,6 @@
     final UndoInputFilter mUndoInputFilter = new UndoInputFilter(this);
     boolean mAllowUndo = true;
 
-    private int mLastInputSource = InputDevice.SOURCE_UNKNOWN;
-
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     // Cursor Controllers.
@@ -1735,8 +1733,6 @@
     public void onTouchEvent(MotionEvent event) {
         final boolean filterOutEvent = shouldFilterOutTouchEvent(event);
 
-        mLastInputSource = event.getSource();
-
         mLastButtonState = event.getButtonState();
         if (filterOutEvent) {
             if (event.getActionMasked() == MotionEvent.ACTION_UP) {
@@ -1789,7 +1785,7 @@
     }
 
     private void showFloatingToolbar() {
-        if (mTextActionMode != null && showUIForTouchScreen()) {
+        if (mTextActionMode != null && mTextView.showUIForTouchScreen()) {
             // Delay "show" so it doesn't interfere with click confirmations
             // or double-clicks that could "dismiss" the floating toolbar.
             int delay = ViewConfiguration.getDoubleTapTimeout();
@@ -1870,7 +1866,7 @@
                     ? getSelectionController() : getInsertionController();
             if (cursorController != null && !cursorController.isActive()
                     && !cursorController.isCursorBeingModified()
-                    && showUIForTouchScreen()) {
+                    && mTextView.showUIForTouchScreen()) {
                 cursorController.show();
             }
         }
@@ -2521,7 +2517,7 @@
             return false;
         }
 
-        if (!showUIForTouchScreen()) {
+        if (!mTextView.showUIForTouchScreen()) {
             return false;
         }
 
@@ -2677,7 +2673,7 @@
                     mTextView.postDelayed(mShowSuggestionRunnable,
                             ViewConfiguration.getDoubleTapTimeout());
                 } else if (hasInsertionController()) {
-                    if (shouldInsertCursor && showUIForTouchScreen()) {
+                    if (shouldInsertCursor && mTextView.showUIForTouchScreen()) {
                         getInsertionController().show();
                     } else {
                         getInsertionController().hide();
@@ -5408,7 +5404,7 @@
             final boolean shouldShow = checkForTransforms() /*check not rotated and compute scale*/
                     && !tooLargeTextForMagnifier()
                     && obtainMagnifierShowCoordinates(event, showPosInView)
-                    && showUIForTouchScreen();
+                    && mTextView.showUIForTouchScreen();
             if (shouldShow) {
                 // Make the cursor visible and stop blinking.
                 mRenderCursorRegardlessTiming = true;
@@ -6354,16 +6350,6 @@
         }
     }
 
-    /**
-     * Returns true when need to show UIs, e.g. floating toolbar, etc, for finger based interaction.
-     *
-     * @return true if UIs need to show for finger interaciton. false if UIs are not necessary.
-     */
-    public boolean showUIForTouchScreen() {
-        return (mLastInputSource & InputDevice.SOURCE_TOUCHSCREEN)
-                == InputDevice.SOURCE_TOUCHSCREEN;
-    }
-
     /** Controller for the insertion cursor. */
     @VisibleForTesting
     public class InsertionPointCursorController implements CursorController {
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 4ccd77b..be6b08f 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -301,7 +301,7 @@
             final SelectionModifierCursorController controller = mEditor.getSelectionController();
             if (controller != null
                     && (mTextView.isTextSelectable() || mTextView.isTextEditable())) {
-                if (mEditor.showUIForTouchScreen()) {
+                if (mTextView.showUIForTouchScreen()) {
                     controller.show();
                 } else {
                     controller.hide();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 28b83b2..f53dd0c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -973,6 +973,11 @@
     private int mDeviceProvisionedState = DEVICE_PROVISIONED_UNKNOWN;
 
     /**
+     * The last input source on this TextView.
+     */
+    private int mLastInputSource = InputDevice.SOURCE_UNKNOWN;
+
+    /**
      * The TextView does not auto-size text (default).
      */
     public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0;
@@ -11565,6 +11570,7 @@
                     MotionEvent.actionToString(event.getActionMasked()),
                     event.getX(), event.getY());
         }
+        mLastInputSource = event.getSource();
         final int action = event.getActionMasked();
         if (mEditor != null) {
             if (!isFromPrimePointer(event, false)) {
@@ -11654,6 +11660,17 @@
     }
 
     /**
+     * Returns true when need to show UIs, e.g. floating toolbar, etc, for finger based interaction.
+     *
+     * @return true if UIs need to show for finger interaciton. false if UIs are not necessary.
+     * @hide
+     */
+    public final boolean showUIForTouchScreen() {
+        return (mLastInputSource & InputDevice.SOURCE_TOUCHSCREEN)
+                == InputDevice.SOURCE_TOUCHSCREEN;
+    }
+
+    /**
      * The fill dialog UI is a more conspicuous and efficient interface than dropdown UI.
      * If autofill suggestions are available when the user clicks on a field that supports filling
      * the dialog UI, Autofill will pop up a fill dialog. The dialog will take up a larger area
diff --git a/core/java/com/android/internal/widget/LocalImageResolver.java b/core/java/com/android/internal/widget/LocalImageResolver.java
index b11ea29..9ef7ce38 100644
--- a/core/java/com/android/internal/widget/LocalImageResolver.java
+++ b/core/java/com/android/internal/widget/LocalImageResolver.java
@@ -19,6 +19,8 @@
 import android.annotation.DrawableRes;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.ImageDecoder;
@@ -109,13 +111,13 @@
                 }
                 break;
             case Icon.TYPE_RESOURCE:
-                if (!(TextUtils.isEmpty(icon.getResPackage())
-                        || context.getPackageName().equals(icon.getResPackage()))) {
-                    // We can't properly resolve icons from other packages here, so fall back.
+                Resources res = resolveResourcesForIcon(context, icon);
+                if (res == null) {
+                    // We couldn't resolve resources properly, fall back to icon loading.
                     return icon.loadDrawable(context);
                 }
 
-                Drawable result = resolveImage(icon.getResId(), context, maxWidth, maxHeight);
+                Drawable result = resolveImage(res, icon.getResId(), maxWidth, maxHeight);
                 if (result != null) {
                     return tintDrawable(icon, result);
                 }
@@ -159,6 +161,13 @@
     }
 
     @Nullable
+    private static Drawable resolveImage(Resources res, @DrawableRes int resId, int maxWidth,
+            int maxHeight) {
+        final ImageDecoder.Source source = ImageDecoder.createSource(res, resId);
+        return resolveImage(source, maxWidth, maxHeight);
+    }
+
+    @Nullable
     private static Drawable resolveBitmapImage(Icon icon, Context context, int maxWidth,
             int maxHeight) {
 
@@ -259,4 +268,52 @@
         }
         return icon.getUri();
     }
+
+    /**
+     * Resolves the correct resources package for a given Icon - it may come from another
+     * package.
+     *
+     * @see Icon#loadDrawableInner(Context)
+     * @hide
+     *
+     * @return resources instance if the operation succeeded, null otherwise
+     */
+    @Nullable
+    @VisibleForTesting
+    public static Resources resolveResourcesForIcon(Context context, Icon icon) {
+        if (icon.getType() != Icon.TYPE_RESOURCE) {
+            return null;
+        }
+
+        // Icons cache resolved resources, use cache if available.
+        Resources res = icon.getResources();
+        if (res != null) {
+            return res;
+        }
+
+        String resPackage = icon.getResPackage();
+        // No package means we try to use current context.
+        if (TextUtils.isEmpty(resPackage) || context.getPackageName().equals(resPackage)) {
+            return context.getResources();
+        }
+
+        if ("android".equals(resPackage)) {
+            return Resources.getSystem();
+        }
+
+        final PackageManager pm = context.getPackageManager();
+        try {
+            ApplicationInfo ai = pm.getApplicationInfo(resPackage,
+                    PackageManager.MATCH_UNINSTALLED_PACKAGES
+                            | PackageManager.GET_SHARED_LIBRARY_FILES);
+            if (ai != null) {
+                return pm.getResourcesForApplication(ai);
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, String.format("Unable to resolve package %s for icon %s", resPackage, icon));
+            return null;
+        }
+
+        return null;
+    }
 }
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 7f50204..14699e7 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -95,3 +95,7 @@
 # Battery
 per-file com_android_internal_os_Kernel* = file:/BATTERY_STATS_OWNERS
 per-file com_android_internal_os_*MultiStateCounter* = file:/BATTERY_STATS_OWNERS
+
+# PM
+per-file com_android_internal_content_* = file:/PACKAGE_MANAGER_OWNERS
+
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index be82879..acf4da6 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -17,28 +17,25 @@
 #define LOG_TAG "NativeLibraryHelper"
 //#define LOG_NDEBUG 0
 
-#include "core_jni_helpers.h"
-
-#include <nativehelper/ScopedUtfChars.h>
 #include <androidfw/ZipFileRO.h>
 #include <androidfw/ZipUtils.h>
-#include <utils/Log.h>
-#include <utils/Vector.h>
-
-#include <zlib.h>
-
 #include <errno.h>
 #include <fcntl.h>
+#include <inttypes.h>
+#include <nativehelper/ScopedUtfChars.h>
 #include <stdlib.h>
 #include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <inttypes.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <zlib.h>
 
 #include <memory>
 
+#include "core_jni_helpers.h"
+
 #define APK_LIB "lib/"
 #define APK_LIB_LEN (sizeof(APK_LIB) - 1)
 
@@ -156,7 +153,7 @@
     size_t* total = (size_t*) arg;
     uint32_t uncompLen;
 
-    if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, NULL, NULL)) {
+    if (!zipFile->getEntryInfo(zipEntry, nullptr, &uncompLen, nullptr, nullptr, nullptr, nullptr)) {
         return INSTALL_FAILED_INVALID_APK;
     }
 
@@ -186,7 +183,7 @@
     uint16_t method;
     off64_t offset;
 
-    if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, NULL, &offset, &when, &crc)) {
+    if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, nullptr, &offset, &when, &crc)) {
         ALOGE("Couldn't read zip entry info\n");
         return INSTALL_FAILED_INVALID_APK;
     }
@@ -307,24 +304,24 @@
 class NativeLibrariesIterator {
 private:
     NativeLibrariesIterator(ZipFileRO* zipFile, bool debuggable, void* cookie)
-        : mZipFile(zipFile), mDebuggable(debuggable), mCookie(cookie), mLastSlash(NULL) {
+          : mZipFile(zipFile), mDebuggable(debuggable), mCookie(cookie), mLastSlash(nullptr) {
         fileName[0] = '\0';
     }
 
 public:
     static NativeLibrariesIterator* create(ZipFileRO* zipFile, bool debuggable) {
-        void* cookie = NULL;
+        void* cookie = nullptr;
         // Do not specify a suffix to find both .so files and gdbserver.
-        if (!zipFile->startIteration(&cookie, APK_LIB, NULL /* suffix */)) {
-            return NULL;
+        if (!zipFile->startIteration(&cookie, APK_LIB, nullptr /* suffix */)) {
+            return nullptr;
         }
 
         return new NativeLibrariesIterator(zipFile, debuggable, cookie);
     }
 
     ZipEntryRO next() {
-        ZipEntryRO next = NULL;
-        while ((next = mZipFile->nextEntry(mCookie)) != NULL) {
+        ZipEntryRO next = nullptr;
+        while ((next = mZipFile->nextEntry(mCookie)) != nullptr) {
             // Make sure this entry has a filename.
             if (mZipFile->getEntryFileName(next, fileName, sizeof(fileName))) {
                 continue;
@@ -338,7 +335,7 @@
             }
 
             const char* lastSlash = strrchr(fileName, '/');
-            ALOG_ASSERT(lastSlash != NULL, "last slash was null somehow for %s\n", fileName);
+            ALOG_ASSERT(lastSlash != nullptr, "last slash was null somehow for %s\n", fileName);
 
             // Skip directories.
             if (*(lastSlash + 1) == 0) {
@@ -389,24 +386,23 @@
 iterateOverNativeFiles(JNIEnv *env, jlong apkHandle, jstring javaCpuAbi,
                        jboolean debuggable, iterFunc callFunc, void* callArg) {
     ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
-    if (zipFile == NULL) {
+    if (zipFile == nullptr) {
         return INSTALL_FAILED_INVALID_APK;
     }
 
     std::unique_ptr<NativeLibrariesIterator> it(
             NativeLibrariesIterator::create(zipFile, debuggable));
-    if (it.get() == NULL) {
+    if (it.get() == nullptr) {
         return INSTALL_FAILED_INVALID_APK;
     }
 
     const ScopedUtfChars cpuAbi(env, javaCpuAbi);
-    if (cpuAbi.c_str() == NULL) {
-        // This would've thrown, so this return code isn't observable by
-        // Java.
+    if (cpuAbi.c_str() == nullptr) {
+        // This would've thrown, so this return code isn't observable by Java.
         return INSTALL_FAILED_INVALID_APK;
     }
-    ZipEntryRO entry = NULL;
-    while ((entry = it->next()) != NULL) {
+    ZipEntryRO entry = nullptr;
+    while ((entry = it->next()) != nullptr) {
         const char* fileName = it->currentEntry();
         const char* lastSlash = it->lastSlash();
 
@@ -427,31 +423,30 @@
     return INSTALL_SUCCEEDED;
 }
 
-
-static int findSupportedAbi(JNIEnv *env, jlong apkHandle, jobjectArray supportedAbisArray,
-        jboolean debuggable) {
-    const int numAbis = env->GetArrayLength(supportedAbisArray);
-    Vector<ScopedUtfChars*> supportedAbis;
-
-    for (int i = 0; i < numAbis; ++i) {
-        supportedAbis.add(new ScopedUtfChars(env,
-            (jstring) env->GetObjectArrayElement(supportedAbisArray, i)));
-    }
-
+static int findSupportedAbi(JNIEnv* env, jlong apkHandle, jobjectArray supportedAbisArray,
+                            jboolean debuggable) {
     ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
-    if (zipFile == NULL) {
+    if (zipFile == nullptr) {
         return INSTALL_FAILED_INVALID_APK;
     }
 
     std::unique_ptr<NativeLibrariesIterator> it(
             NativeLibrariesIterator::create(zipFile, debuggable));
-    if (it.get() == NULL) {
+    if (it.get() == nullptr) {
         return INSTALL_FAILED_INVALID_APK;
     }
 
-    ZipEntryRO entry = NULL;
+    const int numAbis = env->GetArrayLength(supportedAbisArray);
+
+    std::vector<ScopedUtfChars> supportedAbis;
+    supportedAbis.reserve(numAbis);
+    for (int i = 0; i < numAbis; ++i) {
+        supportedAbis.emplace_back(env, (jstring)env->GetObjectArrayElement(supportedAbisArray, i));
+    }
+
+    ZipEntryRO entry = nullptr;
     int status = NO_NATIVE_LIBRARIES;
-    while ((entry = it->next()) != NULL) {
+    while ((entry = it->next()) != nullptr) {
         // We're currently in the lib/ directory of the APK, so it does have some native
         // code. We should return INSTALL_FAILED_NO_MATCHING_ABIS if none of the
         // libraries match.
@@ -466,8 +461,8 @@
         const char* abiOffset = fileName + APK_LIB_LEN;
         const size_t abiSize = lastSlash - abiOffset;
         for (int i = 0; i < numAbis; i++) {
-            const ScopedUtfChars* abi = supportedAbis[i];
-            if (abi->size() == abiSize && !strncmp(abiOffset, abi->c_str(), abiSize)) {
+            const ScopedUtfChars& abi = supportedAbis[i];
+            if (abi.size() == abiSize && !strncmp(abiOffset, abi.c_str(), abiSize)) {
                 // The entry that comes in first (i.e. with a lower index) has the higher priority.
                 if (((i < status) && (status >= 0)) || (status < 0) ) {
                     status = i;
@@ -476,10 +471,6 @@
         }
     }
 
-    for (int i = 0; i < numAbis; ++i) {
-        delete supportedAbis[i];
-    }
-
     return status;
 }
 
@@ -521,19 +512,19 @@
 com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode(JNIEnv *env, jclass clazz,
         jlong apkHandle) {
     ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
-    void* cookie = NULL;
-    if (!zipFile->startIteration(&cookie, NULL /* prefix */, RS_BITCODE_SUFFIX)) {
+    void* cookie = nullptr;
+    if (!zipFile->startIteration(&cookie, nullptr /* prefix */, RS_BITCODE_SUFFIX)) {
         return APK_SCAN_ERROR;
     }
 
     char fileName[PATH_MAX];
-    ZipEntryRO next = NULL;
-    while ((next = zipFile->nextEntry(cookie)) != NULL) {
+    ZipEntryRO next = nullptr;
+    while ((next = zipFile->nextEntry(cookie)) != nullptr) {
         if (zipFile->getEntryFileName(next, fileName, sizeof(fileName))) {
             continue;
         }
         const char* lastSlash = strrchr(fileName, '/');
-        const char* baseName = (lastSlash == NULL) ? fileName : fileName + 1;
+        const char* baseName = (lastSlash == nullptr) ? fileName : fileName + 1;
         if (isFilenameSafe(baseName)) {
             zipFile->endIteration(cookie);
             return BITCODE_PRESENT;
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6a52ec9..e7cae76 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1565,7 +1565,8 @@
     <bool name="config_enableIdleScreenBrightnessMode">false</bool>
 
     <!-- Array of desired screen brightness in nits corresponding to the lux values
-         in the config_autoBrightnessLevels array. The display brightness is defined as the measured
+         in the config_autoBrightnessLevels array. As with config_screenBrightnessMinimumNits and
+         config_screenBrightnessMaximumNits, the display brightness is defined as the measured
          brightness of an all-white image.
 
          If this is defined then:
@@ -1586,7 +1587,7 @@
     <array name="config_autoBrightnessDisplayValuesNitsIdle">
     </array>
 
-    <!-- Array of output values for button backlight corresponding to the lux values
+    <!-- Array of output values for button backlight corresponding to the luX values
          in the config_autoBrightnessLevels array.  This array should have size one greater
          than the size of the config_autoBrightnessLevels array.
          The brightness values must be between 0 and 255 and be non-decreasing.
diff --git a/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java b/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
index 0cee526..271a20b 100644
--- a/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
@@ -17,6 +17,8 @@
 package com.android.internal.widget;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.graphics.BitmapFactory;
 import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.BitmapDrawable;
@@ -279,4 +281,49 @@
         // This drawable must not be loaded - if it was, the code ignored the package specification.
         assertThat(d).isNull();
     }
+
+    @Test
+    public void resolveResourcesForIcon_notAResourceIcon_returnsNull() {
+        Icon icon = Icon.createWithContentUri(Uri.parse("some_uri"));
+        assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)).isNull();
+    }
+
+    @Test
+    public void resolveResourcesForIcon_localPackageIcon_returnsPackageResources() {
+        Icon icon = Icon.createWithResource(mContext, R.drawable.test32x24);
+        assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon))
+                .isSameInstanceAs(mContext.getResources());
+    }
+
+    @Test
+    public void resolveResourcesForIcon_iconWithoutPackageSpecificed_returnsPackageResources() {
+        Icon icon = Icon.createWithResource("", R.drawable.test32x24);
+        assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon))
+                .isSameInstanceAs(mContext.getResources());
+    }
+
+    @Test
+    public void resolveResourcesForIcon_systemPackageSpecified_returnsSystemPackage() {
+        Icon icon = Icon.createWithResource("android", R.drawable.test32x24);
+        assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)).isSameInstanceAs(
+                Resources.getSystem());
+    }
+
+    @Test
+    public void resolveResourcesForIcon_differentPackageSpecified_returnsPackageResources() throws
+            PackageManager.NameNotFoundException {
+        String pkg = "com.android.settings";
+        Resources res = mContext.getPackageManager().getResourcesForApplication(pkg);
+        int resId = res.getIdentifier("ic_android", "drawable", pkg);
+        Icon icon = Icon.createWithResource(pkg, resId);
+
+        assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon).getDrawable(resId,
+                mContext.getTheme())).isNotNull();
+    }
+
+    @Test
+    public void resolveResourcesForIcon_invalidPackageSpecified_returnsNull() {
+        Icon icon = Icon.createWithResource("invalid.package", R.drawable.test32x24);
+        assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)).isNull();
+    }
 }
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index f030d80..e0e13f5 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -81,5 +81,6 @@
         <permission name="android.permission.READ_DEVICE_CONFIG" />
         <permission name="android.permission.READ_SAFETY_CENTER_STATUS" />
         <permission name="android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS" />
+        <permission name="android.permission.READ_SEARCH_INDEXABLES" />
     </privapp-permissions>
 </permissions>
diff --git a/ktfmt_includes.txt b/ktfmt_includes.txt
deleted file mode 100644
index c7062e0..0000000
--- a/ktfmt_includes.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-packages/SystemUI/compose/
-packages/SystemUI/screenshot/
-packages/SystemUI/src/com/android/systemui/people/data
-packages/SystemUI/src/com/android/systemui/people/ui
-packages/SystemUI/src/com/android/systemui/keyguard/data
-packages/SystemUI/src/com/android/systemui/keyguard/dagger
-packages/SystemUI/src/com/android/systemui/keyguard/domain
-packages/SystemUI/src/com/android/systemui/keyguard/shared
-packages/SystemUI/src/com/android/systemui/keyguard/ui
-packages/SystemUI/src/com/android/systemui/qs/footer
-packages/SystemUI/src/com/android/systemui/security
-packages/SystemUI/src/com/android/systemui/common/
-packages/SystemUI/tests/utils/src/com/android/systemui/qs/
-packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSecurityController.kt
-packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeUserInfoController.kt
-packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/MockUserSwitcherControllerWrapper.kt
-packages/SystemUI/tests/src/com/android/systemui/qs/footer/
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 0d75bc4..f1465f4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -105,8 +105,8 @@
         state.mTaskInfo = taskInfo;
         mTasks.put(taskInfo.taskId, state);
 
-        updateRecentsForVisibleFullscreenTask(taskInfo);
         if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
+        updateRecentsForVisibleFullscreenTask(taskInfo);
         if (shouldShowWindowDecor(taskInfo) && mWindowDecorViewModelOptional.isPresent()) {
             SurfaceControl.Transaction t = new SurfaceControl.Transaction();
             state.mWindowDecoration =
@@ -135,8 +135,8 @@
             mWindowDecorViewModelOptional.get().onTaskInfoChanged(
                     state.mTaskInfo, state.mWindowDecoration);
         }
-        updateRecentsForVisibleFullscreenTask(taskInfo);
         if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
+        updateRecentsForVisibleFullscreenTask(taskInfo);
 
         final Point positionInParent = state.mTaskInfo.positionInParent;
         if (!oldPositionInParent.equals(state.mTaskInfo.positionInParent)) {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
index 67d7aca..298bf68 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
@@ -86,8 +86,7 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
-                            repetitions = 3)
+                    .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
         }
 
         const val FIND_OBJECT_TIMEOUT = 2000L
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
index 293eb7c..47557bc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
@@ -18,7 +18,6 @@
 
 import android.platform.test.annotations.FlakyTest
 import android.platform.test.annotations.Postsubmit
-import android.platform.test.annotations.Presubmit
 import android.view.WindowInsets
 import android.view.WindowManager
 import androidx.test.filters.RequiresDevice
@@ -92,7 +91,7 @@
             }
         }
 
-    @Presubmit
+    @FlakyTest(bugId = 242088970)
     @Test
     fun testAppIsVisibleAtEnd() {
         testSpec.assertLayersEnd {
@@ -125,7 +124,7 @@
         super.navBarWindowIsAlwaysVisible()
 
     /** {@inheritDoc} */
-    @Postsubmit
+    @FlakyTest(bugId = 242088970)
     @Test
     override fun taskBarLayerIsVisibleAtStartAndEnd() =
         super.taskBarLayerIsVisibleAtStartAndEnd()
@@ -135,4 +134,28 @@
     @Test
     override fun taskBarWindowIsAlwaysVisible() =
         super.taskBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 242088970)
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() =
+        super.statusBarLayerIsVisibleAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 242088970)
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() =
+        super.statusBarLayerPositionAtStartAndEnd()
+
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 242088970)
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() =
+        super.statusBarWindowIsAlwaysVisible()
+
+    /** {@inheritDoc} */
+    @FlakyTest(bugId = 242088970)
+    @Test
+    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index d194472..6fcd17a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -185,8 +185,7 @@
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    supportedRotations = listOf(Surface.ROTATION_0),
-                    repetitions = 3
+                    supportedRotations = listOf(Surface.ROTATION_0)
                 )
         }
     }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
index 507562b..a99439e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
@@ -246,8 +246,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    supportedRotations = listOf(Surface.ROTATION_0),
-                    repetitions = 3
+                    supportedRotations = listOf(Surface.ROTATION_0)
                 )
         }
     }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
index b5a3c78..39a7017 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
@@ -100,7 +100,7 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                    supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3)
+                    supportedRotations = listOf(Surface.ROTATION_0))
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
index 1d26614..421a6fc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
@@ -125,7 +125,7 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3)
+                supportedRotations = listOf(Surface.ROTATION_0))
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
index b71a9d8..3bffef0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
@@ -86,8 +86,7 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
-                            repetitions = 3)
+                    .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
index 31a39c1..75d25e6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
@@ -105,8 +105,7 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
-                            repetitions = 3)
+                    .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index fd661cf..825aca3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -178,8 +178,7 @@
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    supportedRotations = listOf(Surface.ROTATION_0),
-                    repetitions = 3
+                    supportedRotations = listOf(Surface.ROTATION_0)
                 )
         }
     }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
index b3f0fb9..d3e2ce15 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
@@ -89,7 +89,7 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3
+                supportedRotations = listOf(Surface.ROTATION_0)
             )
         }
     }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
index 8bd5c54..3d64bbe 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
@@ -105,7 +105,7 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3
+                supportedRotations = listOf(Surface.ROTATION_0)
             )
         }
     }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
index 454927e..be39fae 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
@@ -116,8 +116,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
-                    repetitions = 3)
+                .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index 09248a1..4dc9858 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -264,8 +264,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigRotationTests(
-                supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
-                repetitions = 3
+                supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)
             )
         }
     }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
index 6d64cb9..d5de22f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
@@ -224,8 +224,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
-                    repetitions = 1)
+                .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
         }
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
index d238814..6cbb685 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
@@ -178,7 +178,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
                 supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
index ba40c27..581826e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
@@ -195,7 +195,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
                 supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
index 6828589..5c051e8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
@@ -182,7 +182,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
                 supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
index 9ac7c23..9ca9ab0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
@@ -186,7 +186,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 supportedRotations = listOf(Surface.ROTATION_0),
                 // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
                 supportedNavigationModes =
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
index 8401c1a..8e2769f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
@@ -180,7 +180,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
                 supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
index 168afda..531d376 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
@@ -195,7 +195,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
                 supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
index c1fce5f..ea43c7e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
@@ -183,7 +183,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)
             )
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
index 1530561..525e09a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
@@ -180,7 +180,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
                 supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
index 20544bd..c030603 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
@@ -184,7 +184,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
                 supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
index 5a8604f..b8565f3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
@@ -183,7 +183,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
                 supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
index adea66a..20d7f2c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
@@ -185,7 +185,6 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
-                repetitions = SplitScreenHelper.TEST_REPETITIONS,
                 // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
                 supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 88f73d6..b11e542 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -93,6 +93,10 @@
 
 cc_defaults {
     name: "hwui_static_deps",
+    defaults: [
+        "android.hardware.graphics.common-ndk_shared",
+        "android.hardware.graphics.composer3-ndk_shared",
+    ],
     shared_libs: [
         "libbase",
         "libharfbuzz_ng",
@@ -106,9 +110,7 @@
     target: {
         android: {
             shared_libs: [
-                "android.hardware.graphics.common-V3-ndk",
                 "android.hardware.graphics.common@1.2",
-                "android.hardware.graphics.composer3-V1-ndk",
                 "liblog",
                 "libcutils",
                 "libutils",
diff --git a/media/Android.bp b/media/Android.bp
index 7118afa..e97f077 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -35,8 +35,8 @@
         "aidl/android/media/soundtrigger_middleware/SoundTriggerModuleDescriptor.aidl",
     ],
     imports: [
-        "android.media.audio.common.types",
-        "android.media.soundtrigger.types",
+        "android.media.audio.common.types-V2",
+        "android.media.soundtrigger.types-V1",
         "media_permission-aidl",
     ],
 }
@@ -232,12 +232,12 @@
         },
     },
     imports: [
-        "android.media.audio.common.types",
+        "android.media.audio.common.types-V2",
     ],
     versions_with_info: [
         {
             version: "1",
-            imports: ["android.media.audio.common.types-V1"],
+            imports: ["android.media.audio.common.types-V2"],
         },
     ],
 
diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java
index c708876..40f6dc5 100644
--- a/media/java/android/media/AudioDeviceVolumeManager.java
+++ b/media/java/android/media/AudioDeviceVolumeManager.java
@@ -21,6 +21,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -39,23 +41,29 @@
  * @hide
  * AudioDeviceVolumeManager provides access to audio device volume control.
  */
+@SystemApi
 public class AudioDeviceVolumeManager {
 
     // define when using Log.*
     //private static final String TAG = "AudioDeviceVolumeManager";
 
-    /** Indicates no special treatment in the handling of the volume adjustment */
+    /** @hide
+     * Indicates no special treatment in the handling of the volume adjustment */
     public static final int ADJUST_MODE_NORMAL = 0;
-    /** Indicates the start of a volume adjustment */
+    /** @hide
+     * Indicates the start of a volume adjustment */
     public static final int ADJUST_MODE_START = 1;
-    /** Indicates the end of a volume adjustment */
+    /** @hide
+     * Indicates the end of a volume adjustment */
     public static final int ADJUST_MODE_END = 2;
 
+    /** @hide */
     @IntDef(flag = false, prefix = "ADJUST_MODE", value = {
             ADJUST_MODE_NORMAL,
             ADJUST_MODE_START,
             ADJUST_MODE_END}
     )
+    /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     public @interface VolumeAdjustmentMode {}
 
@@ -64,7 +72,16 @@
     private final @NonNull String mPackageName;
     private final @Nullable String mAttributionTag;
 
-    public AudioDeviceVolumeManager(Context context) {
+    /**
+     * Constructor
+     * @param context the Context for the device volume operations
+     */
+    @SuppressLint("ManagerConstructor")
+    // reason for suppression: even though the functionality handled by this class is implemented in
+    // AudioService, we want to avoid bloating android.media.AudioManager
+    // with @SystemApi functionality
+    public AudioDeviceVolumeManager(@NonNull Context context) {
+        Objects.requireNonNull(context);
         mPackageName = context.getApplicationContext().getOpPackageName();
         mAttributionTag = context.getApplicationContext().getAttributionTag();
     }
@@ -101,6 +118,7 @@
                 @VolumeAdjustmentMode int mode);
     }
 
+    /** @hide */
     static class ListenerInfo {
         final @NonNull OnAudioDeviceVolumeChangedListener mListener;
         final @NonNull Executor mExecutor;
@@ -127,6 +145,7 @@
     @GuardedBy("mDeviceVolumeListenerLock")
     private DeviceVolumeDispatcherStub mDeviceVolumeDispatcherStub;
 
+    /** @hide */
     final class DeviceVolumeDispatcherStub extends IAudioDeviceVolumeDispatcher.Stub {
         /**
          * Register / unregister the stub
@@ -305,6 +324,7 @@
      * @param vi the volume information, only stream-based volumes are supported
      * @param ada the device for which volume is to be modified
      */
+    @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada) {
         try {
@@ -315,6 +335,7 @@
     }
 
     /**
+     * @hide
      * Return human-readable name for volume behavior
      * @param behavior one of the volume behaviors defined in AudioManager
      * @return a string for the given behavior
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 650f360..72190e3 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -65,8 +65,6 @@
 
     private static final String TAG = "AudioSystem";
 
-    private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U
-
     // private constructor to prevent instantiating AudioSystem
     private AudioSystem() {
         throw new UnsupportedOperationException("Trying to instantiate AudioSystem");
@@ -293,7 +291,7 @@
             case AUDIO_FORMAT_APTX_HD: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
             case AUDIO_FORMAT_LDAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
             case AUDIO_FORMAT_LC3: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3;
-            case AUDIO_FORMAT_OPUS: return SOURCE_CODEC_TYPE_OPUS; // TODO update in U
+            case AUDIO_FORMAT_OPUS: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS;
             default:
                 Log.e(TAG, "Unknown audio format 0x" + Integer.toHexString(audioFormat)
                         + " for conversion to BT codec");
@@ -336,7 +334,7 @@
                 return AudioSystem.AUDIO_FORMAT_LDAC;
             case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3:
                 return AudioSystem.AUDIO_FORMAT_LC3;
-            case SOURCE_CODEC_TYPE_OPUS: // TODO update in U
+            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS:
                 return AudioSystem.AUDIO_FORMAT_OPUS;
             default:
                 Log.e(TAG, "Unknown BT codec 0x" + Integer.toHexString(btCodec)
diff --git a/media/java/android/media/VolumeInfo.java b/media/java/android/media/VolumeInfo.java
index c61b0e5..6b4f604 100644
--- a/media/java/android/media/VolumeInfo.java
+++ b/media/java/android/media/VolumeInfo.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.media.audiopolicy.AudioVolumeGroup;
 import android.os.IBinder;
@@ -32,16 +33,13 @@
 
 /**
  * @hide
- * A class to represent type of volume information.
+ * A class to represent volume information.
  * Can be used to represent volume associated with a stream type or {@link AudioVolumeGroup}.
  * Volume index is optional when used to represent a category of volume.
  * Index ranges are supported too, making the representation of volume changes agnostic to the
  * range (e.g. can be used to map BT A2DP absolute volume range to internal range).
- *
- * Note: this class is not yet part of the SystemApi but is intended to be gradually introduced
- *       particularly in parts of the audio framework that suffer from code ambiguity when
- *       dealing with different volume ranges / units.
  */
+@SystemApi
 public final class VolumeInfo implements Parcelable {
     private static final String TAG = "VolumeInfo";
 
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index 31fb8d0..9bf126b 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -35,7 +35,7 @@
     ISessionController getController();
     void setFlags(int flags);
     void setActive(boolean active);
-    void setMediaButtonReceiver(in PendingIntent mbr);
+    void setMediaButtonReceiver(in PendingIntent mbr, String sessionPackageName);
     void setMediaButtonBroadcastReceiver(in ComponentName broadcastReceiver);
     void setLaunchPendingIntent(in PendingIntent pi);
     void destroySession();
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 1bd12af..9e265d8 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -286,7 +286,7 @@
     @Deprecated
     public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
         try {
-            mBinder.setMediaButtonReceiver(mbr);
+            mBinder.setMediaButtonReceiver(mbr, mContext.getPackageName());
         } catch (RemoteException e) {
             Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
         }
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt
index e300624..3f37534 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt
@@ -24,6 +24,7 @@
 import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider
 import com.android.settingslib.spa.gallery.page.SliderPageProvider
 import com.android.settingslib.spa.gallery.page.SwitchPreferencePageProvider
+import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
 
 val galleryPageProviders = SettingsPageProviderRepository(
     allPagesList = listOf(
@@ -32,6 +33,7 @@
         SwitchPreferencePageProvider,
         ArgumentPageProvider,
         SliderPageProvider,
+        SpinnerPageProvider,
         SettingsPagerPageProvider,
         FooterPageProvider,
     ),
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
index a85ee2a..089920c 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
@@ -29,6 +29,7 @@
 import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider
 import com.android.settingslib.spa.gallery.page.SliderPageProvider
 import com.android.settingslib.spa.gallery.page.SwitchPreferencePageProvider
+import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
 import com.android.settingslib.spa.widget.scaffold.HomeScaffold
 
 object HomePageProvider : SettingsPageProvider {
@@ -48,6 +49,7 @@
         ArgumentPageProvider.EntryItem(stringParam = "foo", intParam = 0)
 
         SliderPageProvider.EntryItem()
+        SpinnerPageProvider.EntryItem()
         SettingsPagerPageProvider.EntryItem()
         FooterPageProvider.EntryItem()
     }
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
index 3146351..130cbd9 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
@@ -30,11 +30,11 @@
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.theme.SettingsTheme
+import com.android.settingslib.spa.widget.SettingsSlider
+import com.android.settingslib.spa.widget.SettingsSliderModel
 import com.android.settingslib.spa.widget.preference.Preference
 import com.android.settingslib.spa.widget.preference.PreferenceModel
 import com.android.settingslib.spa.widget.scaffold.RegularScaffold
-import com.android.settingslib.spa.widget.ui.SettingsSlider
-import com.android.settingslib.spa.widget.ui.SettingsSliderModel
 
 private const val TITLE = "Sample Slider"
 
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt
new file mode 100644
index 0000000..7efa85b
--- /dev/null
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.gallery.ui
+
+import android.os.Bundle
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.ui.tooling.preview.Preview
+import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.compose.navigator
+import com.android.settingslib.spa.framework.theme.SettingsTheme
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
+import com.android.settingslib.spa.widget.scaffold.RegularScaffold
+import com.android.settingslib.spa.widget.ui.Spinner
+
+private const val TITLE = "Sample Spinner"
+
+object SpinnerPageProvider : SettingsPageProvider {
+    override val name = "Spinner"
+
+    @Composable
+    override fun Page(arguments: Bundle?) {
+        SpinnerPage()
+    }
+
+    @Composable
+    fun EntryItem() {
+        Preference(object : PreferenceModel {
+            override val title = TITLE
+            override val onClick = navigator(name)
+        })
+    }
+}
+
+@Composable
+private fun SpinnerPage() {
+    RegularScaffold(title = TITLE) {
+        val selectedIndex = rememberSaveable { mutableStateOf(0) }
+        Spinner(
+            options = (1..3).map { "Option $it" },
+            selectedIndex = selectedIndex.value,
+            setIndex = { selectedIndex.value = it },
+        )
+        Preference(object : PreferenceModel {
+            override val title = "Selected index"
+            override val summary = remember { derivedStateOf { selectedIndex.value.toString() } }
+        })
+    }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun SpinnerPagePreview() {
+    SettingsTheme {
+        SpinnerPage()
+    }
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
index 6a7b17a..e8d1ea2 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
@@ -21,6 +21,8 @@
 import androidx.activity.compose.setContent
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.LaunchedEffect
+import androidx.navigation.NavGraph.Companion.findStartDestination
 import androidx.navigation.compose.NavHost
 import androidx.navigation.compose.composable
 import androidx.navigation.compose.rememberNavController
@@ -46,12 +48,11 @@
 
     @Composable
     private fun MainContent() {
-        val startDestination =
-            intent?.getStringExtra(KEY_START_DESTINATION) ?: sppRepository.getDefaultStartPageName()
+        val destination = intent?.getStringExtra(KEY_DESTINATION)
 
         val navController = rememberNavController()
         CompositionLocalProvider(navController.localNavController()) {
-            NavHost(navController, startDestination) {
+            NavHost(navController, sppRepository.getDefaultStartPageName()) {
                 for (page in sppRepository.getAllProviders()) {
                     composable(
                         route = page.route,
@@ -61,6 +62,16 @@
                     }
                 }
             }
+
+            if (!destination.isNullOrEmpty()) {
+                LaunchedEffect(Unit) {
+                    navController.navigate(destination) {
+                        popUpTo(navController.graph.findStartDestination().id) {
+                            inclusive = true
+                        }
+                    }
+                }
+            }
         }
     }
 
@@ -68,6 +79,6 @@
         get() = name + arguments.joinToString("") { argument -> "/{${argument.name}}" }
 
     companion object {
-        const val KEY_START_DESTINATION = "spa:SpaActivity:startDestination"
+        const val KEY_DESTINATION = "spa:SpaActivity:destination"
     }
 }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
index c68d5de..32ef0bb 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
@@ -16,25 +16,35 @@
 
 package com.android.settingslib.spa.framework.compose
 
+import androidx.activity.OnBackPressedDispatcher
+import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ProvidedValue
 import androidx.compose.runtime.compositionLocalOf
 import androidx.compose.runtime.remember
 import androidx.navigation.NavHostController
 
 interface NavControllerWrapper {
     fun navigate(route: String)
-    fun navigateUp()
+    fun navigateBack()
 }
 
 @Composable
-fun NavHostController.localNavController() =
-    LocalNavController provides remember { NavControllerWrapperImpl(this) }
+fun NavHostController.localNavController(): ProvidedValue<NavControllerWrapper> {
+    val onBackPressedDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
+    return LocalNavController provides remember {
+        NavControllerWrapperImpl(
+            navController = this,
+            onBackPressedDispatcher = onBackPressedDispatcherOwner?.onBackPressedDispatcher,
+        )
+    }
+}
 
 val LocalNavController = compositionLocalOf<NavControllerWrapper> {
     object : NavControllerWrapper {
         override fun navigate(route: String) {}
 
-        override fun navigateUp() {}
+        override fun navigateBack() {}
     }
 }
 
@@ -46,12 +56,13 @@
 
 internal class NavControllerWrapperImpl(
     private val navController: NavHostController,
+    private val onBackPressedDispatcher: OnBackPressedDispatcher?,
 ) : NavControllerWrapper {
     override fun navigate(route: String) {
         navController.navigate(route)
     }
 
-    override fun navigateUp() {
-        navController.navigateUp()
+    override fun navigateBack() {
+        onBackPressedDispatcher?.onBackPressed()
     }
 }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
index 27fdc91..bc316f7 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
@@ -31,6 +31,10 @@
     val secondaryText: Color = Color.Unspecified,
     val primaryContainer: Color = Color.Unspecified,
     val onPrimaryContainer: Color = Color.Unspecified,
+    val spinnerHeaderContainer: Color = Color.Unspecified,
+    val onSpinnerHeaderContainer: Color = Color.Unspecified,
+    val spinnerItemContainer: Color = Color.Unspecified,
+    val onSpinnerItemContainer: Color = Color.Unspecified,
 )
 
 internal val LocalColorScheme = staticCompositionLocalOf { SettingsColorScheme() }
@@ -65,6 +69,10 @@
         secondaryText = tonalPalette.neutralVariant30,
         primaryContainer = tonalPalette.primary90,
         onPrimaryContainer = tonalPalette.neutral10,
+        spinnerHeaderContainer = tonalPalette.primary90,
+        onSpinnerHeaderContainer = tonalPalette.neutral10,
+        spinnerItemContainer = tonalPalette.secondary90,
+        onSpinnerItemContainer = tonalPalette.neutralVariant30,
     )
 }
 
@@ -87,5 +95,9 @@
         secondaryText = tonalPalette.neutralVariant80,
         primaryContainer = tonalPalette.secondary90,
         onPrimaryContainer = tonalPalette.neutral10,
+        spinnerHeaderContainer = tonalPalette.primary90,
+        onSpinnerHeaderContainer = tonalPalette.neutral10,
+        spinnerItemContainer = tonalPalette.secondary90,
+        onSpinnerItemContainer = tonalPalette.neutralVariant30,
     )
 }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/SettingsSlider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/SettingsSlider.kt
similarity index 98%
rename from packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/SettingsSlider.kt
rename to packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/SettingsSlider.kt
index 0454ac3..4f77a89 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/SettingsSlider.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/SettingsSlider.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settingslib.spa.widget.ui
+package com.android.settingslib.spa.widget
 
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.outlined.AccessAlarm
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
index c960254..b8e4360 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
@@ -26,13 +26,13 @@
 import com.android.settingslib.spa.framework.compose.LocalNavController
 
 @Composable
-internal fun NavigateUp() {
+internal fun NavigateBack() {
     val navController = LocalNavController.current
     val contentDescription = stringResource(
         id = androidx.appcompat.R.string.abc_action_bar_up_description,
     )
     BackAction(contentDescription) {
-        navController.navigateUp()
+        navController.navigateBack()
     }
 }
 
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt
index ee453f2..8b530b0 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt
@@ -49,7 +49,7 @@
                         modifier = Modifier.padding(SettingsDimension.itemPaddingAround),
                     )
                 },
-                navigationIcon = { NavigateUp() },
+                navigationIcon = { NavigateBack() },
                 actions = actions,
                 colors = settingsTopAppBarColors(),
             )
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
new file mode 100644
index 0000000..429b81a
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.widget.ui
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.selection.selectableGroup
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.ArrowDropDown
+import androidx.compose.material.icons.outlined.ArrowDropUp
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.DropdownMenu
+import androidx.compose.material3.DropdownMenuItem
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.DpOffset
+import androidx.compose.ui.unit.dp
+import com.android.settingslib.spa.framework.theme.SettingsDimension
+import com.android.settingslib.spa.framework.theme.SettingsTheme
+
+@Composable
+fun Spinner(options: List<String>, selectedIndex: Int, setIndex: (index: Int) -> Unit) {
+    if (options.isEmpty()) {
+        return
+    }
+
+    var expanded by rememberSaveable { mutableStateOf(false) }
+
+    Box(
+        modifier = Modifier
+            .padding(SettingsDimension.itemPadding)
+            .selectableGroup(),
+    ) {
+        val contentPadding = PaddingValues(horizontal = SettingsDimension.itemPaddingEnd)
+        Button(
+            onClick = { expanded = true },
+            modifier = Modifier.height(36.dp),
+            colors = ButtonDefaults.buttonColors(
+                containerColor = SettingsTheme.colorScheme.spinnerHeaderContainer,
+                contentColor = SettingsTheme.colorScheme.onSpinnerHeaderContainer,
+            ),
+            contentPadding = contentPadding,
+        ) {
+            SpinnerText(options[selectedIndex])
+            Icon(
+                imageVector = when {
+                    expanded -> Icons.Outlined.ArrowDropUp
+                    else -> Icons.Outlined.ArrowDropDown
+                },
+                contentDescription = null,
+            )
+        }
+        DropdownMenu(
+            expanded = expanded,
+            onDismissRequest = { expanded = false },
+            modifier = Modifier.background(SettingsTheme.colorScheme.spinnerItemContainer),
+            offset = DpOffset(x = 0.dp, y = 4.dp),
+        ) {
+            options.forEachIndexed { index, option ->
+                DropdownMenuItem(
+                    text = {
+                        SpinnerText(
+                            text = option,
+                            modifier = Modifier.padding(end = 24.dp),
+                            color = SettingsTheme.colorScheme.onSpinnerItemContainer,
+                        )
+                    },
+                    onClick = {
+                        expanded = false
+                        setIndex(index)
+                    },
+                    contentPadding = contentPadding,
+                )
+            }
+        }
+    }
+}
+
+@Composable
+private fun SpinnerText(
+    text: String,
+    modifier: Modifier = Modifier,
+    color: Color = Color.Unspecified,
+) {
+    Text(
+        text = text,
+        modifier = modifier.padding(end = SettingsDimension.itemPaddingEnd),
+        color = color,
+        style = MaterialTheme.typography.labelLarge,
+    )
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun SpinnerPreview() {
+    SettingsTheme {
+        var selectedIndex by rememberSaveable { mutableStateOf(0) }
+        Spinner(
+            options = (1..3).map { "Option $it" },
+            selectedIndex = selectedIndex,
+            setIndex = { selectedIndex = it },
+        )
+    }
+}
diff --git a/packages/SettingsLib/Spa/tests/Android.bp b/packages/SettingsLib/Spa/tests/Android.bp
index 037d8c4..1ce49fa 100644
--- a/packages/SettingsLib/Spa/tests/Android.bp
+++ b/packages/SettingsLib/Spa/tests/Android.bp
@@ -31,6 +31,7 @@
         "androidx.compose.runtime_runtime",
         "androidx.compose.ui_ui-test-junit4",
         "androidx.compose.ui_ui-test-manifest",
+        "truth-prebuilt",
     ],
     kotlincflags: ["-Xjvm-default=all"],
 }
diff --git a/packages/SettingsLib/Spa/tests/build.gradle b/packages/SettingsLib/Spa/tests/build.gradle
index be5a5ec..5f93a9f 100644
--- a/packages/SettingsLib/Spa/tests/build.gradle
+++ b/packages/SettingsLib/Spa/tests/build.gradle
@@ -63,5 +63,6 @@
     androidTestImplementation(project(":spa"))
     androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.3'
     androidTestImplementation("androidx.compose.ui:ui-test-junit4:$jetpack_compose_version")
+    androidTestImplementation 'com.google.truth:truth:1.1.3'
     androidTestDebugImplementation "androidx.compose.ui:ui-test-manifest:$jetpack_compose_version"
 }
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/SettingsSliderTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/SettingsSliderTest.kt
new file mode 100644
index 0000000..1d95e33
--- /dev/null
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/SettingsSliderTest.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.widget
+
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class SettingsSliderTest {
+    @get:Rule
+    val composeTestRule = createComposeRule()
+
+    @Test
+    fun title_displayed() {
+        composeTestRule.setContent {
+            SettingsSlider(object : SettingsSliderModel {
+                override val title = "Slider"
+                override val initValue = 40
+            })
+        }
+
+        composeTestRule.onNodeWithText("Slider").assertIsDisplayed()
+    }
+
+    // TODO: Add more unit tests for SettingsSlider widget.
+}
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/SpinnerTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/SpinnerTest.kt
new file mode 100644
index 0000000..6c56d63
--- /dev/null
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/SpinnerTest.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.widget.ui
+
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performClick
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class SpinnerTest {
+    @get:Rule
+    val composeTestRule = createComposeRule()
+
+    @Test
+    fun spinner_initialState() {
+        var selectedIndex by mutableStateOf(0)
+        composeTestRule.setContent {
+            Spinner(
+                options = (1..3).map { "Option $it" },
+                selectedIndex = selectedIndex,
+                setIndex = { selectedIndex = it },
+            )
+        }
+
+        composeTestRule.onNodeWithText("Option 1").assertIsDisplayed()
+        composeTestRule.onNodeWithText("Option 2").assertDoesNotExist()
+        assertThat(selectedIndex).isEqualTo(0)
+    }
+
+    @Test
+    fun spinner_canChangeState() {
+        var selectedIndex by mutableStateOf(0)
+        composeTestRule.setContent {
+            Spinner(
+                options = (1..3).map { "Option $it" },
+                selectedIndex = selectedIndex,
+                setIndex = { selectedIndex = it },
+            )
+        }
+
+        composeTestRule.onNodeWithText("Option 1").performClick()
+        composeTestRule.onNodeWithText("Option 2").performClick()
+
+        composeTestRule.onNodeWithText("Option 1").assertDoesNotExist()
+        composeTestRule.onNodeWithText("Option 2").assertIsDisplayed()
+        assertThat(selectedIndex).isEqualTo(1)
+    }
+}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
index dac79a0..eb9ce5e 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
@@ -30,7 +30,6 @@
 import androidx.navigation.navArgument
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.compose.navigator
-import com.android.settingslib.spa.framework.compose.rememberContext
 import com.android.settingslib.spa.widget.preference.SwitchPreference
 import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
 import com.android.settingslib.spaprivileged.model.app.AppRecord
@@ -44,7 +43,7 @@
 private const val USER_ID = "userId"
 
 internal class TogglePermissionAppInfoPageProvider(
-    private val factory: TogglePermissionAppListModelFactory,
+    private val appListTemplate: TogglePermissionAppListTemplate,
 ) : SettingsPageProvider {
     override val name = NAME
 
@@ -57,10 +56,10 @@
     @Composable
     override fun Page(arguments: Bundle?) {
         checkNotNull(arguments)
-        val permission = checkNotNull(arguments.getString(PERMISSION))
+        val permissionType = checkNotNull(arguments.getString(PERMISSION))
         val packageName = checkNotNull(arguments.getString(PACKAGE_NAME))
         val userId = arguments.getInt(USER_ID)
-        val listModel = rememberContext { context -> factory.createModel(permission, context) }
+        val listModel = appListTemplate.rememberModel(permissionType)
         TogglePermissionAppInfoPage(listModel, packageName, userId)
     }
 
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListModel.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
similarity index 73%
rename from packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListModel.kt
rename to packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
index e1354bd..3cc5854 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListModel.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
@@ -47,20 +47,14 @@
     fun setAllowed(record: T, newAllowed: Boolean)
 }
 
-interface TogglePermissionAppListModelFactory {
-    fun createModel(
-        permission: String,
-        context: Context,
-    ): TogglePermissionAppListModel<out AppRecord>
+interface TogglePermissionAppListProvider {
+    val permissionType: String
 
-    fun createPageProviders(): List<SettingsPageProvider> = listOf(
-        TogglePermissionAppListPageProvider(this),
-        TogglePermissionAppInfoPageProvider(this),
-    )
+    fun createModel(context: Context): TogglePermissionAppListModel<out AppRecord>
 
     @Composable
-    fun EntryItem(permissionType: String) {
-        val listModel = rememberModel(permissionType)
+    fun EntryItem() {
+        val listModel = rememberContext(::createModel)
         Preference(
             object : PreferenceModel {
                 override val title = stringResource(listModel.pageTitleResId)
@@ -68,8 +62,28 @@
             }
         )
     }
+
+    /**
+     * Gets the route to the toggle permission App List page.
+     *
+     * Expose route to enable enter from non-SPA pages.
+     */
+    fun getRoute(): String =
+        TogglePermissionAppListPageProvider.getRoute(permissionType)
 }
 
-@Composable
-internal fun TogglePermissionAppListModelFactory.rememberModel(permission: String) =
-    rememberContext { context -> createModel(permission, context) }
+class TogglePermissionAppListTemplate(
+    allProviders: List<TogglePermissionAppListProvider>,
+) {
+    private val listModelProviderMap = allProviders.associateBy { it.permissionType }
+
+    fun createPageProviders(): List<SettingsPageProvider> = listOf(
+        TogglePermissionAppListPageProvider(this),
+        TogglePermissionAppInfoPageProvider(this),
+    )
+
+    @Composable
+    internal fun rememberModel(permissionType: String) = rememberContext { context ->
+        listModelProviderMap.getValue(permissionType).createModel(context)
+    }
+}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
index 6d00d56..f2eb962 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
@@ -38,7 +38,7 @@
 private const val PERMISSION = "permission"
 
 internal class TogglePermissionAppListPageProvider(
-    private val factory: TogglePermissionAppListModelFactory,
+    private val appListTemplate: TogglePermissionAppListTemplate,
 ) : SettingsPageProvider {
     override val name = NAME
 
@@ -55,7 +55,7 @@
 
     @Composable
     private fun TogglePermissionAppList(permissionType: String) {
-        val listModel = factory.rememberModel(permissionType)
+        val listModel = appListTemplate.rememberModel(permissionType)
         val context = LocalContext.current
         val internalListModel = remember {
             TogglePermissionInternalAppListModel(context, listModel)
@@ -75,8 +75,14 @@
     }
 
     companion object {
+        /**
+         * Gets the route to this page.
+         *
+         * Expose route to enable enter from non-SPA pages.
+         */
+        internal fun getRoute(permissionType: String) = "$NAME/$permissionType"
         @Composable
-        internal fun navigator(permissionType: String) = navigator(route = "$NAME/$permissionType")
+        internal fun navigator(permissionType: String) = navigator(route = getRoute(permissionType))
     }
 }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 1940986..b64dcca 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -43,8 +43,6 @@
 public class A2dpProfile implements LocalBluetoothProfile {
     private static final String TAG = "A2dpProfile";
 
-    private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U
-
     private Context mContext;
 
     private BluetoothA2dp mService;
@@ -333,7 +331,7 @@
             case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3:
                 index = 6;
                 break;
-            case SOURCE_CODEC_TYPE_OPUS: // TODO update in U
+            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS:
                 index = 7;
                 break;
            }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 78dea89..abcd65b 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -85,7 +85,6 @@
     <uses-permission android:name="android.permission.CONTROL_VPN" />
     <uses-permission android:name="android.permission.PEERS_MAC_ADDRESS"/>
     <uses-permission android:name="android.permission.READ_WIFI_CREDENTIAL"/>
-    <uses-permission android:name="android.permission.NETWORK_STACK"/>
     <!-- Physical hardware -->
     <uses-permission android:name="android.permission.MANAGE_USB" />
     <uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS" />
@@ -152,6 +151,9 @@
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" />
     <uses-permission android:name="android.permission.GET_RUNTIME_PERMISSIONS" />
 
+    <!-- For auto-grant the access to the Settings' slice preferences, e.g. volume slices. -->
+    <uses-permission android:name="android.permission.READ_SEARCH_INDEXABLES" />
+
     <!-- Needed for WallpaperManager.clear in ImageWallpaper.updateWallpaperLocked -->
     <uses-permission android:name="android.permission.SET_WALLPAPER"/>
 
@@ -956,5 +958,13 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name=".volume.VolumePanelDialogReceiver"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.settings.panel.action.VOLUME" />
+                <action android:name="com.android.systemui.action.LAUNCH_VOLUME_PANEL_DIALOG" />
+                <action android:name="com.android.systemui.action.DISMISS_VOLUME_PANEL_DIALOG" />
+            </intent-filter>
+        </receiver>
     </application>
 </manifest>
diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt
new file mode 100644
index 0000000..3ca8dfe
--- /dev/null
+++ b/packages/SystemUI/ktfmt_includes.txt
@@ -0,0 +1,870 @@
++packages/SystemUI
+-packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/BindServiceViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/BroadcastSentViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/GetMainLooperViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/RegisterReceiverViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/SoftwareBitmapDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/BindServiceViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/BroadcastSentViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/GetMainLooperViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/RegisterReceiverViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/SoftwareBitmapDetectorTest.kt
+-packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
+-packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+-packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainerController.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagSerializer.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagSettingsHelper.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionDarkness.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonPositionCalculator.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerManager.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/system/smartspace/SmartspaceState.kt
+-packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
+-packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt
+-packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
+-packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt
+-packages/SystemUI/src-release/com/android/systemui/flags/FlagsModule.kt
+-packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
+-packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardBiometricLockoutLogger.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardListenQueue.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt
+-packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt
+-packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+-packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/BootCompleteCache.kt
+-packages/SystemUI/src/com/android/systemui/BootCompleteCacheImpl.kt
+-packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt
+-packages/SystemUI/src/com/android/systemui/ChooserSelector.kt
+-packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt
+-packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
+-packages/SystemUI/src/com/android/systemui/DualToneHandler.kt
+-packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
+-packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
+-packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt
+-packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt
+-packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
+-packages/SystemUI/src/com/android/systemui/assist/AssistLogger.kt
+-packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt
+-packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt
+-packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AlternateUdfpsTouchProvider.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/BiometricDisplayListener.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/DwellRippleShader.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHapticsSimulator.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcherStartable.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/PendingRemovalStore.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt
+-packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
+-packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
+-packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt
+-packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlStatus.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlsMetricsLogger.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlsMetricsLoggerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt
+-packages/SystemUI/src/com/android/systemui/controls/CustomIconCache.kt
+-packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlInfo.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapper.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfiguration.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/StatefulControlSubscriber.kt
+-packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt
+-packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsFeatureEnabled.kt
+-packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/AllModel.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingController.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestReceiver.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/FavoritesModel.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ManagementPageIndicator.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlWithState.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/CornerDrawable.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
+-packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+-packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
+-packages/SystemUI/src/com/android/systemui/decor/DecorProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
+-packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
+-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
+-packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt
+-packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
+-packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
+-packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt
+-packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
+-packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
+-packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
+-packages/SystemUI/src/com/android/systemui/dump/DumpsysTableLogger.kt
+-packages/SystemUI/src/com/android/systemui/dump/LogBufferEulogizer.kt
+-packages/SystemUI/src/com/android/systemui/dump/LogBufferFreezer.kt
+-packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt
+-packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
+-packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt
+-packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
+-packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt
+-packages/SystemUI/src/com/android/systemui/log/LogLevel.kt
+-packages/SystemUI/src/com/android/systemui/log/LogMessage.kt
+-packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt
+-packages/SystemUI/src/com/android/systemui/log/LogcatEchoTracker.kt
+-packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt
+-packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerProd.kt
+-packages/SystemUI/src/com/android/systemui/media/AnimationBindHandler.kt
+-packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
+-packages/SystemUI/src/com/android/systemui/media/GutsViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/media/IlluminationDrawable.kt
+-packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
+-packages/SystemUI/src/com/android/systemui/media/LightSourceDrawable.kt
+-packages/SystemUI/src/com/android/systemui/media/LocalMediaManagerFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaCarouselControllerLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaFeatureFlag.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaHostStatesManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaProjectionCaptureTarget.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaScrollView.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaTimeoutLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaViewLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MetadataAnimationHandler.kt
+-packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
+-packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
+-packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt
+-packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaDataProvider.kt
+-packages/SystemUI/src/com/android/systemui/media/SquigglyProgress.kt
+-packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt
+-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionCli.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesManager.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttFlags.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
+-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
+-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+-packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
+-packages/SystemUI/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitor.kt
+-packages/SystemUI/src/com/android/systemui/privacy/MediaProjectionPrivacyItemMonitor.kt
+-packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipEvent.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyConfig.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogEvent.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+-packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt
+-packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+-packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
+-packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
+-packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSExpansionPathInterpolator.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSFragmentDisableFlagsLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSSquishinessController.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSUtils.kt
+-packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt
+-packages/SystemUI/src/com/android/systemui/qs/VisibilityChangedDispatcher.kt
+-packages/SystemUI/src/com/android/systemui/qs/carrier/CellSignalState.kt
+-packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/QSExternalModule.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialogEventLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt
+-packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/tileimpl/HeightOverrideable.kt
+-packages/SystemUI/src/com/android/systemui/qs/tileimpl/IgnorableChildLinearLayout.kt
+-packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+-packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
+-packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+-packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
+-packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
+-packages/SystemUI/src/com/android/systemui/ripple/RippleShader.kt
+-packages/SystemUI/src/com/android/systemui/ripple/RippleShaderUtilLibrary.kt
+-packages/SystemUI/src/com/android/systemui/ripple/RippleView.kt
+-packages/SystemUI/src/com/android/systemui/ripple/SdfShaderLibrary.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt
+-packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt
+-packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserContentResolverProvider.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserContextProvider.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+-packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessMirrorHandler.kt
+-packages/SystemUI/src/com/android/systemui/settings/brightness/MirroredBrightnessController.kt
+-packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManager.kt
+-packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
+-packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
+-packages/SystemUI/src/com/android/systemui/shade/NPVCDownEventState.kt
+-packages/SystemUI/src/com/android/systemui/shade/NotifPanelEvents.kt
+-packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
+-packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
+-packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+-packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenAndDreamTargetFilter.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/ActionClickLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBarWifiView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/DisableFlagsLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockScreenShadeOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/commandline/CommandRegistry.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/AccessPointController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalControllerFactory.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileStatusTrackerFactory.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalCallback.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiStatusTrackerFactory.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/FeedbackIcon.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClickerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManagerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineDumper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolver.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DebugModeCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManagerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifStabilityManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTracker.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifEvent.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtender.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/DebugModeFilterProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGroupController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewListener.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifShadeEventSource.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifStackController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewRenderer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotificationVisibilityProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RenderExtensions.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RootNodeController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/ViewPipeline.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/RemoteInputViewModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallFlags.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelStateListener.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserInfoTracker.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherFeatureController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiActivityModel.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/RemoteInput.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/SmartRepliesInflationModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
+-packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt
+-packages/SystemUI/src/com/android/systemui/toast/ToastLogger.kt
+-packages/SystemUI/src/com/android/systemui/tv/TVSystemUICoreStartableModule.kt
+-packages/SystemUI/src/com/android/systemui/unfold/FoldStateLogger.kt
+-packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
+-packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt
+-packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+-packages/SystemUI/src/com/android/systemui/unfold/UnfoldProgressProvider.kt
+-packages/SystemUI/src/com/android/systemui/user/UserCreator.kt
+-packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
+-packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
+-packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt
+-packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt
+-packages/SystemUI/src/com/android/systemui/util/ColorUtil.kt
+-packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
+-packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt
+-packages/SystemUI/src/com/android/systemui/util/DumpUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/InitializationChecker.kt
+-packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/ListenerSet.kt
+-packages/SystemUI/src/com/android/systemui/util/NeverExactlyLinearLayout.kt
+-packages/SystemUI/src/com/android/systemui/util/NoRemeasureMotionLayout.kt
+-packages/SystemUI/src/com/android/systemui/util/PluralMessageFormater.kt
+-packages/SystemUI/src/com/android/systemui/util/RingerModeTracker.kt
+-packages/SystemUI/src/com/android/systemui/util/RingerModeTrackerImpl.kt
+-packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt
+-packages/SystemUI/src/com/android/systemui/util/SafeMarqueeTextView.kt
+-packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/TraceUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/UserAwareController.kt
+-packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/MeasurementInput.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt
+-packages/SystemUI/src/com/android/systemui/util/collection/RingBuffer.kt
+-packages/SystemUI/src/com/android/systemui/util/concurrency/Execution.kt
+-packages/SystemUI/src/com/android/systemui/util/concurrency/PendingTasksContainer.kt
+-packages/SystemUI/src/com/android/systemui/util/drawable/DrawableSize.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/IpcSerializer.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt
+-packages/SystemUI/src/com/android/systemui/util/view/ViewUtil.kt
+-packages/SystemUI/src/com/android/systemui/util/wrapper/RotationPolicyWrapper.kt
+-packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt
+-packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt
+-packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardBiometricLockoutLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/clock/ClockPaletteTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/BootCompleteCacheTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/InstanceIdSequenceFake.kt
+-packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/PendingRemovalStoreTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/camera/CameraIntentsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/CustomIconCacheTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ServiceWrapperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/StatefulControlSubscriberTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/AllModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/lifecycle/InstantTaskExecutorRule.kt
+-packages/SystemUI/tests/src/com/android/systemui/log/LogBufferTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/AnimationBindHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaResumeListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MetadataAnimationHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SmartspaceMediaDataTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SquigglyProgressTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyChipBuilderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyConfigFlagsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/HeaderPrivacyIconsControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentDisableFlagsLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelSwitchToParentTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSSquishinessControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/SettingObserverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/carrier/CellSignalStateTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogEventLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/ResourceIconTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/ripple/RippleViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenshot/ImageCaptureImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplingInstanceTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/DisableFlagsLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/CommandRegistryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FoldStateListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryStateNotifierTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/VariableDateViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
+-packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/FakeSharedPreferencesTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/FloatingContentCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/ListenerSetTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/RingerModeLiveDataTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/animation/AnimationUtilTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/collection/RingBufferTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/drawable/DrawableSizeTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/kotlin/IpcSerializerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/view/ViewUtilTest.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/util/FakeSharedPreferences.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/util/mockito/KotlinMockitoHelpers.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/SizeScreenStatusProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBackground.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldMain.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
diff --git a/packages/SystemUI/res/layout/media_ttt_chip.xml b/packages/SystemUI/res/layout/media_ttt_chip.xml
index d886806..ae8e38e 100644
--- a/packages/SystemUI/res/layout/media_ttt_chip.xml
+++ b/packages/SystemUI/res/layout/media_ttt_chip.xml
@@ -16,7 +16,7 @@
 <!-- Wrap in a frame layout so that we can update the margins on the inner layout. (Since this view
      is the root view of a window, we cannot change the root view's margins.) -->
 <!-- Alphas start as 0 because the view will be animated in. -->
-<FrameLayout
+<com.android.systemui.media.taptotransfer.sender.MediaTttChipRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/media_ttt_sender_chip"
@@ -97,4 +97,4 @@
             />
 
     </LinearLayout>
-</FrameLayout>
+</com.android.systemui.media.taptotransfer.sender.MediaTttChipRootView>
diff --git a/packages/SystemUI/res/layout/volume_panel_dialog.xml b/packages/SystemUI/res/layout/volume_panel_dialog.xml
new file mode 100644
index 0000000..99a1b5c
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_panel_dialog.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2022 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/volume_panel_dialog"
+    android:layout_width="@dimen/large_dialog_width"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        style="@style/Widget.SliceView.Panel"
+        android:gravity="center_vertical|center_horizontal"
+        android:layout_marginTop="@dimen/dialog_top_padding"
+        android:layout_marginBottom="@dimen/dialog_bottom_padding"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/volume_panel_dialog_title"
+            android:ellipsize="end"
+            android:gravity="center_vertical|center_horizontal"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/sound_settings"
+            android:textAppearance="@style/TextAppearance.Dialog.Title"/>
+    </LinearLayout>
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/volume_panel_parent_layout"
+        android:scrollbars="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:minHeight="304dp"
+        android:layout_weight="1"
+        android:overScrollMode="never"/>
+
+    <LinearLayout
+        android:id="@+id/button_layout"
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/dialog_button_vertical_padding"
+        android:layout_marginStart="@dimen/dialog_side_padding"
+        android:layout_marginEnd="@dimen/dialog_side_padding"
+        android:layout_marginBottom="@dimen/dialog_bottom_padding"
+        android:baselineAligned="false"
+        android:clickable="false"
+        android:focusable="false">
+
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_gravity="start|center_vertical"
+            android:orientation="vertical">
+            <Button
+                android:id="@+id/settings_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/volume_panel_dialog_settings_button"
+                android:ellipsize="end"
+                android:maxLines="1"
+                style="@style/Widget.Dialog.Button.BorderButton"
+                android:clickable="true"
+                android:focusable="true"/>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/dialog_button_horizontal_padding"
+            android:layout_gravity="end|center_vertical">
+            <Button
+                android:id="@+id/done_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/inline_done_button"
+                style="@style/Widget.Dialog.Button"
+                android:maxLines="1"
+                android:ellipsize="end"
+                android:clickable="true"
+                android:focusable="true"/>
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/volume_panel_slice_slider_row.xml b/packages/SystemUI/res/layout/volume_panel_slice_slider_row.xml
new file mode 100644
index 0000000..d1303ed
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_panel_slice_slider_row.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2022 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/slice_slider_layout"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <androidx.slice.widget.SliceView
+        android:id="@+id/slice_view"
+        style="@style/Widget.SliceView.Panel.Slider"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingVertical="@dimen/volume_panel_slice_vertical_padding"
+        android:paddingHorizontal="@dimen/volume_panel_slice_horizontal_padding"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e34d422..a19145d 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -479,6 +479,10 @@
 
     <dimen name="volume_tool_tip_arrow_corner_radius">2dp</dimen>
 
+    <!-- Volume panel slices dimensions -->
+    <dimen name="volume_panel_slice_vertical_padding">8dp</dimen>
+    <dimen name="volume_panel_slice_horizontal_padding">24dp</dimen>
+
     <!-- Size of each item in the ringer selector drawer. -->
     <dimen name="volume_ringer_drawer_item_size">42dp</dimen>
     <dimen name="volume_ringer_drawer_item_size_half">21dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index bfdb170..c7b2ff3 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1139,6 +1139,11 @@
     <!-- Content description for accessibility: Hint if click will disable. [CHAR LIMIT=NONE] -->
     <string name="volume_odi_captions_hint_disable">disable</string>
 
+    <!-- Sound and vibration settings dialog title. [CHAR LIMIT=30] -->
+    <string name="sound_settings">Sound &amp; vibration</string>
+    <!-- Label for button to go to sound settings screen [CHAR_LIMIT=30] -->
+    <string name="volume_panel_dialog_settings_button">Settings</string>
+
     <!-- content description for audio output chooser [CHAR LIMIT=NONE]-->
 
     <!-- Screen pinning dialog title. -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index f7acf06..6d1bcbb 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -935,6 +935,10 @@
         <item name="rowStyle">@style/SliceRow</item>
     </style>
 
+    <style name="Widget.SliceView.Panel.Slider">
+        <item name="rowStyle">@style/SliceRow.Slider</item>
+    </style>
+
     <style name="SliceRow">
         <!-- 2dp start padding for the start icon -->
         <item name="titleItemStartPadding">2dp</item>
@@ -956,6 +960,26 @@
         <item name="actionDividerHeight">32dp</item>
     </style>
 
+    <style name="SliceRow.Slider">
+        <!-- Padding between content and the start icon is 5dp -->
+        <item name="contentStartPadding">5dp</item>
+        <item name="contentEndPadding">0dp</item>
+
+        <!-- 0dp start padding for the end item -->
+        <item name="endItemStartPadding">0dp</item>
+        <!-- 8dp end padding for the end item -->
+        <item name="endItemEndPadding">8dp</item>
+
+        <item name="titleSize">20sp</item>
+        <!-- Align text with slider -->
+        <item name="titleStartPadding">11dp</item>
+        <item name="subContentStartPadding">11dp</item>
+
+        <!-- Padding for indeterminate progress bar -->
+        <item name="progressBarStartPadding">12dp</item>
+        <item name="progressBarEndPadding">16dp</item>
+    </style>
+
     <style name="TextAppearance.Dialog.Title" parent="@android:style/TextAppearance.DeviceDefault.Large">
         <item name="android:textColor">?android:attr/textColorPrimary</item>
         <item name="android:textSize">24sp</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index e1957c0..93175e1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -418,6 +418,7 @@
             SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, state);
 
             getCurrentSecurityController().onResume(reason);
+            updateSideFpsVisibility();
         }
         mView.onResume(
                 mSecurityModel.getSecurityMode(KeyguardUpdateMonitor.getCurrentUser()),
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 282f251..6b3f134 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -19,6 +19,9 @@
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -599,7 +602,6 @@
             @Background DelayableExecutor bgExecutor) {
         super(context);
         mExecution = execution;
-        mWakefulnessLifecycle = wakefulnessLifecycle;
         mUserManager = userManager;
         mLockPatternUtils = lockPatternUtils;
         mHandler = handler;
@@ -625,11 +627,24 @@
                     return Unit.INSTANCE;
                 });
 
+        mWakefulnessLifecycle = wakefulnessLifecycle;
+        mWakefulnessLifecycle.addObserver(new WakefulnessLifecycle.Observer() {
+            @Override
+            public void onFinishedWakingUp() {
+                notifyDozeChanged(mStatusBarStateController.isDozing(), WAKEFULNESS_AWAKE);
+            }
+
+            @Override
+            public void onStartedGoingToSleep() {
+                notifyDozeChanged(mStatusBarStateController.isDozing(), WAKEFULNESS_GOING_TO_SLEEP);
+            }
+        });
+
         mStatusBarStateController = statusBarStateController;
         mStatusBarStateController.addCallback(new StatusBarStateController.StateListener() {
             @Override
             public void onDozingChanged(boolean isDozing) {
-                notifyDozeChanged(isDozing);
+                notifyDozeChanged(isDozing, wakefulnessLifecycle.getWakefulness());
             }
         });
 
@@ -738,13 +753,16 @@
     @Override
     public void setBiometicContextListener(IBiometricContextListener listener) {
         mBiometricContextListener = listener;
-        notifyDozeChanged(mStatusBarStateController.isDozing());
+        notifyDozeChanged(mStatusBarStateController.isDozing(),
+                mWakefulnessLifecycle.getWakefulness());
     }
 
-    private void notifyDozeChanged(boolean isDozing) {
+    private void notifyDozeChanged(boolean isDozing,
+            @WakefulnessLifecycle.Wakefulness int wakefullness) {
         if (mBiometricContextListener != null) {
             try {
-                mBiometricContextListener.onDozeChanged(isDozing);
+                final boolean isAwake = wakefullness == WAKEFULNESS_AWAKE;
+                mBiometricContextListener.onDozeChanged(isDozing, isAwake);
             } catch (RemoteException e) {
                 Log.w(TAG, "failed to notify initial doze state");
             }
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
index 4fe2dd8..e2ef247 100644
--- a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.ActivityIntentHelper
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.shade.NotificationPanelViewController
 import com.android.systemui.shared.system.ActivityManagerKt.isInForeground
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.phone.CentralSurfaces
@@ -117,7 +116,7 @@
                     )
                 } catch (e: RemoteException) {
                     Log.w(
-                        NotificationPanelViewController.TAG,
+                        "CameraGestureHelper",
                         "Unable to start camera activity",
                         e
                     )
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
index 8ba6f1c..d60a222 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
@@ -26,6 +26,7 @@
 import com.android.systemui.screenshot.ActionProxyReceiver;
 import com.android.systemui.screenshot.DeleteScreenshotReceiver;
 import com.android.systemui.screenshot.SmartActionsReceiver;
+import com.android.systemui.volume.VolumePanelDialogReceiver;
 
 import dagger.Binds;
 import dagger.Module;
@@ -78,6 +79,15 @@
      */
     @Binds
     @IntoMap
+    @ClassKey(VolumePanelDialogReceiver.class)
+    public abstract BroadcastReceiver bindVolumePanelDialogReceiver(
+            VolumePanelDialogReceiver broadcastReceiver);
+
+    /**
+     *
+     */
+    @Binds
+    @IntoMap
     @ClassKey(PeopleSpaceWidgetPinnedReceiver.class)
     public abstract BroadcastReceiver bindPeopleSpaceWidgetPinnedReceiver(
             PeopleSpaceWidgetPinnedReceiver broadcastReceiver);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
index 567bdbc..a981f25 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
@@ -70,11 +70,7 @@
                 new BcSmartspaceDataPlugin.SmartspaceTargetListener() {
             @Override
             public void onSmartspaceTargetsUpdated(List<? extends Parcelable> targets) {
-                if (!targets.isEmpty()) {
-                    mDreamOverlayStateController.addComplication(mComplication);
-                } else {
-                    mDreamOverlayStateController.removeComplication(mComplication);
-                }
+                mDreamOverlayStateController.addComplication(mComplication);
             }
         };
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
index 9e2b7c7..a3dc779 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
@@ -50,7 +50,6 @@
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
 
@@ -61,6 +60,7 @@
 import java.util.Set;
 
 import javax.inject.Inject;
+import javax.inject.Provider;
 
 /** */
 @SysUISingleton
@@ -106,6 +106,8 @@
 
     protected volatile Context mContext;
 
+    private final Provider<LocalBluetoothManager> mBluetoothManagerProvider;
+
     private boolean mEnabled;
     private String mKeyboardName;
     private CachedBluetoothDeviceManager mCachedDeviceManager;
@@ -122,8 +124,9 @@
     private int mState;
 
     @Inject
-    public KeyboardUI(Context context) {
+    public KeyboardUI(Context context, Provider<LocalBluetoothManager> bluetoothManagerProvider) {
         super(context);
+        this.mBluetoothManagerProvider = bluetoothManagerProvider;
     }
 
     @Override
@@ -181,7 +184,7 @@
             return;
         }
 
-        LocalBluetoothManager bluetoothManager = Dependency.get(LocalBluetoothManager.class);
+        LocalBluetoothManager bluetoothManager = mBluetoothManagerProvider.get();
         if (bluetoothManager == null)  {
             if (DEBUG) {
                 Slog.e(TAG, "Failed to retrieve LocalBluetoothManager instance");
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 012d766..b02393b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -488,8 +488,8 @@
         TextView deviceName = mMediaViewHolder.getSeamlessText();
         final MediaDeviceData device = data.getDevice();
 
-        final boolean enabled;
-        final boolean seamlessDisabled;
+        final boolean isTapEnabled;
+        final boolean useDisabledAlpha;
         final int iconResource;
         CharSequence deviceString;
         if (showBroadcastButton) {
@@ -499,21 +499,25 @@
                     && TextUtils.equals(device.getName(),
                     MediaDataUtils.getAppLabel(mContext, mPackageName, mContext.getString(
                             R.string.bt_le_audio_broadcast_dialog_unknown_name)));
-            seamlessDisabled = !mIsCurrentBroadcastedApp;
+            useDisabledAlpha = !mIsCurrentBroadcastedApp;
             // Always be enabled if the broadcast button is shown
-            enabled = true;
+            isTapEnabled = true;
+
+            // Defaults for broadcasting state
             deviceString = mContext.getString(R.string.bt_le_audio_broadcast_dialog_unknown_name);
             iconResource = R.drawable.settings_input_antenna;
         } else {
             // Disable clicking on output switcher for invalid devices and resumption controls
-            seamlessDisabled = (device != null && !device.getEnabled()) || data.getResumption();
-            enabled = !seamlessDisabled;
+            useDisabledAlpha = (device != null && !device.getEnabled()) || data.getResumption();
+            isTapEnabled = !useDisabledAlpha;
+
+            // Defaults for non-broadcasting state
             deviceString = mContext.getString(R.string.media_seamless_other_device);
             iconResource = R.drawable.ic_media_home_devices;
         }
 
-        mMediaViewHolder.getSeamlessButton().setAlpha(seamlessDisabled ? DISABLED_ALPHA : 1.0f);
-        seamlessView.setEnabled(enabled);
+        mMediaViewHolder.getSeamlessButton().setAlpha(useDisabledAlpha ? DISABLED_ALPHA : 1.0f);
+        seamlessView.setEnabled(isTapEnabled);
 
         if (device != null) {
             Drawable icon = device.getIcon();
@@ -524,7 +528,9 @@
             } else {
                 iconView.setImageDrawable(icon);
             }
-            deviceString = device.getName();
+            if (device.getName() != null) {
+                deviceString = device.getName();
+            }
         } else {
             // Set to default icon
             iconView.setImageResource(iconResource);
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 7b497ad..c48271e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -518,9 +518,20 @@
             }
             val actions = createActionsFromState(it.packageName,
                     mediaControllerFactory.create(it.token), UserHandle(it.userId))
-            val data = it.copy(
-                    semanticActions = actions,
-                    isPlaying = isPlayingState(state.state))
+
+            // Control buttons
+            // If flag is enabled and controller has a PlaybackState,
+            // create actions from session info
+            // otherwise, no need to update semantic actions.
+            val data = if (actions != null) {
+                it.copy(
+                        semanticActions = actions,
+                        isPlaying = isPlayingState(state.state))
+            } else {
+                it.copy(
+                        isPlaying = isPlayingState(state.state)
+                )
+            }
             if (DEBUG) Log.d(TAG, "State updated outside of notification")
             onMediaDataLoaded(key, key, data)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
index 2518659..b3a4ddf 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -348,7 +348,11 @@
 
                 // If we have a controller but get a null route, then don't trust the device
                 val enabled = device != null && (controller == null || route != null)
-                val name = route?.name?.toString() ?: device?.name
+                val name = if (controller == null || route != null) {
+                    route?.name?.toString() ?: device?.name
+                } else {
+                    null
+                }
                 current = MediaDeviceData(enabled, device?.iconWithoutBackground, name,
                         id = device?.id, showBroadcastButton = false)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
index a153cb6..f93c671 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
@@ -26,6 +26,7 @@
 import com.android.internal.statusbar.IUndoMediaTransferCallback
 import com.android.systemui.R
 import com.android.systemui.media.taptotransfer.common.DEFAULT_TIMEOUT_MILLIS
+import com.android.systemui.plugins.FalsingManager
 
 /**
  * A class enumerating all the possible states of the media tap-to-transfer chip on the sender
@@ -106,12 +107,15 @@
             controllerSender: MediaTttChipControllerSender,
             routeInfo: MediaRoute2Info,
             undoCallback: IUndoMediaTransferCallback?,
-            uiEventLogger: MediaTttSenderUiEventLogger
+            uiEventLogger: MediaTttSenderUiEventLogger,
+            falsingManager: FalsingManager,
         ): View.OnClickListener? {
             if (undoCallback == null) {
                 return null
             }
             return View.OnClickListener {
+                if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@OnClickListener
+
                 uiEventLogger.logUndoClicked(
                     MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED
                 )
@@ -141,12 +145,15 @@
             controllerSender: MediaTttChipControllerSender,
             routeInfo: MediaRoute2Info,
             undoCallback: IUndoMediaTransferCallback?,
-            uiEventLogger: MediaTttSenderUiEventLogger
+            uiEventLogger: MediaTttSenderUiEventLogger,
+            falsingManager: FalsingManager,
         ): View.OnClickListener? {
             if (undoCallback == null) {
                 return null
             }
             return View.OnClickListener {
+                if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@OnClickListener
+
                 uiEventLogger.logUndoClicked(
                     MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
                 )
@@ -212,7 +219,8 @@
         controllerSender: MediaTttChipControllerSender,
         routeInfo: MediaRoute2Info,
         undoCallback: IUndoMediaTransferCallback?,
-        uiEventLogger: MediaTttSenderUiEventLogger
+        uiEventLogger: MediaTttSenderUiEventLogger,
+        falsingManager: FalsingManager,
     ): View.OnClickListener? = null
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
index 9335489..5ad82fd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
@@ -22,21 +22,25 @@
 import android.os.PowerManager
 import android.util.Log
 import android.view.Gravity
+import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManager
 import android.view.accessibility.AccessibilityManager
 import android.widget.TextView
 import com.android.internal.statusbar.IUndoMediaTransferCallback
+import com.android.systemui.Gefingerpoken
 import com.android.systemui.R
 import com.android.systemui.animation.Interpolators
 import com.android.systemui.animation.ViewHierarchyAnimator
+import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.media.taptotransfer.common.ChipInfoCommon
 import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCommon
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.media.taptotransfer.common.MediaTttRemovalReason
+import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.concurrency.DelayableExecutor
@@ -58,7 +62,9 @@
         accessibilityManager: AccessibilityManager,
         configurationController: ConfigurationController,
         powerManager: PowerManager,
-        private val uiEventLogger: MediaTttSenderUiEventLogger
+        private val uiEventLogger: MediaTttSenderUiEventLogger,
+        private val falsingManager: FalsingManager,
+        private val falsingCollector: FalsingCollector,
 ) : MediaTttChipControllerCommon<ChipSenderInfo>(
         context,
         logger,
@@ -70,6 +76,9 @@
         powerManager,
         R.layout.media_ttt_chip,
 ) {
+
+    private lateinit var parent: MediaTttChipRootView
+
     override val windowLayoutParams = commonWindowLayoutParams.apply {
         gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
     }
@@ -121,6 +130,15 @@
 
         val chipState = newChipInfo.state
 
+        // Detect falsing touches on the chip.
+        parent = currentChipView as MediaTttChipRootView
+        parent.touchHandler = object : Gefingerpoken {
+            override fun onTouchEvent(ev: MotionEvent?): Boolean {
+                falsingCollector.onTouchEvent(ev)
+                return false
+            }
+        }
+
         // App icon
         val iconName = setIcon(currentChipView, newChipInfo.routeInfo.clientPackageName)
 
@@ -136,7 +154,11 @@
         // Undo
         val undoView = currentChipView.requireViewById<View>(R.id.undo)
         val undoClickListener = chipState.undoClickListener(
-                this, newChipInfo.routeInfo, newChipInfo.undoCallback, uiEventLogger
+                this,
+                newChipInfo.routeInfo,
+                newChipInfo.undoCallback,
+                uiEventLogger,
+                falsingManager,
         )
         undoView.setOnClickListener(undoClickListener)
         undoView.visibility = (undoClickListener != null).visibleIfTrue()
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt
new file mode 100644
index 0000000..3373159
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.taptotransfer.sender
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.widget.FrameLayout
+import com.android.systemui.Gefingerpoken
+
+/** A simple subclass that allows for observing touch events on chip. */
+class MediaTttChipRootView(
+        context: Context,
+        attrs: AttributeSet?
+) : FrameLayout(context, attrs) {
+
+    /** Assign this field to observe touch events. */
+    var touchHandler: Gefingerpoken? = null
+
+    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
+        touchHandler?.onTouchEvent(ev)
+        return super.dispatchTouchEvent(ev)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
index 3f93108..5da4809 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
@@ -17,7 +17,14 @@
 
 import javax.inject.Inject;
 
-/** */
+/**
+ * Plays a animation to reveal newly added QS tiles.
+ *
+ * The aniumation is played when the user fully opens Quick Settings, and is only shown for
+ * <li> tiles added automatically (not through user customization)
+ * <li> tiles not have been revealed before (memoized via {@code QS_TILE_SPECS_REVEALED}
+ * preference)
+ */
 public class QSTileRevealController {
     private static final long QS_REVEAL_TILES_DELAY = 500L;
 
@@ -39,6 +46,7 @@
             });
         }
     };
+
     QSTileRevealController(Context context, QSPanelController qsPanelController,
             PagedTileLayout pagedTileLayout, QSCustomizerController qsCustomizerController) {
         mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
index a918e5d..309059f 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.screenshot
 
 import android.graphics.Insets
+import android.util.Log
 import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
 import com.android.internal.util.ScreenshotHelper.HardwareBitmapBundler
 import com.android.internal.util.ScreenshotHelper.ScreenshotRequest
@@ -61,8 +62,9 @@
         ) {
 
             val info = policy.findPrimaryContent(policy.getDefaultDisplayId())
+            Log.d(TAG, "findPrimaryContent: $info")
 
-            result = if (policy.isManagedProfile(info.userId)) {
+            result = if (policy.isManagedProfile(info.user.identifier)) {
                 val image = capture.captureTask(info.taskId)
                     ?: error("Task snapshot returned a null Bitmap!")
 
@@ -70,7 +72,7 @@
                 ScreenshotRequest(
                     TAKE_SCREENSHOT_PROVIDED_IMAGE, request.source,
                     HardwareBitmapBundler.hardwareBitmapToBundle(image),
-                    info.bounds, Insets.NONE, info.taskId, info.userId, info.component
+                    info.bounds, Insets.NONE, info.taskId, info.user.identifier, info.component
                 )
             } else {
                 // Create a new request of the same type which includes the top component
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt
index 3580010..f73d204 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt
@@ -19,6 +19,7 @@
 import android.annotation.UserIdInt
 import android.content.ComponentName
 import android.graphics.Rect
+import android.os.UserHandle
 import android.view.Display
 
 /**
@@ -42,7 +43,7 @@
     data class DisplayContentInfo(
         val component: ComponentName,
         val bounds: Rect,
-        @UserIdInt val userId: Int,
+        val user: UserHandle,
         val taskId: Int,
     )
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt
index ba809f6..c2a5060 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt
@@ -29,9 +29,11 @@
 import android.graphics.Rect
 import android.os.Process
 import android.os.RemoteException
+import android.os.UserHandle
 import android.os.UserManager
 import android.util.Log
 import android.view.Display.DEFAULT_DISPLAY
+import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.infra.ServiceConnector
 import com.android.systemui.SystemUIService
 import com.android.systemui.dagger.SysUISingleton
@@ -45,21 +47,13 @@
 import kotlinx.coroutines.withContext
 
 @SysUISingleton
-internal class ScreenshotPolicyImpl @Inject constructor(
+internal open class ScreenshotPolicyImpl @Inject constructor(
     context: Context,
     private val userMgr: UserManager,
     private val atmService: IActivityTaskManager,
     @Background val bgDispatcher: CoroutineDispatcher,
 ) : ScreenshotPolicy {
 
-    private val systemUiContent =
-        DisplayContentInfo(
-            ComponentName(context, SystemUIService::class.java),
-            Rect(),
-            ActivityTaskManager.INVALID_TASK_ID,
-            Process.myUserHandle().identifier,
-        )
-
     private val proxyConnector: ServiceConnector<IScreenshotProxy> =
         ServiceConnector.Impl(
             context,
@@ -78,6 +72,9 @@
     }
 
     private fun nonPipVisibleTask(info: RootTaskInfo): Boolean {
+        if (DEBUG) {
+            debugLogRootTaskInfo(info)
+        }
         return info.windowingMode != WindowConfiguration.WINDOWING_MODE_PINNED &&
             info.isVisible &&
             info.isRunning &&
@@ -99,58 +96,46 @@
         }
 
         val taskInfoList = getAllRootTaskInfosOnDisplay(displayId)
-        if (DEBUG) {
-            debugLogRootTaskInfos(taskInfoList)
-        }
 
         // If no visible task is located, then report SystemUI as the foreground content
         val target = taskInfoList.firstOrNull(::nonPipVisibleTask) ?: return systemUiContent
-
-        val topActivity: ComponentName = target.topActivity ?: error("should not be null")
-        val topChildTask = target.childTaskIds.size - 1
-        val childTaskId = target.childTaskIds[topChildTask]
-        val childTaskUserId = target.childTaskUserIds[topChildTask]
-        val childTaskBounds = target.childTaskBounds[topChildTask]
-
-        return DisplayContentInfo(topActivity, childTaskBounds, childTaskId, childTaskUserId)
+        return target.toDisplayContentInfo()
     }
 
-    private fun debugLogRootTaskInfos(taskInfoList: List<RootTaskInfo>) {
-        for (info in taskInfoList) {
-            Log.d(
-                TAG,
-                "[root task info] " +
-                    "taskId=${info.taskId} " +
-                    "parentTaskId=${info.parentTaskId} " +
-                    "position=${info.position} " +
-                    "positionInParent=${info.positionInParent} " +
-                    "isVisible=${info.isVisible()} " +
-                    "visible=${info.visible} " +
-                    "isFocused=${info.isFocused} " +
-                    "isSleeping=${info.isSleeping} " +
-                    "isRunning=${info.isRunning} " +
-                    "windowMode=${windowingModeToString(info.windowingMode)} " +
-                    "activityType=${activityTypeToString(info.activityType)} " +
-                    "topActivity=${info.topActivity} " +
-                    "topActivityInfo=${info.topActivityInfo} " +
-                    "numActivities=${info.numActivities} " +
-                    "childTaskIds=${Arrays.toString(info.childTaskIds)} " +
-                    "childUserIds=${Arrays.toString(info.childTaskUserIds)} " +
-                    "childTaskBounds=${Arrays.toString(info.childTaskBounds)} " +
-                    "childTaskNames=${Arrays.toString(info.childTaskNames)}"
-            )
+    private fun debugLogRootTaskInfo(info: RootTaskInfo) {
+        Log.d(TAG, "RootTaskInfo={" +
+                "taskId=${info.taskId} " +
+                "parentTaskId=${info.parentTaskId} " +
+                "position=${info.position} " +
+                "positionInParent=${info.positionInParent} " +
+                "isVisible=${info.isVisible()} " +
+                "visible=${info.visible} " +
+                "isFocused=${info.isFocused} " +
+                "isSleeping=${info.isSleeping} " +
+                "isRunning=${info.isRunning} " +
+                "windowMode=${windowingModeToString(info.windowingMode)} " +
+                "activityType=${activityTypeToString(info.activityType)} " +
+                "topActivity=${info.topActivity} " +
+                "topActivityInfo=${info.topActivityInfo} " +
+                "numActivities=${info.numActivities} " +
+                "childTaskIds=${Arrays.toString(info.childTaskIds)} " +
+                "childUserIds=${Arrays.toString(info.childTaskUserIds)} " +
+                "childTaskBounds=${Arrays.toString(info.childTaskBounds)} " +
+                "childTaskNames=${Arrays.toString(info.childTaskNames)}" +
+                "}"
+        )
 
-            for (j in 0 until info.childTaskIds.size) {
-                Log.d(TAG, "    *** [$j] ******")
-                Log.d(TAG, "        ***  childTaskIds[$j]: ${info.childTaskIds[j]}")
-                Log.d(TAG, "        ***  childTaskUserIds[$j]: ${info.childTaskUserIds[j]}")
-                Log.d(TAG, "        ***  childTaskBounds[$j]: ${info.childTaskBounds[j]}")
-                Log.d(TAG, "        ***  childTaskNames[$j]: ${info.childTaskNames[j]}")
-            }
+        for (j in 0 until info.childTaskIds.size) {
+            Log.d(TAG, "    *** [$j] ******")
+            Log.d(TAG, "        ***  childTaskIds[$j]: ${info.childTaskIds[j]}")
+            Log.d(TAG, "        ***  childTaskUserIds[$j]: ${info.childTaskUserIds[j]}")
+            Log.d(TAG, "        ***  childTaskBounds[$j]: ${info.childTaskBounds[j]}")
+            Log.d(TAG, "        ***  childTaskNames[$j]: ${info.childTaskNames[j]}")
         }
     }
 
-    private suspend fun getAllRootTaskInfosOnDisplay(displayId: Int): List<RootTaskInfo> =
+    @VisibleForTesting
+    open suspend fun getAllRootTaskInfosOnDisplay(displayId: Int): List<RootTaskInfo> =
         withContext(bgDispatcher) {
             try {
                 atmService.getAllRootTaskInfosOnDisplay(displayId)
@@ -160,7 +145,8 @@
             }
         }
 
-    private suspend fun isNotificationShadeExpanded(): Boolean = suspendCoroutine { k ->
+    @VisibleForTesting
+    open suspend fun isNotificationShadeExpanded(): Boolean = suspendCoroutine { k ->
         proxyConnector
             .postForResult { it.isNotificationShadeExpanded }
             .whenComplete { expanded, error ->
@@ -171,8 +157,30 @@
             }
     }
 
-    companion object {
-        const val TAG: String = "ScreenshotPolicyImpl"
-        const val DEBUG: Boolean = false
-    }
+    @VisibleForTesting
+    internal val systemUiContent =
+        DisplayContentInfo(
+            ComponentName(context, SystemUIService::class.java),
+            Rect(),
+            Process.myUserHandle(),
+            ActivityTaskManager.INVALID_TASK_ID
+        )
+}
+
+private const val TAG: String = "ScreenshotPolicyImpl"
+private const val DEBUG: Boolean = false
+
+@VisibleForTesting
+internal fun RootTaskInfo.toDisplayContentInfo(): DisplayContentInfo {
+    val topActivity: ComponentName = topActivity ?: error("should not be null")
+    val topChildTask = childTaskIds.size - 1
+    val childTaskId = childTaskIds[topChildTask]
+    val childTaskUserId = childTaskUserIds[topChildTask]
+    val childTaskBounds = childTaskBounds[topChildTask]
+
+    return DisplayContentInfo(
+        topActivity,
+        childTaskBounds,
+        UserHandle.of(childTaskUserId),
+        childTaskId)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
index 9818af3..1cdacb9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
@@ -17,32 +17,30 @@
 package com.android.systemui.shade;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.FrameLayout;
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.TapAgainView;
 
-public class NotificationPanelView extends PanelView {
+/** The shade view. */
+public final class NotificationPanelView extends FrameLayout {
+    static final boolean DEBUG = false;
 
-    private static final boolean DEBUG = false;
-
-    /**
-     * Fling expanding QS.
-     */
-    public static final int FLING_EXPAND = 0;
-
-    public static final String COUNTER_PANEL_OPEN = "panel_open";
-    public static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
+    private final Paint mAlphaPaint = new Paint();
 
     private int mCurrentPanelAlpha;
-    private final Paint mAlphaPaint = new Paint();
     private boolean mDozing;
     private RtlChangeListener mRtlChangeListener;
+    private NotificationPanelViewController.TouchHandler mTouchHandler;
+    private OnConfigurationChangedListener mOnConfigurationChangedListener;
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -99,7 +97,36 @@
         return findViewById(R.id.shade_falsing_tap_again);
     }
 
+    /** Sets the touch handler for this view. */
+    public void setOnTouchListener(NotificationPanelViewController.TouchHandler touchHandler) {
+        super.setOnTouchListener(touchHandler);
+        mTouchHandler = touchHandler;
+    }
+
+    void setOnConfigurationChangedListener(OnConfigurationChangedListener listener) {
+        mOnConfigurationChangedListener = listener;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent event) {
+        return mTouchHandler.onInterceptTouchEvent(event);
+    }
+
+    @Override
+    public void dispatchConfigurationChanged(Configuration newConfig) {
+        super.dispatchConfigurationChanged(newConfig);
+        mOnConfigurationChangedListener.onConfigurationChanged(newConfig);
+    }
+
+    /** Callback for right-to-left setting changes. */
     interface RtlChangeListener {
+        /** Called when right-to-left setting changes. */
         void onRtlPropertielsChanged(int layoutDirection);
     }
+
+    /** Callback for config changes. */
+    interface OnConfigurationChangedListener {
+        /** Called when configuration changes. */
+        void onConfigurationChanged(Configuration newConfig);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 5f07f9f..9a8395c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -33,7 +33,7 @@
 import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
 import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
 import static com.android.systemui.classifier.Classifier.UNLOCK;
-import static com.android.systemui.shade.PanelView.DEBUG;
+import static com.android.systemui.shade.NotificationPanelView.DEBUG;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
@@ -248,7 +248,7 @@
 
 @CentralSurfacesComponent.CentralSurfacesScope
 public final class NotificationPanelViewController {
-    public static final String TAG = PanelView.class.getSimpleName();
+    public static final String TAG = "PanelView";
     public static final float FLING_MAX_LENGTH_SECONDS = 0.6f;
     public static final float FLING_SPEED_UP_FACTOR = 0.6f;
     public static final float FLING_CLOSING_MAX_LENGTH_SECONDS = 0.6f;
@@ -274,7 +274,7 @@
     /**
      * Fling expanding QS.
      */
-    private static final int FLING_EXPAND = 0;
+    public static final int FLING_EXPAND = 0;
 
     /**
      * Fling collapsing QS, potentially stopping when QS becomes QQS.
@@ -430,7 +430,8 @@
     private boolean mQsTracking;
 
     /**
-     * If set, the ongoing touch gesture might both trigger the expansion in {@link PanelView} and
+     * If set, the ongoing touch gesture might both trigger the expansion in {@link
+     * NotificationPanelView} and
      * the expansion for quick settings.
      */
     private boolean mConflictingQsExpansionGesture;
@@ -5405,13 +5406,13 @@
         return animator;
     }
 
-    /** Update the visibility of {@link PanelView} if necessary. */
+    /** Update the visibility of {@link NotificationPanelView} if necessary. */
     public void updateVisibility() {
         mView.setVisibility(shouldPanelBeVisible() ? VISIBLE : INVISIBLE);
     }
 
     /**
-     * Updates the panel expansion and {@link PanelView} visibility if necessary.
+     * Updates the panel expansion and {@link NotificationPanelView} visibility if necessary.
      *
      * TODO(b/200063118): Could public calls to this method be replaced with calls to
      *   {@link #updateVisibility()}? That would allow us to make this method private.
@@ -6170,7 +6171,7 @@
     }
 
     public class OnConfigurationChangedListener implements
-            PanelView.OnConfigurationChangedListener {
+            NotificationPanelView.OnConfigurationChangedListener {
         @Override
         public void onConfigurationChanged(Configuration newConfig) {
             loadDimens();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/PanelView.java b/packages/SystemUI/src/com/android/systemui/shade/PanelView.java
deleted file mode 100644
index 4349d81..0000000
--- a/packages/SystemUI/src/com/android/systemui/shade/PanelView.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.widget.FrameLayout;
-
-import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
-import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
-
-public abstract class PanelView extends FrameLayout {
-    public static final boolean DEBUG = false;
-    public static final String TAG = PanelView.class.getSimpleName();
-    private NotificationPanelViewController.TouchHandler mTouchHandler;
-
-    protected CentralSurfaces mCentralSurfaces;
-    protected HeadsUpManagerPhone mHeadsUpManager;
-
-    protected KeyguardBottomAreaView mKeyguardBottomArea;
-    private OnConfigurationChangedListener mOnConfigurationChangedListener;
-
-    public PanelView(Context context) {
-        super(context);
-    }
-
-    public PanelView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public PanelView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public void setOnTouchListener(NotificationPanelViewController.TouchHandler touchHandler) {
-        super.setOnTouchListener(touchHandler);
-        mTouchHandler = touchHandler;
-    }
-
-    public void setOnConfigurationChangedListener(OnConfigurationChangedListener listener) {
-        mOnConfigurationChangedListener = listener;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent event) {
-        return mTouchHandler.onInterceptTouchEvent(event);
-    }
-
-    @Override
-    public void dispatchConfigurationChanged(Configuration newConfig) {
-        super.dispatchConfigurationChanged(newConfig);
-        mOnConfigurationChangedListener.onConfigurationChanged(newConfig);
-    }
-
-    interface OnConfigurationChangedListener {
-        void onConfigurationChanged(Configuration newConfig);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
index b9684fc..3d161d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
@@ -24,6 +24,8 @@
 import android.view.View;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
@@ -73,6 +75,7 @@
     }
 
     @Override
+    @NonNull
     public ExpandableViewState createExpandableViewState() {
         return new EmptyShadeViewState();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
index 2ca1beb..7b49ecd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
@@ -1,7 +1,6 @@
 package com.android.systemui.statusbar
 
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.NotificationEntryManager
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
 import javax.inject.Inject
@@ -12,14 +11,12 @@
  */
 @SysUISingleton
 class NotificationInteractionTracker @Inject constructor(
-    private val clicker: NotificationClickNotifier,
-    private val entryManager: NotificationEntryManager
+    clicker: NotificationClickNotifier,
 ) : NotifCollectionListener, NotificationInteractionListener {
     private val interactions = mutableMapOf<String, Boolean>()
 
     init {
         clicker.addNotificationInteractionListener(this)
-        entryManager.addCollectionListener(this)
     }
 
     fun hasUserInteractedWith(key: String): Boolean {
@@ -38,5 +35,3 @@
         interactions[key] = true
     }
 }
-
-private const val TAG = "NotificationInteractionTracker"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 2214287..cea3deb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -29,6 +29,8 @@
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
+import androidx.annotation.NonNull;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.SystemBarUtils;
 import com.android.systemui.R;
@@ -153,6 +155,7 @@
     }
 
     @Override
+    @NonNull
     public ExpandableViewState createExpandableViewState() {
         return new ShelfState();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index 8cb18a0..59022c0f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -50,7 +50,6 @@
 import com.android.internal.messages.nano.SystemMessageProto;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.UiBackground;
@@ -76,20 +75,22 @@
     private final Executor mUiBgExecutor;
     private final ArraySet<Pair<String, Integer>> mCurrentNotifs = new ArraySet<>();
     private final CommandQueue mCommandQueue;
-    private KeyguardStateController mKeyguardStateController;
+    private final KeyguardStateController mKeyguardStateController;
 
     @Inject
-    public InstantAppNotifier(Context context, CommandQueue commandQueue,
-            @UiBackground Executor uiBgExecutor) {
+    public InstantAppNotifier(
+            Context context,
+            CommandQueue commandQueue,
+            @UiBackground Executor uiBgExecutor,
+            KeyguardStateController keyguardStateController) {
         super(context);
         mCommandQueue = commandQueue;
         mUiBgExecutor = uiBgExecutor;
+        mKeyguardStateController = keyguardStateController;
     }
 
     @Override
     public void start() {
-        mKeyguardStateController = Dependency.get(KeyguardStateController.class);
-
         // listen for user / profile change.
         try {
             ActivityManager.getService().registerUserSwitchObserver(mUserSwitchListener, TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
deleted file mode 100644
index c9c6f28..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification;
-
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-
-import java.util.Objects;
-
-/**
- * Root controller for the list of notifications in the shade.
- *
- * TODO: Much of the code in NotificationPresenter should eventually move in here. It will proxy
- * domain-specific behavior (ARC, etc) to subcontrollers.
- */
-public class NotificationListController {
-    private final NotificationEntryManager mEntryManager;
-    private final NotificationListContainer mListContainer;
-    private final DeviceProvisionedController mDeviceProvisionedController;
-
-    public NotificationListController(
-            NotificationEntryManager entryManager,
-            NotificationListContainer listContainer,
-            DeviceProvisionedController deviceProvisionedController) {
-        mEntryManager = Objects.requireNonNull(entryManager);
-        mListContainer = Objects.requireNonNull(listContainer);
-        mDeviceProvisionedController = Objects.requireNonNull(deviceProvisionedController);
-    }
-
-    /**
-     * Causes the controller to register listeners on its dependencies. This method must be called
-     * before the controller is ready to perform its duties.
-     */
-    public void bind() {
-        mEntryManager.addNotificationEntryListener(mEntryListener);
-        mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
-    }
-
-    @SuppressWarnings("FieldCanBeLocal")
-    private final NotificationEntryListener mEntryListener = new NotificationEntryListener() {
-        @Override
-        public void onEntryRemoved(
-                NotificationEntry entry,
-                NotificationVisibility visibility,
-                boolean removedByUser,
-                int reason) {
-            mListContainer.cleanUpViewStateForEntry(entry);
-        }
-    };
-
-    // TODO: (b/145659174) remove after moving to NewNotifPipeline. Replaced by
-    //  DeviceProvisionedCoordinator
-    private final DeviceProvisionedListener mDeviceProvisionedListener =
-            new DeviceProvisionedListener() {
-                @Override
-                public void onDeviceProvisionedChanged() {
-                    mEntryManager.updateNotifications("device provisioned changed");
-                }
-            };
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index dbf4810..126a986 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -18,10 +18,8 @@
 
 import android.animation.ObjectAnimator
 import android.util.FloatProperty
-import com.android.systemui.Dumpable
 import com.android.systemui.animation.Interpolators
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -34,20 +32,17 @@
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener
 import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
-import java.io.PrintWriter
 import javax.inject.Inject
 import kotlin.math.min
 
 @SysUISingleton
 class NotificationWakeUpCoordinator @Inject constructor(
-    dumpManager: DumpManager,
     private val mHeadsUpManager: HeadsUpManager,
     private val statusBarStateController: StatusBarStateController,
     private val bypassController: KeyguardBypassController,
     private val dozeParameters: DozeParameters,
     private val screenOffAnimationController: ScreenOffAnimationController
-) : OnHeadsUpChangedListener, StatusBarStateController.StateListener, PanelExpansionListener,
-    Dumpable {
+) : OnHeadsUpChangedListener, StatusBarStateController.StateListener, PanelExpansionListener {
 
     private val mNotificationVisibility = object : FloatProperty<NotificationWakeUpCoordinator>(
         "notificationVisibility") {
@@ -65,7 +60,6 @@
 
     private var mLinearDozeAmount: Float = 0.0f
     private var mDozeAmount: Float = 0.0f
-    private var mDozeAmountSource: String = "init"
     private var mNotificationVisibleAmount = 0.0f
     private var mNotificationsVisible = false
     private var mNotificationsVisibleForExpansion = false
@@ -148,7 +142,6 @@
         }
 
     init {
-        dumpManager.registerDumpable(this)
         mHeadsUpManager.addListener(this)
         statusBarStateController.addCallback(this)
         addListener(object : WakeUpListener {
@@ -255,14 +248,13 @@
             // Let's notify the scroller that an animation started
             notifyAnimationStart(mLinearDozeAmount == 1.0f)
         }
-        setDozeAmount(linear, eased, source = "StatusBar")
+        setDozeAmount(linear, eased)
     }
 
-    fun setDozeAmount(linear: Float, eased: Float, source: String) {
+    fun setDozeAmount(linear: Float, eased: Float) {
         val changed = linear != mLinearDozeAmount
         mLinearDozeAmount = linear
         mDozeAmount = eased
-        mDozeAmountSource = source
         mStackScrollerController.setDozeAmount(mDozeAmount)
         updateHideAmount()
         if (changed && linear == 0.0f) {
@@ -279,7 +271,7 @@
             // undefined state, so it's an indication that we should do state cleanup. We override
             // the doze amount to 0f (not dozing) so that the notifications are no longer hidden.
             // See: UnlockedScreenOffAnimationController.onFinishedWakingUp()
-            setDozeAmount(0f, 0f, source = "Override: Shade->Shade (lock cancelled by unlock)")
+            setDozeAmount(0f, 0f)
         }
 
         if (overrideDozeAmountIfAnimatingScreenOff(mLinearDozeAmount)) {
@@ -319,11 +311,12 @@
      */
     private fun overrideDozeAmountIfBypass(): Boolean {
         if (bypassController.bypassEnabled) {
-            if (statusBarStateController.state == StatusBarState.KEYGUARD) {
-                setDozeAmount(1f, 1f, source = "Override: bypass (keyguard)")
-            } else {
-                setDozeAmount(0f, 0f, source = "Override: bypass (shade)")
+            var amount = 1.0f
+            if (statusBarStateController.state == StatusBarState.SHADE ||
+                statusBarStateController.state == StatusBarState.SHADE_LOCKED) {
+                amount = 0.0f
             }
+            setDozeAmount(amount, amount)
             return true
         }
         return false
@@ -339,7 +332,7 @@
      */
     private fun overrideDozeAmountIfAnimatingScreenOff(linearDozeAmount: Float): Boolean {
         if (screenOffAnimationController.overrideNotificationsFullyDozingOnKeyguard()) {
-            setDozeAmount(1f, 1f, source = "Override: animating screen off")
+            setDozeAmount(1f, 1f)
             return true
         }
 
@@ -433,24 +426,4 @@
          */
         @JvmDefault fun onPulseExpansionChanged(expandingChanged: Boolean) {}
     }
-
-    override fun dump(pw: PrintWriter, args: Array<out String>) {
-        pw.println("mLinearDozeAmount: $mLinearDozeAmount")
-        pw.println("mDozeAmount: $mDozeAmount")
-        pw.println("mDozeAmountSource: $mDozeAmountSource")
-        pw.println("mNotificationVisibleAmount: $mNotificationVisibleAmount")
-        pw.println("mNotificationsVisible: $mNotificationsVisible")
-        pw.println("mNotificationsVisibleForExpansion: $mNotificationsVisibleForExpansion")
-        pw.println("mVisibilityAmount: $mVisibilityAmount")
-        pw.println("mLinearVisibilityAmount: $mLinearVisibilityAmount")
-        pw.println("pulseExpanding: $pulseExpanding")
-        pw.println("state: ${StatusBarState.toString(state)}")
-        pw.println("fullyAwake: $fullyAwake")
-        pw.println("wakingUp: $wakingUp")
-        pw.println("willWakeUp: $willWakeUp")
-        pw.println("collapsedEnoughToHide: $collapsedEnoughToHide")
-        pw.println("pulsing: $pulsing")
-        pw.println("notificationsFullyHidden: $notificationsFullyHidden")
-        pw.println("canShowPulsingHuns: $canShowPulsingHuns")
-    }
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 385fbb5..be9f133 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -27,20 +27,20 @@
 import com.android.systemui.statusbar.notification.NotificationActivityStarter
 import com.android.systemui.statusbar.notification.NotificationClicker
 import com.android.systemui.statusbar.notification.NotificationEntryManager
-import com.android.systemui.statusbar.notification.NotificationListController
 import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.TargetSdkResolver
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl
 import com.android.systemui.statusbar.notification.collection.init.NotifPipelineInitializer
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
 import com.android.systemui.statusbar.notification.collection.render.NotifStackController
 import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder
 import com.android.systemui.statusbar.notification.logging.NotificationLogger
 import com.android.systemui.statusbar.notification.row.NotifBindPipelineInitializer
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.phone.CentralSurfaces
-import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.wm.shell.bubbles.Bubbles
 import dagger.Lazy
 import java.io.PrintWriter
@@ -65,7 +65,6 @@
     private val notifPipelineInitializer: Lazy<NotifPipelineInitializer>,
     private val notifBindPipelineInitializer: NotifBindPipelineInitializer,
     private val notificationLogger: NotificationLogger,
-    private val deviceProvisionedController: DeviceProvisionedController,
     private val notificationRowBinder: NotificationRowBinderImpl,
     private val notificationsMediaManager: NotificationMediaManager,
     private val headsUpViewBinder: HeadsUpViewBinder,
@@ -85,12 +84,11 @@
     ) {
         notificationListener.registerAsSystemService()
 
-        val listController =
-                NotificationListController(
-                        entryManager,
-                        listContainer,
-                        deviceProvisionedController)
-        listController.bind()
+        notifPipeline.get().addCollectionListener(object : NotifCollectionListener {
+            override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
+                listContainer.cleanUpViewStateForEntry(entry)
+            }
+        })
 
         notificationRowBinder.setNotificationClicker(
                 clickerBuilder.build(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 855390d..8574f87 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -25,8 +25,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -68,6 +66,9 @@
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -3247,6 +3248,7 @@
     }
 
     @Override
+    @NonNull
     public ExpandableViewState createExpandableViewState() {
         return new NotificationViewState();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 8f73b80..1e09b8a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -29,6 +29,7 @@
 import android.view.ViewParent;
 import android.widget.FrameLayout;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.systemui.Dumpable;
@@ -66,7 +67,7 @@
     protected float mContentTransformationAmount;
     protected boolean mIsLastChild;
     protected int mContentShift;
-    private final ExpandableViewState mViewState;
+    @NonNull private final ExpandableViewState mViewState;
     private float mContentTranslation;
     protected boolean mLastInSection;
     protected boolean mFirstInSection;
@@ -610,6 +611,7 @@
 
     public void setActualHeightAnimating(boolean animating) {}
 
+    @NonNull
     protected ExpandableViewState createExpandableViewState() {
         return new ExpandableViewState();
     }
@@ -642,7 +644,12 @@
         return mViewState;
     }
 
-    @Nullable public ExpandableViewState getViewState() {
+    /**
+     * Get the {@link ExpandableViewState} associated with the view.
+     *
+     * @return the ExpandableView's view state.
+     */
+    @NonNull public ExpandableViewState getViewState() {
         return mViewState;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index e43ecf7..49dc655 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -23,6 +23,8 @@
 import android.util.IndentingPrintWriter;
 import android.view.View;
 
+import androidx.annotation.NonNull;
+
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.ViewState;
@@ -142,6 +144,7 @@
     }
 
     @Override
+    @NonNull
     public ExpandableViewState createExpandableViewState() {
         return new FooterViewState();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index cc87499..1fb265f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -4460,8 +4460,7 @@
     }
 
     private void updateVisibility() {
-        boolean shouldShow = !mAmbientState.isFullyHidden() || !onKeyguard();
-        setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
+        mController.updateVisibility(!mAmbientState.isFullyHidden() || !onKeyguard());
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4526,17 +4525,21 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    void updateEmptyShadeView(boolean visible, boolean notifVisibleInShade) {
+    void updateEmptyShadeView(boolean visible, boolean areNotificationsHiddenInShade) {
         mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
 
         int oldTextRes = mEmptyShadeView.getTextResource();
-        int newTextRes = notifVisibleInShade
+        int newTextRes = areNotificationsHiddenInShade
                 ? R.string.dnd_suppressing_shade_text : R.string.empty_shade_text;
         if (oldTextRes != newTextRes) {
             mEmptyShadeView.setText(newTextRes);
         }
     }
 
+    public boolean isEmptyShadeViewVisible() {
+        return mEmptyShadeView.isVisible();
+    }
+
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void updateFooterView(boolean visible, boolean showDismissView, boolean showHistory) {
         if (mFooterView == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index e6eceb5..ec1e620 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -177,7 +177,6 @@
     private NotificationStackScrollLayout mView;
     private boolean mFadeNotificationsOnDismiss;
     private NotificationSwipeHelper mSwipeHelper;
-    private boolean mShowEmptyShadeView;
     @Nullable private Boolean mHistoryEnabled;
     private int mBarState;
     private HeadsUpAppearanceController mHeadsUpAppearanceController;
@@ -1173,8 +1172,21 @@
     }
 
     /**
-     * Update whether we should show the empty shade view (no notifications in the shade).
-     * If so, send the update to our view.
+     * Set the visibility of the view, and propagate it to specific children.
+     *
+     * @param visible either the view is visible or not.
+     */
+    public void updateVisibility(boolean visible) {
+        mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+
+        if (mView.getVisibility() == View.VISIBLE) {
+            // Synchronize EmptyShadeView visibility with the parent container.
+            updateShowEmptyShadeView();
+        }
+    }
+
+    /**
+     * Update whether we should show the empty shade view ("no notifications" in the shade).
      *
      * When in split mode, notifications are always visible regardless of the state of the
      * QuickSettings panel. That being the case, empty view is always shown if the other conditions
@@ -1182,18 +1194,31 @@
      */
     public void updateShowEmptyShadeView() {
         Trace.beginSection("NSSLC.updateShowEmptyShadeView");
-        mShowEmptyShadeView = mStatusBarStateController.getCurrentOrUpcomingState() != KEYGUARD
-                && !mView.isQsFullScreen()
-                && getVisibleNotificationCount() == 0;
 
-        mView.updateEmptyShadeView(
-                mShowEmptyShadeView,
-                mZenModeController.areNotificationsHiddenInShade());
+        final boolean shouldShow = getVisibleNotificationCount() == 0
+                && !mView.isQsFullScreen()
+                // Hide empty shade view when in transition to Keyguard.
+                // That avoids "No Notifications" to blink when transitioning to AOD.
+                // For more details, see: b/228790482
+                && !isInTransitionToKeyguard();
+
+        mView.updateEmptyShadeView(shouldShow, mZenModeController.areNotificationsHiddenInShade());
+
         Trace.endSection();
     }
 
+    /**
+     * @return true if {@link StatusBarStateController} is in transition to the KEYGUARD
+     *         and false otherwise.
+     */
+    private boolean isInTransitionToKeyguard() {
+        final int currentState = mStatusBarStateController.getState();
+        final int upcomingState = mStatusBarStateController.getCurrentOrUpcomingState();
+        return (currentState != upcomingState && upcomingState == KEYGUARD);
+    }
+
     public boolean isShowingEmptyShadeView() {
-        return mShowEmptyShadeView;
+        return mView.isEmptyShadeViewVisible();
     }
 
     public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 6d513d0da..353355b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -120,11 +120,64 @@
         updateClipping(algorithmState, ambientState);
         updateSpeedBumpState(algorithmState, speedBumpIndex);
         updateShelfState(algorithmState, ambientState);
+        updateAlphaState(algorithmState, ambientState);
         getNotificationChildrenStates(algorithmState, ambientState);
     }
 
+    private void updateAlphaState(StackScrollAlgorithmState algorithmState,
+            AmbientState ambientState) {
+        for (ExpandableView view : algorithmState.visibleChildren) {
+            final ViewState viewState = view.getViewState();
+
+            final boolean isHunGoingToShade = ambientState.isShadeExpanded()
+                    && view == ambientState.getTrackedHeadsUpRow();
+
+            if (isHunGoingToShade) {
+                // Keep 100% opacity for heads up notification going to shade.
+                viewState.alpha = 1f;
+            } else if (ambientState.isOnKeyguard()) {
+                // Adjust alpha for wakeup to lockscreen.
+                viewState.alpha = 1f - ambientState.getHideAmount();
+            } else if (ambientState.isExpansionChanging()) {
+                // Adjust alpha for shade open & close.
+                float expansion = ambientState.getExpansionFraction();
+                viewState.alpha = ambientState.isBouncerInTransit()
+                        ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion)
+                        : ShadeInterpolation.getContentAlpha(expansion);
+            }
+
+            // For EmptyShadeView if on keyguard, we need to control the alpha to create
+            // a nice transition when the user is dragging down the notification panel.
+            if (view instanceof EmptyShadeView && ambientState.isOnKeyguard()) {
+                final float fractionToShade = ambientState.getFractionToShade();
+                viewState.alpha = ShadeInterpolation.getContentAlpha(fractionToShade);
+            }
+
+            NotificationShelf shelf = ambientState.getShelf();
+            if (shelf != null) {
+                final ViewState shelfState = shelf.getViewState();
+
+                // After the shelf has updated its yTranslation, explicitly set alpha=0 for view
+                // below shelf to skip rendering them in the hardware layer. We do not set them
+                // invisible because that runs invalidate & onDraw when these views return onscreen,
+                // which is more expensive.
+                if (shelfState.hidden) {
+                    // When the shelf is hidden, it won't clip views, so we don't hide rows
+                    return;
+                }
+
+                final float shelfTop = shelfState.yTranslation;
+                final float viewTop = viewState.yTranslation;
+                if (viewTop >= shelfTop) {
+                    viewState.alpha = 0;
+                }
+            }
+        }
+    }
+
     /**
      * How expanded or collapsed notifications are when pulling down the shade.
+     *
      * @param ambientState Current ambient state.
      * @return 0 when fully collapsed, 1 when expanded.
      */
@@ -208,22 +261,6 @@
         }
 
         shelf.updateState(algorithmState, ambientState);
-
-        // After the shelf has updated its yTranslation, explicitly set alpha=0 for view below shelf
-        // to skip rendering them in the hardware layer. We do not set them invisible because that
-        // runs invalidate & onDraw when these views return onscreen, which is more expensive.
-        if (shelf.getViewState().hidden) {
-            // When the shelf is hidden, it won't clip views, so we don't hide rows
-            return;
-        }
-        final float shelfTop = shelf.getViewState().yTranslation;
-
-        for (ExpandableView view : algorithmState.visibleChildren) {
-            final float viewTop = view.getViewState().yTranslation;
-            if (viewTop >= shelfTop) {
-                view.getViewState().alpha = 0;
-            }
-        }
     }
 
     private void updateClipping(StackScrollAlgorithmState algorithmState,
@@ -473,21 +510,6 @@
         ExpandableViewState viewState = view.getViewState();
         viewState.location = ExpandableViewState.LOCATION_UNKNOWN;
 
-        final boolean isHunGoingToShade = ambientState.isShadeExpanded()
-                && view == ambientState.getTrackedHeadsUpRow();
-        if (isHunGoingToShade) {
-            // Keep 100% opacity for heads up notification going to shade.
-        } else if (ambientState.isOnKeyguard()) {
-            // Adjust alpha for wakeup to lockscreen.
-            viewState.alpha = 1f - ambientState.getHideAmount();
-        } else if (ambientState.isExpansionChanging()) {
-            // Adjust alpha for shade open & close.
-            float expansion = ambientState.getExpansionFraction();
-            viewState.alpha = ambientState.isBouncerInTransit()
-                    ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion)
-                    : ShadeInterpolation.getContentAlpha(expansion);
-        }
-
         final float expansionFraction = getExpansionFractionWithoutShelf(
                 algorithmState, ambientState);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 747c4de..52a45d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -55,7 +55,6 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.qs.QSPanelController;
-import com.android.systemui.shade.NotificationPanelView;
 import com.android.systemui.shade.NotificationPanelViewController;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -326,12 +325,12 @@
                 mNotificationPanelViewController.expand(true /* animate */);
                 mNotificationStackScrollLayoutController.setWillExpand(true);
                 mHeadsUpManager.unpinAll(true /* userUnpinned */);
-                mMetricsLogger.count(NotificationPanelView.COUNTER_PANEL_OPEN, 1);
+                mMetricsLogger.count("panel_open", 1);
             } else if (!mNotificationPanelViewController.isInSettings()
                     && !mNotificationPanelViewController.isExpanding()) {
                 mNotificationPanelViewController.flingSettings(0 /* velocity */,
-                        NotificationPanelView.FLING_EXPAND);
-                mMetricsLogger.count(NotificationPanelView.COUNTER_PANEL_OPEN_QS, 1);
+                        NotificationPanelViewController.FLING_EXPAND);
+                mMetricsLogger.count("panel_open_qs", 1);
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index ed186ab..8273d57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -33,7 +33,6 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.demomode.DemoModeCommandReceiver;
@@ -137,11 +136,12 @@
                 LinearLayout linearLayout,
                 FeatureFlags featureFlags,
                 StatusBarPipelineFlags statusBarPipelineFlags,
-                Provider<WifiViewModel> wifiViewModelProvider) {
+                Provider<WifiViewModel> wifiViewModelProvider,
+                DarkIconDispatcher darkIconDispatcher) {
             super(linearLayout, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
             mIconHPadding = mContext.getResources().getDimensionPixelSize(
                     R.dimen.status_bar_icon_padding);
-            mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
+            mDarkIconDispatcher = darkIconDispatcher;
         }
 
         @Override
@@ -198,20 +198,24 @@
             private final FeatureFlags mFeatureFlags;
             private final StatusBarPipelineFlags mStatusBarPipelineFlags;
             private final Provider<WifiViewModel> mWifiViewModelProvider;
+            private final DarkIconDispatcher mDarkIconDispatcher;
 
             @Inject
             public Factory(
                     FeatureFlags featureFlags,
                     StatusBarPipelineFlags statusBarPipelineFlags,
-                    Provider<WifiViewModel> wifiViewModelProvider) {
+                    Provider<WifiViewModel> wifiViewModelProvider,
+                    DarkIconDispatcher darkIconDispatcher) {
                 mFeatureFlags = featureFlags;
                 mStatusBarPipelineFlags = statusBarPipelineFlags;
                 mWifiViewModelProvider = wifiViewModelProvider;
+                mDarkIconDispatcher = darkIconDispatcher;
             }
 
             public DarkIconManager create(LinearLayout group) {
                 return new DarkIconManager(
-                        group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider);
+                        group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider,
+                        mDarkIconDispatcher);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
index 7765427..103f3fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
@@ -46,7 +46,7 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.stateIn
 
 /**
  * Provides data related to the wifi state.
@@ -118,12 +118,19 @@
             }
         }
 
-        trySend(WIFI_NETWORK_DEFAULT)
         connectivityManager.registerNetworkCallback(WIFI_NETWORK_CALLBACK_REQUEST, callback)
 
         awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
     }
-        .shareIn(scope, started = SharingStarted.WhileSubscribed())
+        // There will be multiple wifi icons in different places that will frequently
+        // subscribe/unsubscribe to flows as the views attach/detach. Using [stateIn] ensures that
+        // new subscribes will get the latest value immediately upon subscription. Otherwise, the
+        // views could show stale data. See b/244173280.
+        .stateIn(
+            scope,
+            started = SharingStarted.WhileSubscribed(),
+            initialValue = WIFI_NETWORK_DEFAULT
+        )
 
     override val wifiActivity: Flow<WifiActivityModel> =
             if (wifiManager == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 13c3df3..c7ba518 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -48,7 +48,6 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -248,6 +247,7 @@
 
     private final ConfigurationController mConfigurationController;
     private final MediaOutputDialogFactory mMediaOutputDialogFactory;
+    private final VolumePanelFactory mVolumePanelFactory;
     private final ActivityStarter mActivityStarter;
 
     private boolean mShowing;
@@ -279,6 +279,7 @@
             DeviceProvisionedController deviceProvisionedController,
             ConfigurationController configurationController,
             MediaOutputDialogFactory mediaOutputDialogFactory,
+            VolumePanelFactory volumePanelFactory,
             ActivityStarter activityStarter,
             InteractionJankMonitor interactionJankMonitor) {
         mContext =
@@ -290,6 +291,7 @@
         mDeviceProvisionedController = deviceProvisionedController;
         mConfigurationController = configurationController;
         mMediaOutputDialogFactory = mediaOutputDialogFactory;
+        mVolumePanelFactory = volumePanelFactory;
         mActivityStarter = activityStarter;
         mShowActiveStreamOnly = showActiveStreamOnly();
         mHasSeenODICaptionsTooltip =
@@ -1045,10 +1047,9 @@
         if (mSettingsIcon != null) {
             mSettingsIcon.setOnClickListener(v -> {
                 Events.writeEvent(Events.EVENT_SETTINGS_CLICK);
-                Intent intent = new Intent(Settings.Panel.ACTION_VOLUME);
                 dismissH(DISMISS_REASON_SETTINGS_CLICKED);
                 mMediaOutputDialogFactory.dismiss();
-                mActivityStarter.startActivity(intent, true /* dismissShade */);
+                mVolumePanelFactory.create(true /* aboveStatusBar */, null);
             });
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java
new file mode 100644
index 0000000..2c74fb9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+import android.provider.SettingsSlicesContract;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
+import androidx.lifecycle.LiveData;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.slice.Slice;
+import androidx.slice.SliceMetadata;
+import androidx.slice.widget.EventInfo;
+import androidx.slice.widget.SliceLiveData;
+
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.BluetoothUtils;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.settingslib.media.MediaOutputConstants;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Visual presentation of the volume panel dialog.
+ */
+public class VolumePanelDialog extends SystemUIDialog implements LifecycleOwner {
+    private static final String TAG = "VolumePanelDialog";
+
+    private static final int DURATION_SLICE_BINDING_TIMEOUT_MS = 200;
+    private static final int DEFAULT_SLICE_SIZE = 4;
+
+    private RecyclerView mVolumePanelSlices;
+    private VolumePanelSlicesAdapter mVolumePanelSlicesAdapter;
+    private final LifecycleRegistry mLifecycleRegistry;
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+    private final Map<Uri, LiveData<Slice>> mSliceLiveData = new LinkedHashMap<>();
+    private final HashSet<Uri> mLoadedSlices = new HashSet<>();
+    private boolean mSlicesReadyToLoad;
+    private LocalBluetoothProfileManager mProfileManager;
+
+    public VolumePanelDialog(Context context, boolean aboveStatusBar) {
+        super(context);
+        mLifecycleRegistry = new LifecycleRegistry(this);
+        if (!aboveStatusBar) {
+            getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.d(TAG, "onCreate");
+
+        View dialogView = LayoutInflater.from(getContext()).inflate(R.layout.volume_panel_dialog,
+                null);
+        final Window window = getWindow();
+        window.setContentView(dialogView);
+
+        Button doneButton = dialogView.findViewById(R.id.done_button);
+        doneButton.setOnClickListener(v -> dismiss());
+        Button settingsButton = dialogView.findViewById(R.id.settings_button);
+        settingsButton.setOnClickListener(v -> {
+            getContext().startActivity(new Intent(Settings.ACTION_SOUND_SETTINGS).addFlags(
+                    Intent.FLAG_ACTIVITY_NEW_TASK));
+            dismiss();
+        });
+
+        LocalBluetoothManager localBluetoothManager = LocalBluetoothManager.getInstance(
+                getContext(), null);
+        if (localBluetoothManager != null) {
+            mProfileManager = localBluetoothManager.getProfileManager();
+        }
+
+        mVolumePanelSlices = dialogView.findViewById(R.id.volume_panel_parent_layout);
+        mVolumePanelSlices.setLayoutManager(new LinearLayoutManager(getContext()));
+
+        loadAllSlices();
+
+        mLifecycleRegistry.setCurrentState(Lifecycle.State.CREATED);
+    }
+
+    private void loadAllSlices() {
+        mSliceLiveData.clear();
+        mLoadedSlices.clear();
+        final List<Uri> sliceUris = getSlices();
+
+        for (Uri uri : sliceUris) {
+            final LiveData<Slice> sliceLiveData = SliceLiveData.fromUri(getContext(), uri,
+                    (int type, Throwable source) -> {
+                        if (!removeSliceLiveData(uri)) {
+                            mLoadedSlices.add(uri);
+                        }
+                    });
+
+            // Add slice first to make it in order.  Will remove it later if there's an error.
+            mSliceLiveData.put(uri, sliceLiveData);
+
+            sliceLiveData.observe(this, slice -> {
+                if (mLoadedSlices.contains(uri)) {
+                    return;
+                }
+                Log.d(TAG, "received slice: " + (slice == null ? null : slice.getUri()));
+                final SliceMetadata metadata = SliceMetadata.from(getContext(), slice);
+                if (slice == null || metadata.isErrorSlice()) {
+                    if (!removeSliceLiveData(uri)) {
+                        mLoadedSlices.add(uri);
+                    }
+                } else if (metadata.getLoadingState() == SliceMetadata.LOADED_ALL) {
+                    mLoadedSlices.add(uri);
+                } else {
+                    mHandler.postDelayed(() -> {
+                        mLoadedSlices.add(uri);
+                        setupAdapterWhenReady();
+                    }, DURATION_SLICE_BINDING_TIMEOUT_MS);
+                }
+
+                setupAdapterWhenReady();
+            });
+        }
+    }
+
+    private void setupAdapterWhenReady() {
+        if (mLoadedSlices.size() == mSliceLiveData.size() && !mSlicesReadyToLoad) {
+            mSlicesReadyToLoad = true;
+            mVolumePanelSlicesAdapter = new VolumePanelSlicesAdapter(this, mSliceLiveData);
+            mVolumePanelSlicesAdapter.setOnSliceActionListener((eventInfo, sliceItem) -> {
+                if (eventInfo.actionType == EventInfo.ACTION_TYPE_SLIDER) {
+                    return;
+                }
+                this.dismiss();
+            });
+            if (mSliceLiveData.size() < DEFAULT_SLICE_SIZE) {
+                mVolumePanelSlices.setMinimumHeight(0);
+            }
+            mVolumePanelSlices.setAdapter(mVolumePanelSlicesAdapter);
+        }
+    }
+
+    private boolean removeSliceLiveData(Uri uri) {
+        boolean removed = false;
+        // Keeps observe media output slice
+        if (!uri.equals(MEDIA_OUTPUT_INDICATOR_SLICE_URI)) {
+            Log.d(TAG, "remove uri: " + uri);
+            removed = mSliceLiveData.remove(uri) != null;
+            if (mVolumePanelSlicesAdapter != null) {
+                mVolumePanelSlicesAdapter.updateDataSet(new ArrayList<>(mSliceLiveData.values()));
+            }
+        }
+        return removed;
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        Log.d(TAG, "onStart");
+        mLifecycleRegistry.setCurrentState(Lifecycle.State.STARTED);
+        mLifecycleRegistry.setCurrentState(Lifecycle.State.RESUMED);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        Log.d(TAG, "onStop");
+        mLifecycleRegistry.setCurrentState(Lifecycle.State.DESTROYED);
+    }
+
+    private List<Uri> getSlices() {
+        final List<Uri> uris = new ArrayList<>();
+        uris.add(REMOTE_MEDIA_SLICE_URI);
+        uris.add(VOLUME_MEDIA_URI);
+        Uri controlUri = getExtraControlUri();
+        if (controlUri != null) {
+            Log.d(TAG, "add extra control slice");
+            uris.add(controlUri);
+        }
+        uris.add(MEDIA_OUTPUT_INDICATOR_SLICE_URI);
+        uris.add(VOLUME_CALL_URI);
+        uris.add(VOLUME_RINGER_URI);
+        uris.add(VOLUME_ALARM_URI);
+        return uris;
+    }
+
+    private static final String SETTINGS_SLICE_AUTHORITY = "com.android.settings.slices";
+    private static final Uri REMOTE_MEDIA_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SETTINGS_SLICE_AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath(MediaOutputConstants.KEY_REMOTE_MEDIA)
+            .build();
+    private static final Uri VOLUME_MEDIA_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SETTINGS_SLICE_AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath("media_volume")
+            .build();
+    private static final Uri MEDIA_OUTPUT_INDICATOR_SLICE_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SETTINGS_SLICE_AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_INTENT)
+            .appendPath("media_output_indicator")
+            .build();
+    private static final Uri VOLUME_CALL_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SETTINGS_SLICE_AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath("call_volume")
+            .build();
+    private static final Uri VOLUME_RINGER_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SETTINGS_SLICE_AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath("ring_volume")
+            .build();
+    private static final Uri VOLUME_ALARM_URI = new Uri.Builder()
+            .scheme(ContentResolver.SCHEME_CONTENT)
+            .authority(SETTINGS_SLICE_AUTHORITY)
+            .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+            .appendPath("alarm_volume")
+            .build();
+
+    private Uri getExtraControlUri() {
+        Uri controlUri = null;
+        final BluetoothDevice bluetoothDevice = findActiveDevice();
+        if (bluetoothDevice != null) {
+            // The control slice width = dialog width - horizontal padding of two sides
+            final int dialogWidth =
+                    getWindow().getWindowManager().getCurrentWindowMetrics().getBounds().width();
+            final int controlSliceWidth = dialogWidth
+                    - getContext().getResources().getDimensionPixelSize(
+                    R.dimen.volume_panel_slice_horizontal_padding) * 2;
+            final String uri = BluetoothUtils.getControlUriMetaData(bluetoothDevice);
+            if (!TextUtils.isEmpty(uri)) {
+                try {
+                    controlUri = Uri.parse(uri + controlSliceWidth);
+                } catch (NullPointerException exception) {
+                    Log.d(TAG, "unable to parse extra control uri");
+                    controlUri = null;
+                }
+            }
+        }
+        return controlUri;
+    }
+
+    private BluetoothDevice findActiveDevice() {
+        if (mProfileManager != null) {
+            final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+            if (a2dpProfile != null) {
+                return a2dpProfile.getActiveDevice();
+            }
+        }
+        return null;
+    }
+
+    @NonNull
+    @Override
+    public Lifecycle getLifecycle() {
+        return mLifecycleRegistry;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt
new file mode 100644
index 0000000..f11d5d1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.provider.Settings
+import android.text.TextUtils
+import android.util.Log
+import javax.inject.Inject
+
+private const val TAG = "VolumePanelDialogReceiver"
+private const val LAUNCH_ACTION = "com.android.systemui.action.LAUNCH_VOLUME_PANEL_DIALOG"
+private const val DISMISS_ACTION = "com.android.systemui.action.DISMISS_VOLUME_PANEL_DIALOG"
+
+/**
+ * BroadcastReceiver for handling volume panel dialog intent
+ */
+class VolumePanelDialogReceiver @Inject constructor(
+    private val volumePanelFactory: VolumePanelFactory
+) : BroadcastReceiver() {
+    override fun onReceive(context: Context, intent: Intent) {
+        Log.d(TAG, "onReceive intent" + intent.action)
+        if (TextUtils.equals(LAUNCH_ACTION, intent.action) ||
+                TextUtils.equals(Settings.Panel.ACTION_VOLUME, intent.action)) {
+            volumePanelFactory.create(true, null)
+        } else if (TextUtils.equals(DISMISS_ACTION, intent.action)) {
+            volumePanelFactory.dismiss()
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt
new file mode 100644
index 0000000..c2fafbf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume
+
+import android.content.Context
+import android.util.Log
+import android.view.View
+import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+private const val TAG = "VolumePanelFactory"
+private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
+
+/**
+ * Factory to create [VolumePanelDialog] objects. This is the dialog that allows the user to adjust
+ * multiple streams with sliders.
+ */
+@SysUISingleton
+class VolumePanelFactory @Inject constructor(
+    private val context: Context,
+    private val dialogLaunchAnimator: DialogLaunchAnimator
+) {
+    companion object {
+        var volumePanelDialog: VolumePanelDialog? = null
+    }
+
+    /** Creates a [VolumePanelDialog]. The dialog will be animated from [view] if it is not null. */
+    fun create(aboveStatusBar: Boolean, view: View? = null) {
+        if (volumePanelDialog?.isShowing == true) {
+            return
+        }
+
+        val dialog = VolumePanelDialog(context, aboveStatusBar)
+        volumePanelDialog = dialog
+
+        // Show the dialog.
+        if (view != null) {
+            dialogLaunchAnimator.showFromView(dialog, view, animateBackgroundBoundsChange = true)
+        } else {
+            dialog.show()
+        }
+    }
+
+    /** Dismiss [VolumePanelDialog] if exist. */
+    fun dismiss() {
+        if (DEBUG) {
+            Log.d(TAG, "dismiss dialog")
+        }
+        volumePanelDialog?.dismiss()
+        volumePanelDialog = null
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java
new file mode 100644
index 0000000..2371402
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume;
+
+import static android.app.slice.Slice.HINT_ERROR;
+import static android.app.slice.SliceItem.FORMAT_SLICE;
+
+import android.content.Context;
+import android.net.Uri;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LiveData;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.slice.Slice;
+import androidx.slice.SliceItem;
+import androidx.slice.widget.SliceView;
+
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * RecyclerView adapter for Slices in Settings Panels.
+ */
+public class VolumePanelSlicesAdapter extends
+        RecyclerView.Adapter<VolumePanelSlicesAdapter.SliceRowViewHolder> {
+
+    private final List<LiveData<Slice>> mSliceLiveData;
+    private final LifecycleOwner mLifecycleOwner;
+    private SliceView.OnSliceActionListener mOnSliceActionListener;
+
+    public VolumePanelSlicesAdapter(LifecycleOwner lifecycleOwner,
+            Map<Uri, LiveData<Slice>> sliceLiveData) {
+        mLifecycleOwner = lifecycleOwner;
+        mSliceLiveData = new ArrayList<>(sliceLiveData.values());
+    }
+
+    @NonNull
+    @Override
+    public SliceRowViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
+        final Context context = viewGroup.getContext();
+        final LayoutInflater inflater = LayoutInflater.from(context);
+        View view = inflater.inflate(R.layout.volume_panel_slice_slider_row, viewGroup, false);
+        return new SliceRowViewHolder(view);
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull SliceRowViewHolder sliceRowViewHolder, int position) {
+        sliceRowViewHolder.onBind(mSliceLiveData.get(position), position);
+    }
+
+    @Override
+    public int getItemCount() {
+        return mSliceLiveData.size();
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return position;
+    }
+
+    void setOnSliceActionListener(SliceView.OnSliceActionListener listener) {
+        mOnSliceActionListener = listener;
+    }
+
+    void updateDataSet(ArrayList<LiveData<Slice>> list) {
+        mSliceLiveData.clear();
+        mSliceLiveData.addAll(list);
+        notifyDataSetChanged();
+    }
+
+    /**
+     * ViewHolder for binding Slices to SliceViews.
+     */
+    public class SliceRowViewHolder extends RecyclerView.ViewHolder {
+
+        private final SliceView mSliceView;
+
+        public SliceRowViewHolder(View view) {
+            super(view);
+            mSliceView = view.findViewById(R.id.slice_view);
+            mSliceView.setMode(SliceView.MODE_LARGE);
+            mSliceView.setShowTitleItems(true);
+            mSliceView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+            mSliceView.setOnSliceActionListener(mOnSliceActionListener);
+        }
+
+        /**
+         * Called when the view is displayed.
+         */
+        public void onBind(LiveData<Slice> sliceLiveData, int position) {
+            sliceLiveData.observe(mLifecycleOwner, mSliceView);
+
+            // Do not show the divider above media devices switcher slice per request
+            final Slice slice = sliceLiveData.getValue();
+
+            // Hides slice which reports with error hint or not contain any slice sub-item.
+            if (slice == null || !isValidSlice(slice)) {
+                mSliceView.setVisibility(View.GONE);
+            } else {
+                mSliceView.setVisibility(View.VISIBLE);
+            }
+        }
+
+        private boolean isValidSlice(Slice slice) {
+            if (slice.getHints().contains(HINT_ERROR)) {
+                return false;
+            }
+            for (SliceItem item : slice.getItems()) {
+                if (item.getFormat().equals(FORMAT_SLICE)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
index f3855bd..c5792b9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
@@ -30,6 +30,7 @@
 import com.android.systemui.volume.VolumeComponent;
 import com.android.systemui.volume.VolumeDialogComponent;
 import com.android.systemui.volume.VolumeDialogImpl;
+import com.android.systemui.volume.VolumePanelFactory;
 
 import dagger.Binds;
 import dagger.Module;
@@ -52,6 +53,7 @@
             DeviceProvisionedController deviceProvisionedController,
             ConfigurationController configurationController,
             MediaOutputDialogFactory mediaOutputDialogFactory,
+            VolumePanelFactory volumePanelFactory,
             ActivityStarter activityStarter,
             InteractionJankMonitor interactionJankMonitor) {
         VolumeDialogImpl impl = new VolumeDialogImpl(
@@ -61,6 +63,7 @@
                 deviceProvisionedController,
                 configurationController,
                 mediaOutputDialogFactory,
+                volumePanelFactory,
                 activityStarter,
                 interactionJankMonitor);
         impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index aecec9d..d68e8bd 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -387,6 +387,33 @@
     }
 
     @Test
+    public void onResume_sideFpsHintShouldBeShown_sideFpsHintShown() {
+        setupGetSecurityView();
+        setupConditionsToEnableSideFpsHint();
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+        reset(mSidefpsController);
+
+        mKeyguardSecurityContainerController.onResume(0);
+
+        verify(mSidefpsController).show();
+        verify(mSidefpsController, never()).hide();
+    }
+
+    @Test
+    public void onResume_sideFpsHintShouldNotBeShown_sideFpsHintHidden() {
+        setupGetSecurityView();
+        setupConditionsToEnableSideFpsHint();
+        setSideFpsHintEnabledFromResources(false);
+        mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+        reset(mSidefpsController);
+
+        mKeyguardSecurityContainerController.onResume(0);
+
+        verify(mSidefpsController).hide();
+        verify(mSidefpsController, never()).show();
+    }
+
+    @Test
     public void showNextSecurityScreenOrFinish_setsSecurityScreenToPinAfterSimPinUnlock() {
         // GIVEN the current security method is SimPin
         when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index e0d1f7a..b18b0ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -20,6 +20,8 @@
 import static android.hardware.biometrics.BiometricManager.Authenticators;
 import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE;
 
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static junit.framework.Assert.assertEquals;
@@ -157,13 +159,15 @@
     @Mock
     private InteractionJankMonitor mInteractionJankMonitor;
     @Captor
-    ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mFpAuthenticatorsRegisteredCaptor;
+    private ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mFpAuthenticatorsRegisteredCaptor;
     @Captor
-    ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mFaceAuthenticatorsRegisteredCaptor;
+    private ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mFaceAuthenticatorsRegisteredCaptor;
     @Captor
-    ArgumentCaptor<BiometricStateListener> mBiometricStateCaptor;
+    private ArgumentCaptor<BiometricStateListener> mBiometricStateCaptor;
     @Captor
-    ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
+    private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
+    @Captor
+    private ArgumentCaptor<WakefulnessLifecycle.Observer> mWakefullnessObserverCaptor;
 
     private TestableContext mContextSpy;
     private Execution mExecution;
@@ -242,7 +246,9 @@
                 mFaceAuthenticatorsRegisteredCaptor.capture());
 
         when(mStatusBarStateController.isDozing()).thenReturn(false);
+        when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
         verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
+        verify(mWakefulnessLifecycle).addObserver(mWakefullnessObserverCaptor.capture());
 
         mFpAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(fpProps);
         mFaceAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(faceProps);
@@ -759,16 +765,37 @@
     }
 
     @Test
-    public void testForwardsDozeEvent() throws RemoteException {
+    public void testForwardsDozeEvents() throws RemoteException {
+        when(mStatusBarStateController.isDozing()).thenReturn(true);
+        when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
         mAuthController.setBiometicContextListener(mContextListener);
 
-        mStatusBarStateListenerCaptor.getValue().onDozingChanged(false);
         mStatusBarStateListenerCaptor.getValue().onDozingChanged(true);
+        mStatusBarStateListenerCaptor.getValue().onDozingChanged(false);
 
         InOrder order = inOrder(mContextListener);
-        // invoked twice since the initial state is false
-        order.verify(mContextListener, times(2)).onDozeChanged(eq(false));
-        order.verify(mContextListener).onDozeChanged(eq(true));
+        order.verify(mContextListener, times(2)).onDozeChanged(eq(true), eq(true));
+        order.verify(mContextListener).onDozeChanged(eq(false), eq(true));
+        order.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void testForwardsWakeEvents() throws RemoteException {
+        when(mStatusBarStateController.isDozing()).thenReturn(false);
+        when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
+        mAuthController.setBiometicContextListener(mContextListener);
+
+        mWakefullnessObserverCaptor.getValue().onStartedGoingToSleep();
+        mWakefullnessObserverCaptor.getValue().onFinishedGoingToSleep();
+        mWakefullnessObserverCaptor.getValue().onStartedWakingUp();
+        mWakefullnessObserverCaptor.getValue().onFinishedWakingUp();
+        mWakefullnessObserverCaptor.getValue().onPostFinishedWakingUp();
+
+        InOrder order = inOrder(mContextListener);
+        order.verify(mContextListener).onDozeChanged(eq(false), eq(true));
+        order.verify(mContextListener).onDozeChanged(eq(false), eq(false));
+        order.verify(mContextListener).onDozeChanged(eq(false), eq(true));
+        order.verifyNoMoreInteractions();
     }
 
     // Helpers
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
index 7d54758..fa8f88a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
@@ -43,7 +43,7 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-import java.util.Arrays;
+import java.util.Collections;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -61,9 +61,6 @@
     private SmartSpaceComplication mComplication;
 
     @Mock
-    private ComplicationViewModel mComplicationViewModel;
-
-    @Mock
     private View mBcSmartspaceView;
 
     @Before
@@ -125,12 +122,12 @@
 
         // Test
         final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
-        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
+        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Collections.singletonList(target));
         verify(mDreamOverlayStateController).addComplication(eq(mComplication));
     }
 
     @Test
-    public void testOverlayActive_targetsEmpty_removesComplication() {
+    public void testOverlayActive_targetsEmpty_addsComplication() {
         final SmartSpaceComplication.Registrant registrant = getRegistrant();
         registrant.start();
 
@@ -145,13 +142,9 @@
                 ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
         verify(mSmartspaceController).addListener(listenerCaptor.capture());
 
-        final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
-        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
-        verify(mDreamOverlayStateController).addComplication(eq(mComplication));
-
         // Test
-        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList());
-        verify(mDreamOverlayStateController).removeComplication(eq(mComplication));
+        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Collections.emptyList());
+        verify(mDreamOverlayStateController).addComplication(eq(mComplication));
     }
 
     @Test
@@ -170,8 +163,7 @@
                 ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
         verify(mSmartspaceController).addListener(listenerCaptor.capture());
 
-        final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
-        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
+        listenerCaptor.getValue().onSmartspaceTargetsUpdated(Collections.emptyList());
         verify(mDreamOverlayStateController).addComplication(eq(mComplication));
 
         // Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index 1785022..bef4695 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -1051,6 +1051,17 @@
     }
 
     @Test
+    fun bindDeviceWithNullName() {
+        val fallbackString = context.getResources().getString(R.string.media_seamless_other_device)
+        player.attachPlayer(viewHolder)
+        val state = mediaData.copy(device = device.copy(name = null))
+        player.bindPlayer(state, PACKAGE)
+        assertThat(seamless.isEnabled()).isTrue()
+        assertThat(seamlessText.getText()).isEqualTo(fallbackString)
+        assertThat(seamless.contentDescription).isEqualTo(fallbackString)
+    }
+
+    @Test
     fun bindDeviceResumptionPlayer() {
         player.attachPlayer(viewHolder)
         val state = mediaData.copy(resumption = true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index d1ed8e9..f9c7d2d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.tuner.TunerService
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
@@ -108,6 +107,7 @@
     private val clock = FakeSystemClock()
     @Mock private lateinit var tunerService: TunerService
     @Captor lateinit var tunableCaptor: ArgumentCaptor<TunerService.Tunable>
+    @Captor lateinit var callbackCaptor: ArgumentCaptor<(String, PlaybackState) -> Unit>
 
     private val instanceIdSequence = InstanceIdSequenceFake(1 shl 20)
 
@@ -974,7 +974,6 @@
     fun testPlaybackStateChange_keyExists_callsListener() {
         // Notification has been added
         addNotificationAndLoad()
-        val callbackCaptor = argumentCaptor<(String, PlaybackState) -> Unit>()
         verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
 
         // Callback gets an updated state
@@ -992,7 +991,6 @@
     @Test
     fun testPlaybackStateChange_keyDoesNotExist_doesNothing() {
         val state = PlaybackState.Builder().build()
-        val callbackCaptor = argumentCaptor<(String, PlaybackState) -> Unit>()
         verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
 
         // No media added with this key
@@ -1013,7 +1011,6 @@
 
         // And then get a state update
         val state = PlaybackState.Builder().build()
-        val callbackCaptor = argumentCaptor<(String, PlaybackState) -> Unit>()
         verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
 
         // Then no changes are made
@@ -1022,6 +1019,83 @@
             anyBoolean())
     }
 
+    @Test
+    fun testPlaybackState_PauseWhenFlagTrue_keyExists_callsListener() {
+        whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(true)
+        val state = PlaybackState.Builder()
+                .setState(PlaybackState.STATE_PAUSED, 0L, 1f)
+                .build()
+        whenever(controller.playbackState).thenReturn(state)
+
+        addNotificationAndLoad()
+        verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
+        callbackCaptor.value.invoke(KEY, state)
+
+        verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY),
+                capture(mediaDataCaptor), eq(true), eq(0), eq(false))
+        assertThat(mediaDataCaptor.value.isPlaying).isFalse()
+        assertThat(mediaDataCaptor.value.semanticActions).isNotNull()
+    }
+
+    @Test
+    fun testPlaybackState_PauseStateAfterAddingResumption_keyExists_callsListener() {
+        val desc = MediaDescription.Builder().run {
+            setTitle(SESSION_TITLE)
+            build()
+        }
+        val state = PlaybackState.Builder()
+                .setState(PlaybackState.STATE_PAUSED, 0L, 1f)
+                .setActions(PlaybackState.ACTION_PLAY_PAUSE)
+                .build()
+
+        // Add resumption controls in order to have semantic actions.
+        // To make sure that they are not null after changing state.
+        mediaDataManager.addResumptionControls(
+                USER_ID,
+                desc,
+                Runnable {},
+                session.sessionToken,
+                APP_NAME,
+                pendingIntent,
+                PACKAGE_NAME
+        )
+        backgroundExecutor.runAllReady()
+        foregroundExecutor.runAllReady()
+
+        verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
+        callbackCaptor.value.invoke(PACKAGE_NAME, state)
+
+        verify(listener)
+                .onMediaDataLoaded(
+                        eq(PACKAGE_NAME),
+                        eq(PACKAGE_NAME),
+                        capture(mediaDataCaptor),
+                        eq(true),
+                        eq(0),
+                        eq(false)
+                )
+        assertThat(mediaDataCaptor.value.isPlaying).isFalse()
+        assertThat(mediaDataCaptor.value.semanticActions).isNotNull()
+    }
+
+    @Test
+    fun testPlaybackStateNull_Pause_keyExists_callsListener() {
+        whenever(controller.playbackState).thenReturn(null)
+        val state = PlaybackState.Builder()
+                .setState(PlaybackState.STATE_PAUSED, 0L, 1f)
+                .setActions(PlaybackState.ACTION_PLAY_PAUSE)
+                .build()
+
+        addNotificationAndLoad()
+        verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
+        callbackCaptor.value.invoke(KEY, state)
+
+        verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY),
+                capture(mediaDataCaptor), eq(true), eq(0), eq(false))
+        assertThat(mediaDataCaptor.value.isPlaying).isFalse()
+        assertThat(mediaDataCaptor.value.semanticActions).isNull()
+    }
+
     /**
      * Helper function to add a media notification and capture the resulting MediaData
      */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
index ee10426..121c894 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
@@ -59,8 +59,8 @@
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
-import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
 
 private const val KEY = "TEST_KEY"
 private const val KEY_OLD = "TEST_KEY_OLD"
@@ -402,9 +402,10 @@
         manager.onMediaDataLoaded(KEY, null, mediaData)
         fakeBgExecutor.runAllReady()
         fakeFgExecutor.runAllReady()
-        // THEN the device is disabled
+        // THEN the device is disabled and name is set to null
         val data = captureDeviceData(KEY)
         assertThat(data.enabled).isFalse()
+        assertThat(data.name).isNull()
     }
 
     @Test
@@ -421,9 +422,10 @@
         deviceCallback.onSelectedDeviceStateChanged(device, 1)
         fakeBgExecutor.runAllReady()
         fakeFgExecutor.runAllReady()
-        // THEN the device is disabled
+        // THEN the device is disabled and name is set to null
         val data = captureDeviceData(KEY)
         assertThat(data.enabled).isFalse()
+        assertThat(data.name).isNull()
     }
 
     @Test
@@ -440,9 +442,24 @@
         deviceCallback.onDeviceListUpdate(mutableListOf(device))
         fakeBgExecutor.runAllReady()
         fakeFgExecutor.runAllReady()
-        // THEN the device is disabled
+        // THEN the device is disabled and name is set to null
         val data = captureDeviceData(KEY)
         assertThat(data.enabled).isFalse()
+        assertThat(data.name).isNull()
+    }
+
+    @Test
+    fun mr2ReturnsRouteWithNullName_useLocalDeviceName() {
+        // GIVEN that MR2Manager returns a routing session that does not have a name
+        whenever(route.name).thenReturn(null)
+        // WHEN a notification is added
+        manager.onMediaDataLoaded(KEY, null, mediaData)
+        fakeBgExecutor.runAllReady()
+        fakeFgExecutor.runAllReady()
+        // THEN the device is enabled and uses the current connected device name
+        val data = captureDeviceData(KEY)
+        assertThat(data.name).isEqualTo(DEVICE_NAME)
+        assertThat(data.enabled).isTrue()
     }
 
     @Test
@@ -647,12 +664,14 @@
             override fun onPlaybackStopped(reason: Int, broadcastId: Int) {}
             override fun onBroadcastUpdated(reason: Int, broadcastId: Int) {}
             override fun onBroadcastUpdateFailed(reason: Int, broadcastId: Int) {}
-            override fun onBroadcastMetadataChanged(broadcastId: Int,
-                                                    metadata: BluetoothLeBroadcastMetadata) {}
+            override fun onBroadcastMetadataChanged(
+                broadcastId: Int,
+                metadata: BluetoothLeBroadcastMetadata
+            ) {}
         }
 
         bluetoothLeBroadcast.registerCallback(fakeFgExecutor, callback)
-        return callback;
+        return callback
     }
 
     fun setupLeAudioConfiguration(isLeAudio: Boolean) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
index 1061e3c..fa47a74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
@@ -35,7 +35,9 @@
 import com.android.internal.statusbar.IUndoMediaTransferCallback
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.media.taptotransfer.common.MediaTttLogger
+import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -48,11 +50,12 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -78,6 +81,10 @@
     private lateinit var viewUtil: ViewUtil
     @Mock
     private lateinit var commandQueue: CommandQueue
+    @Mock
+    private lateinit var falsingManager: FalsingManager
+    @Mock
+    private lateinit var falsingCollector: FalsingCollector
     private lateinit var commandQueueCallback: CommandQueue.Callbacks
     private lateinit var fakeAppIconDrawable: Drawable
     private lateinit var fakeClock: FakeSystemClock
@@ -115,7 +122,9 @@
             accessibilityManager,
             configurationController,
             powerManager,
-            senderUiEventLogger
+            senderUiEventLogger,
+            falsingManager,
+            falsingCollector
         )
 
         val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
@@ -421,6 +430,38 @@
     }
 
     @Test
+    fun transferToReceiverSucceeded_withUndoRunnable_falseTap_callbackNotRun() {
+        whenever(falsingManager.isFalseTap(anyInt())).thenReturn(true)
+        var undoCallbackCalled = false
+        val undoCallback = object : IUndoMediaTransferCallback.Stub() {
+            override fun onUndoTriggered() {
+                undoCallbackCalled = true
+            }
+        }
+
+        controllerSender.displayChip(transferToReceiverSucceeded(undoCallback))
+        getChipView().getUndoButton().performClick()
+
+        assertThat(undoCallbackCalled).isFalse()
+    }
+
+    @Test
+    fun transferToReceiverSucceeded_withUndoRunnable_realTap_callbackRun() {
+        whenever(falsingManager.isFalseTap(anyInt())).thenReturn(false)
+        var undoCallbackCalled = false
+        val undoCallback = object : IUndoMediaTransferCallback.Stub() {
+            override fun onUndoTriggered() {
+                undoCallbackCalled = true
+            }
+        }
+
+        controllerSender.displayChip(transferToReceiverSucceeded(undoCallback))
+        getChipView().getUndoButton().performClick()
+
+        assertThat(undoCallbackCalled).isTrue()
+    }
+
+    @Test
     fun transferToReceiverSucceeded_undoButtonClick_switchesToTransferToThisDeviceTriggered() {
         val undoCallback = object : IUndoMediaTransferCallback.Stub() {
             override fun onUndoTriggered() {}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
index 48fbd35..073c23c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
@@ -23,6 +23,7 @@
 import android.graphics.Rect
 import android.hardware.HardwareBuffer
 import android.os.Bundle
+import android.os.UserHandle
 import android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD
 import android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER
 import android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN
@@ -97,7 +98,7 @@
         policy.setManagedProfile(USER_ID, false)
         policy.setDisplayContentInfo(
             policy.getDefaultDisplayId(),
-            DisplayContentInfo(component, bounds, USER_ID, TASK_ID))
+            DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID))
 
         val request = ScreenshotRequest(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD)
         val processor = RequestProcessor(imageCapture, policy, flags, scope)
@@ -120,7 +121,7 @@
         // Indicate that the primary content belongs to a manged profile
         policy.setManagedProfile(USER_ID, true)
         policy.setDisplayContentInfo(policy.getDefaultDisplayId(),
-            DisplayContentInfo(component, bounds, USER_ID, TASK_ID))
+            DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID))
 
         val request = ScreenshotRequest(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD)
         val processor = RequestProcessor(imageCapture, policy, flags, scope)
@@ -160,7 +161,7 @@
 
         policy.setManagedProfile(USER_ID, false)
         policy.setDisplayContentInfo(policy.getDefaultDisplayId(),
-            DisplayContentInfo(component, bounds, USER_ID, TASK_ID))
+            DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID))
 
         val processedRequest = processor.process(request)
 
@@ -183,7 +184,7 @@
         // Indicate that the primary content belongs to a manged profile
         policy.setManagedProfile(USER_ID, true)
         policy.setDisplayContentInfo(policy.getDefaultDisplayId(),
-            DisplayContentInfo(component, bounds, USER_ID, TASK_ID))
+            DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID))
 
         val processedRequest = processor.process(request)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt
new file mode 100644
index 0000000..17396b1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot
+
+import android.app.ActivityTaskManager.RootTaskInfo
+import android.app.IActivityTaskManager
+import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
+import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
+import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED
+import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.app.WindowConfiguration.WINDOWING_MODE_PINNED
+import android.content.ComponentName
+import android.content.Context
+import android.graphics.Rect
+import android.os.UserHandle
+import android.os.UserManager
+import android.testing.AndroidTestingRunner
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.screenshot.ScreenshotPolicy.DisplayContentInfo
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.junit.runner.RunWith
+
+// The following values are chosen to be distinct from commonly seen real values
+private const val DISPLAY_ID = 100
+private const val PRIMARY_USER = 2000
+private const val MANAGED_PROFILE_USER = 3000
+
+@RunWith(AndroidTestingRunner::class)
+class ScreenshotPolicyImplTest : SysuiTestCase() {
+
+    @Test
+    fun testToDisplayContentInfo() {
+        assertThat(fullScreenWorkProfileTask.toDisplayContentInfo())
+            .isEqualTo(
+                DisplayContentInfo(
+                    ComponentName(
+                        "com.google.android.apps.nbu.files",
+                        "com.google.android.apps.nbu.files.home.HomeActivity"
+                    ),
+                    Rect(0, 0, 1080, 2400),
+                    UserHandle.of(MANAGED_PROFILE_USER),
+                    65))
+    }
+
+    @Test
+    fun findPrimaryContent_ignoresPipTask() = runBlocking {
+        val policy = fakeTasksPolicyImpl(
+            mContext,
+            shadeExpanded = false,
+            tasks = listOf(
+                    pipTask,
+                    fullScreenWorkProfileTask,
+                    launcherTask,
+                    emptyTask)
+        )
+
+        val info = policy.findPrimaryContent(DISPLAY_ID)
+        assertThat(info).isEqualTo(fullScreenWorkProfileTask.toDisplayContentInfo())
+    }
+
+    @Test
+    fun findPrimaryContent_shadeExpanded_ignoresTopTask() = runBlocking {
+        val policy = fakeTasksPolicyImpl(
+            mContext,
+            shadeExpanded = true,
+            tasks = listOf(
+                fullScreenWorkProfileTask,
+                launcherTask,
+                emptyTask)
+        )
+
+        val info = policy.findPrimaryContent(DISPLAY_ID)
+        assertThat(info).isEqualTo(policy.systemUiContent)
+    }
+
+    @Test
+    fun findPrimaryContent_emptyTaskList() = runBlocking {
+        val policy = fakeTasksPolicyImpl(
+            mContext,
+            shadeExpanded = false,
+            tasks = listOf()
+        )
+
+        val info = policy.findPrimaryContent(DISPLAY_ID)
+        assertThat(info).isEqualTo(policy.systemUiContent)
+    }
+
+    @Test
+    fun findPrimaryContent_workProfileNotOnTop() = runBlocking {
+        val policy = fakeTasksPolicyImpl(
+            mContext,
+            shadeExpanded = false,
+            tasks = listOf(
+                launcherTask,
+                fullScreenWorkProfileTask,
+                emptyTask)
+        )
+
+        val info = policy.findPrimaryContent(DISPLAY_ID)
+        assertThat(info).isEqualTo(launcherTask.toDisplayContentInfo())
+    }
+
+    private fun fakeTasksPolicyImpl(
+        context: Context,
+        shadeExpanded: Boolean,
+        tasks: List<RootTaskInfo>
+    ): ScreenshotPolicyImpl {
+        val userManager = mock<UserManager>()
+        val atmService = mock<IActivityTaskManager>()
+        val dispatcher = Dispatchers.Unconfined
+
+        return object : ScreenshotPolicyImpl(context, userManager, atmService, dispatcher) {
+            override suspend fun isManagedProfile(userId: Int) = (userId == MANAGED_PROFILE_USER)
+            override suspend fun getAllRootTaskInfosOnDisplay(displayId: Int) = tasks
+            override suspend fun isNotificationShadeExpanded() = shadeExpanded
+        }
+    }
+
+    private val pipTask = RootTaskInfo().apply {
+        configuration.windowConfiguration.apply {
+            windowingMode = WINDOWING_MODE_PINNED
+            bounds = Rect(628, 1885, 1038, 2295)
+            activityType = ACTIVITY_TYPE_STANDARD
+        }
+        displayId = DISPLAY_ID
+        userId = PRIMARY_USER
+        taskId = 66
+        visible = true
+        isVisible = true
+        isRunning = true
+        numActivities = 1
+        topActivity = ComponentName(
+            "com.google.android.youtube",
+            "com.google.android.apps.youtube.app.watchwhile.WatchWhileActivity"
+        )
+        childTaskIds = intArrayOf(66)
+        childTaskNames = arrayOf("com.google.android.youtube/" +
+                "com.google.android.youtube.app.honeycomb.Shell\$HomeActivity")
+        childTaskUserIds = intArrayOf(0)
+        childTaskBounds = arrayOf(Rect(628, 1885, 1038, 2295))
+    }
+
+    private val fullScreenWorkProfileTask = RootTaskInfo().apply {
+        configuration.windowConfiguration.apply {
+            windowingMode = WINDOWING_MODE_FULLSCREEN
+            bounds = Rect(0, 0, 1080, 2400)
+            activityType = ACTIVITY_TYPE_STANDARD
+        }
+        displayId = DISPLAY_ID
+        userId = MANAGED_PROFILE_USER
+        taskId = 65
+        visible = true
+        isVisible = true
+        isRunning = true
+        numActivities = 1
+        topActivity = ComponentName(
+            "com.google.android.apps.nbu.files",
+            "com.google.android.apps.nbu.files.home.HomeActivity"
+        )
+        childTaskIds = intArrayOf(65)
+        childTaskNames = arrayOf("com.google.android.apps.nbu.files/" +
+                "com.google.android.apps.nbu.files.home.HomeActivity")
+        childTaskUserIds = intArrayOf(MANAGED_PROFILE_USER)
+        childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400))
+    }
+
+    private val launcherTask = RootTaskInfo().apply {
+        configuration.windowConfiguration.apply {
+            windowingMode = WINDOWING_MODE_FULLSCREEN
+            bounds = Rect(0, 0, 1080, 2400)
+            activityType = ACTIVITY_TYPE_HOME
+        }
+        displayId = DISPLAY_ID
+        taskId = 1
+        userId = PRIMARY_USER
+        visible = true
+        isVisible = true
+        isRunning = true
+        numActivities = 1
+        topActivity = ComponentName(
+            "com.google.android.apps.nexuslauncher",
+            "com.google.android.apps.nexuslauncher.NexusLauncherActivity",
+        )
+        childTaskIds = intArrayOf(1)
+        childTaskNames = arrayOf("com.google.android.apps.nexuslauncher/" +
+                "com.google.android.apps.nexuslauncher.NexusLauncherActivity")
+        childTaskUserIds = intArrayOf(0)
+        childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400))
+    }
+
+    private val emptyTask = RootTaskInfo().apply {
+        configuration.windowConfiguration.apply {
+            windowingMode = WINDOWING_MODE_FULLSCREEN
+            bounds = Rect(0, 0, 1080, 2400)
+            activityType = ACTIVITY_TYPE_UNDEFINED
+        }
+        displayId = DISPLAY_ID
+        taskId = 2
+        userId = PRIMARY_USER
+        visible = false
+        isVisible = false
+        isRunning = false
+        numActivities = 0
+        childTaskIds = intArrayOf(3, 4)
+        childTaskNames = arrayOf("", "")
+        childTaskUserIds = intArrayOf(0, 0)
+        childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400), Rect(0, 2400, 1080, 4800))
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 98389c2..e2ce939 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -458,7 +458,6 @@
 
         NotificationWakeUpCoordinator coordinator =
                 new NotificationWakeUpCoordinator(
-                        mDumpManager,
                         mock(HeadsUpManagerPhone.class),
                         new StatusBarStateControllerImpl(new UiEventLoggerFake(), mDumpManager,
                                 mInteractionJankMonitor),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
deleted file mode 100644
index 19dd027..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification;
-
-import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.verify;
-
-import android.app.ActivityManager;
-import android.app.Notification;
-import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class NotificationListControllerTest extends SysuiTestCase {
-    private NotificationListController mController;
-
-    @Mock private NotificationEntryManager mEntryManager;
-    @Mock private NotificationListContainer mListContainer;
-    @Mock private DeviceProvisionedController mDeviceProvisionedController;
-
-    @Captor private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
-    @Captor private ArgumentCaptor<DeviceProvisionedListener> mProvisionedCaptor;
-
-    private NotificationEntryListener mEntryListener;
-    private DeviceProvisionedListener mProvisionedListener;
-
-    private int mNextNotifId = 0;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mDependency.injectMockDependency(NotificationLockscreenUserManager.class);
-
-        mController = new NotificationListController(
-                mEntryManager,
-                mListContainer,
-                mDeviceProvisionedController);
-        mController.bind();
-
-        // Capture callbacks passed to mocks
-        verify(mEntryManager).addNotificationEntryListener(mEntryListenerCaptor.capture());
-        mEntryListener = mEntryListenerCaptor.getValue();
-        verify(mDeviceProvisionedController).addCallback(mProvisionedCaptor.capture());
-        mProvisionedListener = mProvisionedCaptor.getValue();
-    }
-
-    @Test
-    public void testCleanUpViewStateOnEntryRemoved() {
-        final NotificationEntry entry = buildEntry();
-        mEntryListener.onEntryRemoved(
-                entry,
-                NotificationVisibility.obtain(entry.getKey(), 0, 0, true),
-                false,
-                UNDEFINED_DISMISS_REASON);
-        verify(mListContainer).cleanUpViewStateForEntry(entry);
-    }
-
-    @Test
-    public void testCallUpdateNotificationsOnDeviceProvisionedChange() {
-        mProvisionedListener.onDeviceProvisionedChanged();
-        verify(mEntryManager).updateNotifications(anyString());
-    }
-
-    private NotificationEntry buildEntry() {
-        mNextNotifId++;
-
-        Notification.Builder n = new Notification.Builder(mContext, "")
-                .setSmallIcon(R.drawable.ic_person)
-                .setContentTitle("Title")
-                .setContentText("Text");
-
-        return new NotificationEntryBuilder()
-                .setPkg(TEST_PACKAGE_NAME)
-                .setOpPkg(TEST_PACKAGE_NAME)
-                .setId(mNextNotifId)
-                .setUid(TEST_UID)
-                .setNotification(n.build())
-                .setUser(new UserHandle(ActivityManager.getCurrentUser()))
-                .build();
-    }
-
-    private static final String TEST_PACKAGE_NAME = "test";
-    private static final int TEST_UID = 0;
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 8fd6842..35d2363b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -3,19 +3,21 @@
 import android.annotation.DimenRes
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
+import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.ShadeInterpolation.getContentAlpha
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.statusbar.EmptyShadeView
+import com.android.systemui.statusbar.NotificationShelf
+import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
-import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController
-import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
 import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
-import junit.framework.Assert.assertEquals
 import org.junit.Before
 import org.junit.Test
 import org.mockito.Mockito.mock
@@ -26,17 +28,20 @@
 
     private val hostView = FrameLayout(context)
     private val stackScrollAlgorithm = StackScrollAlgorithm(context, hostView)
-    private val expandableViewState = ExpandableViewState()
     private val notificationRow = mock(ExpandableNotificationRow::class.java)
     private val dumpManager = mock(DumpManager::class.java)
     private val mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager::class.java)
+    private val notificationShelf = mock(NotificationShelf::class.java)
+    private val emptyShadeView = EmptyShadeView(context, /* attrs= */ null).apply {
+        layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100)
+    }
 
     private val ambientState = AmbientState(
-        context,
-        dumpManager,
-        SectionProvider { _, _ -> false },
-        BypassController { false },
-        mStatusBarKeyguardViewManager
+            context,
+            dumpManager,
+            /* sectionProvider */ { _, _ -> false },
+            /* bypassController */ { false },
+            mStatusBarKeyguardViewManager
     )
 
     private val testableResources = mContext.orCreateTestableResources
@@ -49,7 +54,9 @@
 
     @Before
     fun setUp() {
-        whenever(notificationRow.viewState).thenReturn(expandableViewState)
+        whenever(notificationShelf.viewState).thenReturn(ExpandableViewState())
+        whenever(notificationRow.viewState).thenReturn(ExpandableViewState())
+
         hostView.addView(notificationRow)
     }
 
@@ -60,7 +67,8 @@
 
         stackScrollAlgorithm.resetViewStates(ambientState, 0)
 
-        assertThat(expandableViewState.yTranslation).isEqualTo(stackScrollAlgorithm.mHeadsUpInset)
+        assertThat(notificationRow.viewState.yTranslation)
+                .isEqualTo(stackScrollAlgorithm.mHeadsUpInset)
     }
 
     @Test
@@ -75,15 +83,12 @@
         stackScrollAlgorithm.resetViewStates(ambientState, 0)
 
         // top margin presence should decrease heads up translation up to minHeadsUpTranslation
-        assertThat(expandableViewState.yTranslation).isEqualTo(minHeadsUpTranslation)
+        assertThat(notificationRow.viewState.yTranslation).isEqualTo(minHeadsUpTranslation)
     }
 
     @Test
     fun resetViewStates_emptyShadeView_isCenteredVertically() {
         stackScrollAlgorithm.initView(context)
-        val emptyShadeView = EmptyShadeView(context, /* attrs= */ null).apply {
-            layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100)
-        }
         hostView.removeAllViews()
         hostView.addView(emptyShadeView)
         ambientState.layoutMaxHeight = 1280
@@ -98,6 +103,121 @@
     }
 
     @Test
+    fun resetViewStates_hunGoingToShade_viewBecomesOpaque() {
+        whenever(notificationRow.isAboveShelf).thenReturn(true)
+        ambientState.isShadeExpanded = true
+        ambientState.trackedHeadsUpRow = notificationRow
+        stackScrollAlgorithm.initView(context)
+
+        stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+        assertThat(notificationRow.viewState.alpha).isEqualTo(1f)
+    }
+
+    @Test
+    fun resetViewStates_isExpansionChanging_viewBecomesTransparent() {
+        whenever(mStatusBarKeyguardViewManager.isBouncerInTransit).thenReturn(false)
+        ambientState.isExpansionChanging = true
+        ambientState.expansionFraction = 0.25f
+        stackScrollAlgorithm.initView(context)
+
+        stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+        val expected = getContentAlpha(0.25f)
+        assertThat(notificationRow.viewState.alpha).isEqualTo(expected)
+    }
+
+    @Test
+    fun resetViewStates_isExpansionChangingWhileBouncerInTransit_viewBecomesTransparent() {
+        whenever(mStatusBarKeyguardViewManager.isBouncerInTransit).thenReturn(true)
+        ambientState.isExpansionChanging = true
+        ambientState.expansionFraction = 0.25f
+        stackScrollAlgorithm.initView(context)
+
+        stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+        val expected = aboutToShowBouncerProgress(0.25f)
+        assertThat(notificationRow.viewState.alpha).isEqualTo(expected)
+    }
+
+    @Test
+    fun resetViewStates_isOnKeyguard_viewBecomesTransparent() {
+        ambientState.setStatusBarState(StatusBarState.KEYGUARD)
+        ambientState.hideAmount = 0.25f
+        stackScrollAlgorithm.initView(context)
+
+        stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+        assertThat(notificationRow.viewState.alpha).isEqualTo(1f - ambientState.hideAmount)
+    }
+
+    @Test
+    fun resetViewStates_isOnKeyguard_emptyShadeViewBecomesTransparent() {
+        ambientState.setStatusBarState(StatusBarState.KEYGUARD)
+        ambientState.fractionToShade = 0.25f
+        stackScrollAlgorithm.initView(context)
+        hostView.removeAllViews()
+        hostView.addView(emptyShadeView)
+
+        stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+        val expected = getContentAlpha(ambientState.fractionToShade)
+        assertThat(emptyShadeView.viewState.alpha).isEqualTo(expected)
+    }
+
+    @Test
+    fun resetViewStates_isOnKeyguard_emptyShadeViewBecomesOpaque() {
+        ambientState.setStatusBarState(StatusBarState.SHADE)
+        ambientState.fractionToShade = 0.25f
+        stackScrollAlgorithm.initView(context)
+        hostView.removeAllViews()
+        hostView.addView(emptyShadeView)
+
+        stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+        assertThat(emptyShadeView.viewState.alpha).isEqualTo(1f)
+    }
+
+    @Test
+    fun resetViewStates_hiddenShelf_viewAlphaDoesNotChange() {
+        val expected = notificationShelf.viewState.alpha
+        notificationShelf.viewState.hidden = true
+        ambientState.shelf = notificationShelf
+        stackScrollAlgorithm.initView(context)
+
+        stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+        assertThat(notificationShelf.viewState.alpha).isEqualTo(expected)
+    }
+
+    @Test
+    fun resetViewStates_shelfTopLessThanViewTop_hidesView() {
+        notificationRow.viewState.yTranslation = 10f
+        notificationShelf.viewState.yTranslation = 0.9f
+        notificationShelf.viewState.hidden = false
+        ambientState.shelf = notificationShelf
+        stackScrollAlgorithm.initView(context)
+
+        stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+        assertThat(notificationRow.viewState.alpha).isEqualTo(0f)
+    }
+
+    @Test
+    fun resetViewStates_shelfTopGreaterOrEqualThanViewTop_viewAlphaDoesNotChange() {
+        val expected = notificationRow.viewState.alpha
+        notificationRow.viewState.yTranslation = 10f
+        notificationShelf.viewState.yTranslation = 10f
+        notificationShelf.viewState.hidden = false
+        ambientState.shelf = notificationShelf
+        stackScrollAlgorithm.initView(context)
+
+        stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+        assertThat(notificationRow.viewState.alpha).isEqualTo(expected)
+    }
+
+    @Test
     fun getGapForLocation_onLockscreen_returnsSmallGap() {
         val gap = stackScrollAlgorithm.getGapForLocation(
                 /* fractionToShade= */ 0f, /* onKeyguard= */ true)
@@ -267,7 +387,6 @@
         assertEquals(10f, expandableViewState.yTranslation)
     }
 
-
     @Test
     fun clampHunToTop_viewYFarAboveVisibleStack_heightCollapsed() {
         val expandableViewState = ExpandableViewState()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
index a6b7e51..ca98143 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
@@ -58,7 +58,6 @@
     @Before
     public void setup() {
         injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
-        mDependency.injectMockDependency(DarkIconDispatcher.class);
     }
 
     @Test
@@ -75,7 +74,8 @@
                 layout,
                 mock(FeatureFlags.class),
                 mock(StatusBarPipelineFlags.class),
-                () -> mock(WifiViewModel.class));
+                () -> mock(WifiViewModel.class),
+                mock(DarkIconDispatcher.class));
         testCallOnAdd_forManager(manager);
     }
 
@@ -116,8 +116,10 @@
                 LinearLayout group,
                 FeatureFlags featureFlags,
                 StatusBarPipelineFlags statusBarPipelineFlags,
-                Provider<WifiViewModel> wifiViewModelProvider) {
-            super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
+                Provider<WifiViewModel> wifiViewModelProvider,
+                DarkIconDispatcher darkIconDispatcher) {
+            super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider,
+                    darkIconDispatcher);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
index 9829271..d070ba0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
@@ -473,6 +473,40 @@
         job.cancel()
     }
 
+    /** Regression test for b/244173280. */
+    @Test
+    fun wifiNetwork_multipleSubscribers_newSubscribersGetCurrentValue() = runBlocking(IMMEDIATE) {
+        var latest1: WifiNetworkModel? = null
+        val job1 = underTest
+            .wifiNetwork
+            .onEach { latest1 = it }
+            .launchIn(this)
+
+        getNetworkCallback()
+            .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
+
+        assertThat(latest1 is WifiNetworkModel.Active).isTrue()
+        val latest1Active = latest1 as WifiNetworkModel.Active
+        assertThat(latest1Active.networkId).isEqualTo(NETWORK_ID)
+        assertThat(latest1Active.ssid).isEqualTo(SSID)
+
+        // WHEN we add a second subscriber after having already emitted a value
+        var latest2: WifiNetworkModel? = null
+        val job2 = underTest
+            .wifiNetwork
+            .onEach { latest2 = it }
+            .launchIn(this)
+
+        // THEN the second subscribe receives the already-emitted value
+        assertThat(latest2 is WifiNetworkModel.Active).isTrue()
+        val latest2Active = latest2 as WifiNetworkModel.Active
+        assertThat(latest2Active.networkId).isEqualTo(NETWORK_ID)
+        assertThat(latest2Active.ssid).isEqualTo(SSID)
+
+        job1.cancel()
+        job2.cancel()
+    }
+
     @Test
     fun wifiActivity_nullWifiManager_receivesDefault() = runBlocking(IMMEDIATE) {
         underTest = WifiRepositoryImpl(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 312db2d..2e74bf5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -85,6 +85,8 @@
     @Mock
     MediaOutputDialogFactory mMediaOutputDialogFactory;
     @Mock
+    VolumePanelFactory mVolumePanelFactory;
+    @Mock
     ActivityStarter mActivityStarter;
     @Mock
     InteractionJankMonitor mInteractionJankMonitor;
@@ -102,6 +104,7 @@
                 mDeviceProvisionedController,
                 mConfigurationController,
                 mMediaOutputDialogFactory,
+                mVolumePanelFactory,
                 mActivityStarter,
                 mInteractionJankMonitor);
         mDialog.init(0, null);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 6aa472f..01af23d 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -4248,7 +4248,8 @@
         final String procName = r.processName;
         HostingRecord hostingRecord = new HostingRecord(
                 HostingRecord.HOSTING_TYPE_SERVICE, r.instanceName,
-                r.definingPackageName, r.definingUid, r.serviceInfo.processName);
+                r.definingPackageName, r.definingUid, r.serviceInfo.processName,
+                getHostingRecordTriggerType(r));
         ProcessRecord app;
 
         if (!isolated) {
@@ -4358,6 +4359,14 @@
         return null;
     }
 
+    private String getHostingRecordTriggerType(ServiceRecord r) {
+        if (Manifest.permission.BIND_JOB_SERVICE.equals(r.permission)
+                && r.mRecentCallingUid == SYSTEM_UID) {
+            return HostingRecord.TRIGGER_TYPE_JOB;
+        }
+        return HostingRecord.TRIGGER_TYPE_UNKNOWN;
+    }
+
     private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
             throws TransactionTooLargeException {
         for (int i=r.bindings.size()-1; i>=0; i--) {
diff --git a/services/core/java/com/android/server/am/HostingRecord.java b/services/core/java/com/android/server/am/HostingRecord.java
index 2498f76..30811a1 100644
--- a/services/core/java/com/android/server/am/HostingRecord.java
+++ b/services/core/java/com/android/server/am/HostingRecord.java
@@ -30,9 +30,10 @@
 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_SERVICE;
 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_SYSTEM;
 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_TOP_ACTIVITY;
-import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_PUSH_MESSAGE;
-import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_PUSH_MESSAGE_OVER_QUOTA;
 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_ALARM;
+import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_JOB;
+import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE;
+import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA;
 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_UNKNOWN;
 import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TYPE__UNKNOWN;
 
@@ -97,6 +98,7 @@
     public static final String TRIGGER_TYPE_ALARM = "alarm";
     public static final String TRIGGER_TYPE_PUSH_MESSAGE = "push_message";
     public static final String TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA = "push_message_over_quota";
+    public static final String TRIGGER_TYPE_JOB = "job";
 
     @NonNull private final String mHostingType;
     private final String mHostingName;
@@ -126,10 +128,11 @@
     }
 
     public HostingRecord(@NonNull String hostingType, ComponentName hostingName,
-            String definingPackageName, int definingUid, String definingProcessName) {
+            String definingPackageName, int definingUid, String definingProcessName,
+            String triggerType) {
         this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE, definingPackageName,
                 definingUid, false /* isTopApp */, definingProcessName, null /* action */,
-                TRIGGER_TYPE_UNKNOWN);
+                triggerType);
     }
 
     public HostingRecord(@NonNull String hostingType, ComponentName hostingName, boolean isTopApp) {
@@ -313,9 +316,11 @@
             case TRIGGER_TYPE_ALARM:
                 return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_ALARM;
             case TRIGGER_TYPE_PUSH_MESSAGE:
-                return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_PUSH_MESSAGE;
+                return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE;
             case TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA:
-                return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_PUSH_MESSAGE_OVER_QUOTA;
+                return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA;
+            case TRIGGER_TYPE_JOB:
+                return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_JOB;
             default:
                 return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_UNKNOWN;
         }
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 66a4527..4adbfaa 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -53,8 +53,6 @@
 
     private static final String TAG = "AS.BtHelper";
 
-    private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U
-
     private final @NonNull AudioDeviceBroker mDeviceBroker;
 
     BtHelper(@NonNull AudioDeviceBroker broker) {
@@ -913,7 +911,7 @@
                 return "ENCODING_APTX_HD";
             case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
                 return "ENCODING_LDAC";
-            case SOURCE_CODEC_TYPE_OPUS: // TODO update in U
+            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS:
                 return "ENCODING_OPUS";
             default:
                 return "ENCODING_BT_CODEC_TYPE(" + btCodecType + ")";
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 689ddd2..c29755a 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -72,7 +72,6 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.DumpUtils;
 import com.android.server.SystemService;
-import com.android.server.biometrics.sensors.CoexCoordinator;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -951,16 +950,6 @@
             return new ArrayList<>();
         }
 
-        public boolean isAdvancedCoexLogicEnabled(Context context) {
-            return Settings.Secure.getInt(context.getContentResolver(),
-                    CoexCoordinator.SETTING_ENABLE_NAME, 1) != 0;
-        }
-
-        public boolean isCoexFaceNonBypassHapticsDisabled(Context context) {
-            return Settings.Secure.getInt(context.getContentResolver(),
-                    CoexCoordinator.FACE_HAPTIC_DISABLE, 0) != 0;
-        }
-
         public Supplier<Long> getRequestGenerator() {
             final AtomicLong generator = new AtomicLong(0);
             return () -> generator.incrementAndGet();
@@ -992,14 +981,6 @@
                 mEnabledOnKeyguardCallbacks);
         mRequestCounter = mInjector.getRequestGenerator();
 
-        // TODO(b/193089985) This logic lives here (outside of CoexCoordinator) so that it doesn't
-        //  need to depend on context. We can remove this code once the advanced logic is enabled
-        //  by default.
-        CoexCoordinator coexCoordinator = CoexCoordinator.getInstance();
-        coexCoordinator.setAdvancedLogicEnabled(injector.isAdvancedCoexLogicEnabled(context));
-        coexCoordinator.setFaceHapticDisabledWhenNonBypass(
-                injector.isCoexFaceNonBypassHapticsDisabled(context));
-
         try {
             injector.getActivityManagerService().registerUserSwitchObserver(
                     new UserSwitchObserver() {
@@ -1333,7 +1314,5 @@
         pw.println();
         pw.println("CurrentSession: " + mAuthSession);
         pw.println();
-        pw.println("CoexCoordinator: " + CoexCoordinator.getInstance().toString());
-        pw.println();
     }
 }
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContext.java b/services/core/java/com/android/server/biometrics/log/BiometricContext.java
index c86a8cb..8265203 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricContext.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricContext.java
@@ -46,6 +46,9 @@
     /** If the display is in AOD. */
     boolean isAod();
 
+    /** If the device is awake or is becoming awake. */
+    boolean isAwake();
+
     /**
      * Subscribe to context changes.
      *
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
index 9d2fde7..3d1a634 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
@@ -43,7 +43,7 @@
 /**
  * A default provider for {@link BiometricContext}.
  */
-class BiometricContextProvider implements BiometricContext {
+final class BiometricContextProvider implements BiometricContext {
 
     private static final String TAG = "BiometricContextProvider";
 
@@ -76,7 +76,8 @@
     private final Map<Integer, InstanceId> mSession = new ConcurrentHashMap<>();
 
     private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
-    private boolean mIsDozing = false;
+    private boolean mIsAod = false;
+    private boolean mIsAwake = false;
 
     @VisibleForTesting
     BiometricContextProvider(@NonNull AmbientDisplayConfiguration ambientDisplayConfiguration,
@@ -85,9 +86,14 @@
         try {
             service.setBiometicContextListener(new IBiometricContextListener.Stub() {
                 @Override
-                public void onDozeChanged(boolean isDozing) {
-                    mIsDozing = isDozing;
-                    notifyChanged();
+                public void onDozeChanged(boolean isDozing, boolean isAwake) {
+                    isDozing = isDozing && isAodEnabled();
+                    final boolean changed = (mIsAod != isDozing) || (mIsAwake != isAwake);
+                    if (changed) {
+                        mIsAod = isDozing;
+                        mIsAwake = isAwake;
+                        notifyChanged();
+                    }
                 }
 
                 private void notifyChanged() {
@@ -97,6 +103,10 @@
                         notifySubscribers();
                     }
                 }
+
+                private boolean isAodEnabled() {
+                    return mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
+                }
             });
             service.registerSessionListener(SESSION_TYPES, new ISessionListener.Stub() {
                 @Override
@@ -161,7 +171,12 @@
 
     @Override
     public boolean isAod() {
-        return mIsDozing && mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
+        return mIsAod;
+    }
+
+    @Override
+    public boolean isAwake() {
+        return mIsAwake;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 4eb6d38..8a24ff6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -29,7 +29,6 @@
 import android.hardware.biometrics.BiometricOverlayConstants;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.security.KeyStore;
 import android.util.EventLog;
 import android.util.Slog;
@@ -46,9 +45,7 @@
  * A class to keep track of the authentication state for a given client.
  */
 public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
-        implements AuthenticationConsumer  {
-
-    private static final String TAG = "Biometrics/AuthenticationClient";
+        implements AuthenticationConsumer {
 
     // New, has not started yet
     public static final int STATE_NEW = 0;
@@ -67,28 +64,27 @@
             STATE_STARTED_PAUSED_ATTEMPTED,
             STATE_STOPPED})
     @interface State {}
-
+    private static final String TAG = "Biometrics/AuthenticationClient";
+    protected final long mOperationId;
     private final boolean mIsStrongBiometric;
     private final boolean mRequireConfirmation;
     private final ActivityTaskManager mActivityTaskManager;
     private final BiometricManager mBiometricManager;
-    @Nullable private final TaskStackListener mTaskStackListener;
+    @Nullable
+    private final TaskStackListener mTaskStackListener;
     private final LockoutTracker mLockoutTracker;
     private final boolean mIsRestricted;
     private final boolean mAllowBackgroundAuthentication;
     private final boolean mIsKeyguardBypassEnabled;
-
-    protected final long mOperationId;
-
+    // TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update
+    //  the state. We should think of a way to improve this in the future.
+    @State
+    protected int mState = STATE_NEW;
     private long mStartTimeMs;
 
     private boolean mAuthAttempted;
     private boolean mAuthSuccess = false;
 
-    // TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update
-    //  the state. We should think of a way to improve this in the future.
-    protected @State int mState = STATE_NEW;
-
     public AuthenticationClient(@NonNull Context context, @NonNull Supplier<T> lazyDaemon,
             @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
             int targetUserId, long operationId, boolean restricted, @NonNull String owner,
@@ -111,8 +107,9 @@
         mIsKeyguardBypassEnabled = isKeyguardBypassEnabled;
     }
 
-    public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) {
-        final @LockoutTracker.LockoutMode int lockoutMode =
+    @LockoutTracker.LockoutMode
+    public int handleFailedAttempt(int userId) {
+        @LockoutTracker.LockoutMode final int lockoutMode =
                 mLockoutTracker.getLockoutModeForUser(userId);
         final PerformanceTracker performanceTracker =
                 PerformanceTracker.getInstanceForSensorId(getSensorId());
@@ -173,14 +170,16 @@
 
         final ClientMonitorCallbackConverter listener = getListener();
 
-        if (DEBUG) Slog.v(TAG, "onAuthenticated(" + authenticated + ")"
-                + ", ID:" + identifier.getBiometricId()
-                + ", Owner: " + getOwnerString()
-                + ", isBP: " + isBiometricPrompt()
-                + ", listener: " + listener
-                + ", requireConfirmation: " + mRequireConfirmation
-                + ", user: " + getTargetUserId()
-                + ", clientMonitor: " + toString());
+        if (DEBUG) {
+            Slog.v(TAG, "onAuthenticated(" + authenticated + ")"
+                    + ", ID:" + identifier.getBiometricId()
+                    + ", Owner: " + getOwnerString()
+                    + ", isBP: " + isBiometricPrompt()
+                    + ", listener: " + listener
+                    + ", requireConfirmation: " + mRequireConfirmation
+                    + ", user: " + getTargetUserId()
+                    + ", clientMonitor: " + this);
+        }
 
         final PerformanceTracker pm = PerformanceTracker.getInstanceForSensorId(getSensorId());
         if (isCryptoOperation()) {
@@ -239,142 +238,57 @@
                         getSensorId(), getTargetUserId(), byteToken);
             }
 
-            final CoexCoordinator coordinator = CoexCoordinator.getInstance();
-            coordinator.onAuthenticationSucceeded(SystemClock.uptimeMillis(), this,
-                    new CoexCoordinator.Callback() {
-                @Override
-                public void sendAuthenticationResult(boolean addAuthTokenIfStrong) {
-                    if (addAuthTokenIfStrong && mIsStrongBiometric) {
-                        final int result = KeyStore.getInstance().addAuthToken(byteToken);
-                        Slog.d(TAG, "addAuthToken: " + result);
+            // For BP, BiometricService will add the authToken to Keystore.
+            if (!isBiometricPrompt() && mIsStrongBiometric) {
+                final int result = KeyStore.getInstance().addAuthToken(byteToken);
+                if (result != KeyStore.NO_ERROR) {
+                    Slog.d(TAG, "Error adding auth token : " + result);
+                } else {
+                    Slog.d(TAG, "addAuthToken: " + result);
+                }
+            } else {
+                Slog.d(TAG, "Skipping addAuthToken");
+            }
+            try {
+                if (listener != null) {
+                    if (!mIsRestricted) {
+                        listener.onAuthenticationSucceeded(getSensorId(), identifier, byteToken,
+                                getTargetUserId(), mIsStrongBiometric);
                     } else {
-                        Slog.d(TAG, "Skipping addAuthToken");
+                        listener.onAuthenticationSucceeded(getSensorId(), null /* identifier */,
+                                byteToken,
+                                getTargetUserId(), mIsStrongBiometric);
                     }
-
-                    if (listener != null) {
-                        try {
-                            // Explicitly have if/else here to make it super obvious in case the
-                            // code is touched in the future.
-                            if (!mIsRestricted) {
-                                listener.onAuthenticationSucceeded(getSensorId(),
-                                        identifier,
-                                        byteToken,
-                                        getTargetUserId(),
-                                        mIsStrongBiometric);
-                            } else {
-                                listener.onAuthenticationSucceeded(getSensorId(),
-                                        null /* identifier */,
-                                        byteToken,
-                                        getTargetUserId(),
-                                        mIsStrongBiometric);
-                            }
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "Unable to notify listener", e);
-                        }
-                    } else {
-                        Slog.w(TAG, "Client not listening");
-                    }
+                } else {
+                    Slog.e(TAG, "Received successful auth, but client was not listening");
                 }
-
-                @Override
-                public void sendHapticFeedback() {
-                    if (listener != null && mShouldVibrate) {
-                        vibrateSuccess();
-                    }
-                }
-
-                @Override
-                public void handleLifecycleAfterAuth() {
-                    AuthenticationClient.this.handleLifecycleAfterAuth(true /* authenticated */);
-                }
-
-                @Override
-                public void sendAuthenticationCanceled() {
-                    sendCancelOnly(listener);
-                }
-            });
-        } else { // not authenticated
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Unable to notify listener", e);
+                mCallback.onClientFinished(this, false);
+                return;
+            }
+        } else {
             if (isBackgroundAuth) {
                 Slog.e(TAG, "cancelling due to background auth");
                 cancel();
             } else {
                 // Allow system-defined limit of number of attempts before giving up
-                final @LockoutTracker.LockoutMode int lockoutMode =
+                @LockoutTracker.LockoutMode final int lockoutMode =
                         handleFailedAttempt(getTargetUserId());
                 if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
                     markAlreadyDone();
                 }
 
-                final CoexCoordinator coordinator = CoexCoordinator.getInstance();
-                coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode,
-                        new CoexCoordinator.Callback() {
-                            @Override
-                            public void sendAuthenticationResult(boolean addAuthTokenIfStrong) {
-                                if (listener != null) {
-                                    try {
-                                        listener.onAuthenticationFailed(getSensorId());
-                                    } catch (RemoteException e) {
-                                        Slog.e(TAG, "Unable to notify listener", e);
-                                    }
-                                }
-                            }
-
-                            @Override
-                            public void sendHapticFeedback() {
-                                if (listener != null && mShouldVibrate) {
-                                    vibrateError();
-                                }
-                            }
-
-                            @Override
-                            public void handleLifecycleAfterAuth() {
-                                AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */);
-                            }
-
-                            @Override
-                            public void sendAuthenticationCanceled() {
-                                sendCancelOnly(listener);
-                            }
-                        });
+                try {
+                    listener.onAuthenticationFailed(getSensorId());
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Unable to notify listener", e);
+                    mCallback.onClientFinished(this, false);
+                    return;
+                }
             }
         }
-    }
-
-    /**
-     * Only call this method on interfaces where lockout does not come from onError, I.E. the
-     * old HIDL implementation.
-     */
-    protected void onLockoutTimed(long durationMillis) {
-        final ClientMonitorCallbackConverter listener = getListener();
-        final CoexCoordinator coordinator = CoexCoordinator.getInstance();
-        coordinator.onAuthenticationError(this, BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
-                new CoexCoordinator.ErrorCallback() {
-            @Override
-            public void sendHapticFeedback() {
-                if (listener != null && mShouldVibrate) {
-                    vibrateError();
-                }
-            }
-        });
-    }
-
-    /**
-     * Only call this method on interfaces where lockout does not come from onError, I.E. the
-     * old HIDL implementation.
-     */
-    protected void onLockoutPermanent() {
-        final ClientMonitorCallbackConverter listener = getListener();
-        final CoexCoordinator coordinator = CoexCoordinator.getInstance();
-        coordinator.onAuthenticationError(this,
-                BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT,
-                new CoexCoordinator.ErrorCallback() {
-            @Override
-            public void sendHapticFeedback() {
-                if (listener != null && mShouldVibrate) {
-                    vibrateError();
-                }
-            }
-        });
+        AuthenticationClient.this.handleLifecycleAfterAuth(authenticated);
     }
 
     private void sendCancelOnly(@Nullable ClientMonitorCallbackConverter listener) {
@@ -396,7 +310,7 @@
     public void onAcquired(int acquiredInfo, int vendorCode) {
         super.onAcquired(acquiredInfo, vendorCode);
 
-        final @LockoutTracker.LockoutMode int lockoutMode =
+        @LockoutTracker.LockoutMode final int lockoutMode =
                 mLockoutTracker.getLockoutModeForUser(getTargetUserId());
         if (lockoutMode == LockoutTracker.LOCKOUT_NONE) {
             PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
@@ -408,8 +322,6 @@
     public void onError(@BiometricConstants.Errors int errorCode, int vendorCode) {
         super.onError(errorCode, vendorCode);
         mState = STATE_STOPPED;
-
-        CoexCoordinator.getInstance().onAuthenticationError(this, errorCode, this::vibrateError);
     }
 
     /**
@@ -419,7 +331,7 @@
     public void start(@NonNull ClientMonitorCallback callback) {
         super.start(callback);
 
-        final @LockoutTracker.LockoutMode int lockoutMode =
+        @LockoutTracker.LockoutMode final int lockoutMode =
                 mLockoutTracker.getLockoutModeForUser(getTargetUserId());
         if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
             Slog.v(TAG, "In lockout mode(" + lockoutMode + ") ; disallowing authentication");
@@ -450,22 +362,20 @@
     }
 
     /**
-     * Handles lifecycle, e.g. {@link BiometricScheduler},
-     * {@link com.android.server.biometrics.sensors.BaseClientMonitor.Callback} after authentication
-     * results are known. Note that this happens asynchronously from (but shortly after)
-     * {@link #onAuthenticated(BiometricAuthenticator.Identifier, boolean, ArrayList)} and allows
-     * {@link CoexCoordinator} a chance to invoke/delay this event.
-     * @param authenticated
+     * Handles lifecycle, e.g. {@link BiometricScheduler} after authentication. This is necessary
+     * as different clients handle the lifecycle of authentication success/reject differently. I.E.
+     * Fingerprint does not finish authentication when it is rejected.
      */
     protected abstract void handleLifecycleAfterAuth(boolean authenticated);
 
     /**
      * @return true if a user was detected (i.e. face was found, fingerprint sensor was touched.
-     *         etc)
+     * etc)
      */
     public abstract boolean wasUserDetected();
 
-    public @State int getState() {
+    @State
+    public int getState() {
         return mState;
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index 63609f7..9317c4e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -54,7 +54,7 @@
  * interactions with the HAL before finishing.
  *
  * We currently assume (and require) that each biometric sensor have its own instance of a
- * {@link BiometricScheduler}. See {@link CoexCoordinator}.
+ * {@link BiometricScheduler}.
  */
 @MainThread
 public class BiometricScheduler {
@@ -156,7 +156,6 @@
     private int mTotalOperationsHandled;
     private final int mRecentOperationsLimit;
     @NonNull private final List<Integer> mRecentOperations;
-    @NonNull private final CoexCoordinator mCoexCoordinator;
 
     // Internal callback, notified when an operation is complete. Notifies the requester
     // that the operation is complete, before performing internal scheduler work (such as
@@ -165,11 +164,6 @@
         @Override
         public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
             Slog.d(getTag(), "[Started] " + clientMonitor);
-
-            if (clientMonitor instanceof AuthenticationClient) {
-                mCoexCoordinator.addAuthenticationClient(mSensorType,
-                        (AuthenticationClient<?>) clientMonitor);
-            }
         }
 
         @Override
@@ -189,10 +183,6 @@
                 }
 
                 Slog.d(getTag(), "[Finishing] " + clientMonitor + ", success: " + success);
-                if (clientMonitor instanceof AuthenticationClient) {
-                    mCoexCoordinator.removeAuthenticationClient(mSensorType,
-                            (AuthenticationClient<?>) clientMonitor);
-                }
 
                 if (mGestureAvailabilityDispatcher != null) {
                     mGestureAvailabilityDispatcher.markSensorActive(
@@ -216,8 +206,7 @@
             @SensorType int sensorType,
             @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
             @NonNull IBiometricService biometricService,
-            int recentOperationsLimit,
-            @NonNull CoexCoordinator coexCoordinator) {
+            int recentOperationsLimit) {
         mBiometricTag = tag;
         mHandler = handler;
         mSensorType = sensorType;
@@ -227,7 +216,6 @@
         mCrashStates = new ArrayDeque<>();
         mRecentOperationsLimit = recentOperationsLimit;
         mRecentOperations = new ArrayList<>();
-        mCoexCoordinator = coexCoordinator;
     }
 
     /**
@@ -244,7 +232,7 @@
         this(tag, new Handler(Looper.getMainLooper()), sensorType, gestureAvailabilityDispatcher,
                 IBiometricService.Stub.asInterface(
                         ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
-                LOG_NUM_RECENT_OPERATIONS, CoexCoordinator.getInstance());
+                LOG_NUM_RECENT_OPERATIONS);
     }
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
deleted file mode 100644
index c8a90e7..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors;
-
-import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FACE;
-import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_UDFPS;
-import static com.android.server.biometrics.sensors.BiometricScheduler.sensorTypeToString;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.hardware.biometrics.BiometricConstants;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.biometrics.sensors.BiometricScheduler.SensorType;
-import com.android.server.biometrics.sensors.fingerprint.Udfps;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-
-/**
- * Singleton that contains the core logic for determining if haptics and authentication callbacks
- * should be sent to receivers. Note that this class is used even when coex is not required (e.g.
- * single sensor devices, or multi-sensor devices where only a single sensor is authenticating).
- * This allows us to have all business logic in one testable place.
- */
-public class CoexCoordinator {
-
-    private static final String TAG = "BiometricCoexCoordinator";
-    public static final String SETTING_ENABLE_NAME =
-            "com.android.server.biometrics.sensors.CoexCoordinator.enable";
-    public static final String FACE_HAPTIC_DISABLE =
-            "com.android.server.biometrics.sensors.CoexCoordinator.disable_face_haptics";
-    private static final boolean DEBUG = true;
-
-    // Successful authentications should be used within this amount of time.
-    static final long SUCCESSFUL_AUTH_VALID_DURATION_MS = 5000;
-
-    /**
-     * Callback interface notifying the owner of "results" from the CoexCoordinator's business
-     * logic for accept and reject.
-     */
-    interface Callback {
-        /**
-         * Requests the owner to send the result (success/reject) and any associated info to the
-         * receiver (e.g. keyguard, BiometricService, etc).
-         */
-        void sendAuthenticationResult(boolean addAuthTokenIfStrong);
-
-        /**
-         * Requests the owner to initiate a vibration for this event.
-         */
-        void sendHapticFeedback();
-
-        /**
-         * Requests the owner to handle the AuthenticationClient's lifecycle (e.g. finish and remove
-         * from scheduler if auth was successful).
-         */
-        void handleLifecycleAfterAuth();
-
-        /**
-         * Requests the owner to notify the caller that authentication was canceled.
-         */
-        void sendAuthenticationCanceled();
-    }
-
-    /**
-     * Callback interface notifying the owner of "results" from the CoexCoordinator's business
-     * logic for errors.
-     */
-    interface ErrorCallback {
-        /**
-         * Requests the owner to initiate a vibration for this event.
-         */
-        void sendHapticFeedback();
-    }
-
-    private static final CoexCoordinator sInstance = new CoexCoordinator();
-
-    @VisibleForTesting
-    public static class SuccessfulAuth {
-        final long mAuthTimestamp;
-        final @SensorType int mSensorType;
-        final AuthenticationClient<?> mAuthenticationClient;
-        final Callback mCallback;
-        final CleanupRunnable mCleanupRunnable;
-
-        public static class CleanupRunnable implements Runnable {
-            @NonNull final LinkedList<SuccessfulAuth> mSuccessfulAuths;
-            @NonNull final SuccessfulAuth mAuth;
-            @NonNull final Callback mCallback;
-
-            public CleanupRunnable(@NonNull LinkedList<SuccessfulAuth> successfulAuths,
-                    @NonNull SuccessfulAuth auth, @NonNull Callback callback) {
-                mSuccessfulAuths = successfulAuths;
-                mAuth = auth;
-                mCallback = callback;
-            }
-
-            @Override
-            public void run() {
-                final boolean removed = mSuccessfulAuths.remove(mAuth);
-                Slog.w(TAG, "Removing stale successfulAuth: " + mAuth.toString()
-                        + ", success: " + removed);
-                mCallback.handleLifecycleAfterAuth();
-            }
-        }
-
-        public SuccessfulAuth(@NonNull Handler handler,
-                @NonNull LinkedList<SuccessfulAuth> successfulAuths,
-                long currentTimeMillis,
-                @SensorType int sensorType,
-                @NonNull AuthenticationClient<?> authenticationClient,
-                @NonNull Callback callback) {
-            mAuthTimestamp = currentTimeMillis;
-            mSensorType = sensorType;
-            mAuthenticationClient = authenticationClient;
-            mCallback = callback;
-
-            mCleanupRunnable = new CleanupRunnable(successfulAuths, this, callback);
-
-            handler.postDelayed(mCleanupRunnable, SUCCESSFUL_AUTH_VALID_DURATION_MS);
-        }
-
-        @Override
-        public String toString() {
-            return "SensorType: " + sensorTypeToString(mSensorType)
-                    + ", mAuthTimestamp: " + mAuthTimestamp
-                    + ", authenticationClient: " + mAuthenticationClient;
-        }
-    }
-
-    /** The singleton instance. */
-    @NonNull
-    public static CoexCoordinator getInstance() {
-        return sInstance;
-    }
-
-    @VisibleForTesting
-    public void setAdvancedLogicEnabled(boolean enabled) {
-        mAdvancedLogicEnabled = enabled;
-    }
-
-    public void setFaceHapticDisabledWhenNonBypass(boolean disabled) {
-        mFaceHapticDisabledWhenNonBypass = disabled;
-    }
-
-    @VisibleForTesting
-    void reset() {
-        mClientMap.clear();
-    }
-
-    // SensorType to AuthenticationClient map
-    private final Map<Integer, AuthenticationClient<?>> mClientMap = new HashMap<>();
-    @VisibleForTesting final LinkedList<SuccessfulAuth> mSuccessfulAuths = new LinkedList<>();
-    private boolean mAdvancedLogicEnabled;
-    private boolean mFaceHapticDisabledWhenNonBypass;
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
-
-    private CoexCoordinator() {}
-
-    public void addAuthenticationClient(@BiometricScheduler.SensorType int sensorType,
-            @NonNull AuthenticationClient<?> client) {
-        if (DEBUG) {
-            Slog.d(TAG, "addAuthenticationClient(" + sensorTypeToString(sensorType) + ")"
-                    + ", client: " + client);
-        }
-
-        if (mClientMap.containsKey(sensorType)) {
-            Slog.w(TAG, "Overwriting existing client: " + mClientMap.get(sensorType)
-                    + " with new client: " + client);
-        }
-
-        mClientMap.put(sensorType, client);
-    }
-
-    public void removeAuthenticationClient(@BiometricScheduler.SensorType int sensorType,
-            @NonNull AuthenticationClient<?> client) {
-        if (DEBUG) {
-            Slog.d(TAG, "removeAuthenticationClient(" + sensorTypeToString(sensorType) + ")"
-                    + ", client: " + client);
-        }
-
-        if (!mClientMap.containsKey(sensorType)) {
-            Slog.e(TAG, "sensorType: " + sensorType + " does not exist in map. Client: " + client);
-            return;
-        }
-        mClientMap.remove(sensorType);
-    }
-
-    /**
-     * Notify the coordinator that authentication succeeded (accepted)
-     */
-    public void onAuthenticationSucceeded(long currentTimeMillis,
-            @NonNull AuthenticationClient<?> client,
-            @NonNull Callback callback) {
-        final boolean isUsingSingleModality = isSingleAuthOnly(client);
-
-        if (client.isBiometricPrompt()) {
-            if (!isUsingSingleModality && hasMultipleSuccessfulAuthentications()) {
-                // only send feedback on the first one
-            } else {
-                callback.sendHapticFeedback();
-            }
-            // For BP, BiometricService will add the authToken to Keystore.
-            callback.sendAuthenticationResult(false /* addAuthTokenIfStrong */);
-            callback.handleLifecycleAfterAuth();
-        } else if (isUnknownClient(client)) {
-            // Client doesn't exist in our map for some reason. Give the user feedback so the
-            // device doesn't feel like it's stuck. All other cases below can assume that the
-            // client exists in our map.
-            callback.sendHapticFeedback();
-            callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
-            callback.handleLifecycleAfterAuth();
-        } else if (mAdvancedLogicEnabled && client.isKeyguard()) {
-            if (isUsingSingleModality) {
-                // Single sensor authentication
-                callback.sendHapticFeedback();
-                callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
-                callback.handleLifecycleAfterAuth();
-            } else {
-                // Multi sensor authentication
-                AuthenticationClient<?> udfps = mClientMap.getOrDefault(SENSOR_TYPE_UDFPS, null);
-                AuthenticationClient<?> face = mClientMap.getOrDefault(SENSOR_TYPE_FACE, null);
-                if (isCurrentFaceAuth(client)) {
-                    if (isUdfpsActivelyAuthing(udfps)) {
-                        // Face auth success while UDFPS is actively authing. No callback, no haptic
-                        // Feedback will be provided after UDFPS result:
-                        // 1) UDFPS succeeds - simply remove this from the queue
-                        // 2) UDFPS rejected - use this face auth success to notify clients
-                        mSuccessfulAuths.add(new SuccessfulAuth(mHandler, mSuccessfulAuths,
-                                currentTimeMillis, SENSOR_TYPE_FACE, client, callback));
-                    } else {
-                        if (mFaceHapticDisabledWhenNonBypass && !face.isKeyguardBypassEnabled()) {
-                            Slog.w(TAG, "Skipping face success haptic");
-                        } else {
-                            callback.sendHapticFeedback();
-                        }
-                        callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
-                        callback.handleLifecycleAfterAuth();
-                    }
-                } else if (isCurrentUdfps(client)) {
-                    if (isFaceScanning()) {
-                        // UDFPS succeeds while face is still scanning
-                        // Cancel face auth and/or prevent it from invoking haptics/callbacks after
-                        face.cancel();
-                    }
-
-                    removeAndFinishAllFaceFromQueue();
-
-                    callback.sendHapticFeedback();
-                    callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
-                    callback.handleLifecycleAfterAuth();
-                } else {
-                    // Capacitive fingerprint sensor (or other)
-                    callback.sendHapticFeedback();
-                    callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
-                    callback.handleLifecycleAfterAuth();
-                }
-            }
-        } else {
-            // Non-keyguard authentication. For example, Fingerprint Settings use of
-            // FingerprintManager for highlighting fingers
-            callback.sendHapticFeedback();
-            callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
-            callback.handleLifecycleAfterAuth();
-        }
-    }
-
-    /**
-     * Notify the coordinator that a rejection has occurred.
-     */
-    public void onAuthenticationRejected(long currentTimeMillis,
-            @NonNull AuthenticationClient<?> client,
-            @LockoutTracker.LockoutMode int lockoutMode,
-            @NonNull Callback callback) {
-        final boolean isUsingSingleModality = isSingleAuthOnly(client);
-
-        if (mAdvancedLogicEnabled && client.isKeyguard()) {
-            if (isUsingSingleModality) {
-                callback.sendHapticFeedback();
-                callback.handleLifecycleAfterAuth();
-            } else {
-                // Multi sensor authentication
-                AuthenticationClient<?> udfps = mClientMap.getOrDefault(SENSOR_TYPE_UDFPS, null);
-                AuthenticationClient<?> face = mClientMap.getOrDefault(SENSOR_TYPE_FACE, null);
-                if (isCurrentFaceAuth(client)) {
-                    if (isUdfpsActivelyAuthing(udfps)) {
-                        // UDFPS should still be running in this case, do not vibrate. However, we
-                        // should notify the callback and finish the client, so that Keyguard and
-                        // BiometricScheduler do not get stuck.
-                        Slog.d(TAG, "Face rejected in multi-sensor auth, udfps: " + udfps);
-                        callback.handleLifecycleAfterAuth();
-                    } else if (isUdfpsAuthAttempted(udfps)) {
-                        // If UDFPS is STATE_STARTED_PAUSED (e.g. finger rejected but can still
-                        // auth after pointer goes down, it means UDFPS encountered a rejection. In
-                        // this case, we need to play the final reject haptic since face auth is
-                        // also done now.
-                        callback.sendHapticFeedback();
-                        callback.handleLifecycleAfterAuth();
-                    } else {
-                        // UDFPS auth has never been attempted.
-                        if (mFaceHapticDisabledWhenNonBypass && !face.isKeyguardBypassEnabled()) {
-                            Slog.w(TAG, "Skipping face reject haptic");
-                        } else {
-                            callback.sendHapticFeedback();
-                        }
-                        callback.handleLifecycleAfterAuth();
-                    }
-                } else if (isCurrentUdfps(client)) {
-                    // Face should either be running, or have already finished
-                    SuccessfulAuth auth = popSuccessfulFaceAuthIfExists(currentTimeMillis);
-                    if (auth != null) {
-                        Slog.d(TAG, "Using recent auth: " + auth);
-                        callback.handleLifecycleAfterAuth();
-
-                        auth.mCallback.sendHapticFeedback();
-                        auth.mCallback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
-                        auth.mCallback.handleLifecycleAfterAuth();
-                    } else {
-                        Slog.d(TAG, "UDFPS rejected in multi-sensor auth");
-                        callback.sendHapticFeedback();
-                        callback.handleLifecycleAfterAuth();
-                    }
-                } else {
-                    Slog.d(TAG, "Unknown client rejected: " + client);
-                    callback.sendHapticFeedback();
-                    callback.handleLifecycleAfterAuth();
-                }
-            }
-        } else if (client.isBiometricPrompt() && !isUsingSingleModality) {
-            if (!isCurrentFaceAuth(client)) {
-                callback.sendHapticFeedback();
-            }
-            callback.handleLifecycleAfterAuth();
-        } else {
-            callback.sendHapticFeedback();
-            callback.handleLifecycleAfterAuth();
-        }
-
-        // Always notify keyguard, otherwise the cached "running" state in KeyguardUpdateMonitor
-        // will get stuck.
-        if (lockoutMode == LockoutTracker.LOCKOUT_NONE) {
-            // Don't send onAuthenticationFailed if we're in lockout, it causes a
-            // janky UI on Keyguard/BiometricPrompt since "authentication failed"
-            // will show briefly and be replaced by "device locked out" message.
-            callback.sendAuthenticationResult(false /* addAuthTokenIfStrong */);
-        }
-    }
-
-    /**
-     * Notify the coordinator that an error has occurred.
-     */
-    public void onAuthenticationError(@NonNull AuthenticationClient<?> client,
-            @BiometricConstants.Errors int error, @NonNull ErrorCallback callback) {
-        final boolean isUsingSingleModality = isSingleAuthOnly(client);
-
-        // Figure out non-coex state
-        final boolean shouldUsuallyVibrate;
-        if (isCurrentFaceAuth(client)) {
-            final boolean notDetectedOnKeyguard = client.isKeyguard() && !client.wasUserDetected();
-            final boolean authAttempted = client.wasAuthAttempted();
-
-            switch (error) {
-                case BiometricConstants.BIOMETRIC_ERROR_TIMEOUT:
-                case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT:
-                case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT:
-                    shouldUsuallyVibrate = authAttempted && !notDetectedOnKeyguard;
-                    break;
-                default:
-                    shouldUsuallyVibrate = false;
-                    break;
-            }
-        } else {
-            shouldUsuallyVibrate = false;
-        }
-
-        // Figure out coex state
-        final boolean hapticSuppressedByCoex;
-        if (mAdvancedLogicEnabled && client.isKeyguard()) {
-            if (isUsingSingleModality) {
-                hapticSuppressedByCoex = false;
-            } else {
-                hapticSuppressedByCoex = isCurrentFaceAuth(client)
-                        && !client.isKeyguardBypassEnabled();
-            }
-        } else if (client.isBiometricPrompt() && !isUsingSingleModality) {
-            hapticSuppressedByCoex = isCurrentFaceAuth(client);
-        } else {
-            hapticSuppressedByCoex = false;
-        }
-
-        // Combine and send feedback if appropriate
-        if (shouldUsuallyVibrate && !hapticSuppressedByCoex) {
-            callback.sendHapticFeedback();
-        } else {
-            Slog.v(TAG, "no haptic shouldUsuallyVibrate: " + shouldUsuallyVibrate
-                    + ", hapticSuppressedByCoex: " + hapticSuppressedByCoex);
-        }
-    }
-
-    @Nullable
-    private SuccessfulAuth popSuccessfulFaceAuthIfExists(long currentTimeMillis) {
-        for (SuccessfulAuth auth : mSuccessfulAuths) {
-            if (currentTimeMillis - auth.mAuthTimestamp >= SUCCESSFUL_AUTH_VALID_DURATION_MS) {
-                // TODO(b/193089985): This removes the auth but does not notify the client with
-                //  an appropriate lifecycle event (such as ERROR_CANCELED), and violates the
-                //  API contract. However, this might be OK for now since the validity duration
-                //  is way longer than the time it takes to auth with fingerprint.
-                Slog.e(TAG, "Removing stale auth: " + auth);
-                mSuccessfulAuths.remove(auth);
-            } else if (auth.mSensorType == SENSOR_TYPE_FACE) {
-                mSuccessfulAuths.remove(auth);
-                return auth;
-            }
-        }
-        return null;
-    }
-
-    private void removeAndFinishAllFaceFromQueue() {
-        // Note that these auth are all successful, but have never notified the client (e.g.
-        // keyguard). To comply with the authentication lifecycle, we must notify the client that
-        // auth is "done". The safest thing to do is to send ERROR_CANCELED.
-        for (SuccessfulAuth auth : mSuccessfulAuths) {
-            if (auth.mSensorType == SENSOR_TYPE_FACE) {
-                Slog.d(TAG, "Removing from queue, canceling, and finishing: " + auth);
-                auth.mCallback.sendAuthenticationCanceled();
-                auth.mCallback.handleLifecycleAfterAuth();
-                mSuccessfulAuths.remove(auth);
-            }
-        }
-    }
-
-    private boolean isCurrentFaceAuth(@NonNull AuthenticationClient<?> client) {
-        return client == mClientMap.getOrDefault(SENSOR_TYPE_FACE, null);
-    }
-
-    private boolean isCurrentUdfps(@NonNull AuthenticationClient<?> client) {
-        return client == mClientMap.getOrDefault(SENSOR_TYPE_UDFPS, null);
-    }
-
-    private boolean isFaceScanning() {
-        AuthenticationClient<?> client = mClientMap.getOrDefault(SENSOR_TYPE_FACE, null);
-        return client != null && client.getState() == AuthenticationClient.STATE_STARTED;
-    }
-
-    private static boolean isUdfpsActivelyAuthing(@Nullable AuthenticationClient<?> client) {
-        if (client instanceof Udfps) {
-            return client.getState() == AuthenticationClient.STATE_STARTED;
-        }
-        return false;
-    }
-
-    private static boolean isUdfpsAuthAttempted(@Nullable AuthenticationClient<?> client) {
-        if (client instanceof Udfps) {
-            return client.getState() == AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED;
-        }
-        return false;
-    }
-
-    private boolean isUnknownClient(@NonNull AuthenticationClient<?> client) {
-        for (AuthenticationClient<?> c : mClientMap.values()) {
-            if (c == client) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean isSingleAuthOnly(@NonNull AuthenticationClient<?> client) {
-        if (mClientMap.values().size() != 1) {
-            return false;
-        }
-
-        for (AuthenticationClient<?> c : mClientMap.values()) {
-            if (c != client) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean hasMultipleSuccessfulAuthentications() {
-        int count = 0;
-        for (AuthenticationClient<?> c : mClientMap.values()) {
-            if (c.wasAuthSuccessful()) {
-                count++;
-            }
-            if (count > 1) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("Enabled: ").append(mAdvancedLogicEnabled);
-        sb.append(", Face Haptic Disabled: ").append(mFaceHapticDisabledWhenNonBypass);
-        sb.append(", Queue size: " ).append(mSuccessfulAuths.size());
-        for (SuccessfulAuth auth : mSuccessfulAuths) {
-            sb.append(", Auth: ").append(auth.toString());
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
index ae75b7d..a486d16 100644
--- a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
@@ -95,10 +95,9 @@
             @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
             @NonNull IBiometricService biometricService,
             @NonNull CurrentUserRetriever currentUserRetriever,
-            @NonNull UserSwitchCallback userSwitchCallback,
-            @NonNull CoexCoordinator coexCoordinator) {
+            @NonNull UserSwitchCallback userSwitchCallback) {
         super(tag, handler, sensorType, gestureAvailabilityDispatcher, biometricService,
-                LOG_NUM_RECENT_OPERATIONS, coexCoordinator);
+                LOG_NUM_RECENT_OPERATIONS);
 
         mCurrentUserRetriever = currentUserRetriever;
         mUserSwitchCallback = userSwitchCallback;
@@ -112,7 +111,7 @@
         this(tag, new Handler(Looper.getMainLooper()), sensorType, gestureAvailabilityDispatcher,
                 IBiometricService.Stub.asInterface(
                         ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
-                currentUserRetriever, userSwitchCallback, CoexCoordinator.getInstance());
+                currentUserRetriever, userSwitchCallback);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index ca4b747..e18e31ec 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -274,7 +274,6 @@
 
     @Override
     public void onLockoutTimed(long durationMillis) {
-        super.onLockoutTimed(durationMillis);
         mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
         // Lockout metrics are logged as an error code.
         final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT;
@@ -290,7 +289,6 @@
 
     @Override
     public void onLockoutPermanent() {
-        super.onLockoutPermanent();
         mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
         // Lockout metrics are logged as an error code.
         final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 1688f96..f7d94c9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -315,21 +315,27 @@
     private ICancellationSignal doAuthenticate() throws RemoteException {
         final AidlSession session = getFreshDaemon();
 
+        final OperationContext opContext = getOperationContext();
+        getBiometricContext().subscribe(opContext, ctx -> {
+            if (session.hasContextMethods()) {
+                try {
+                    session.getSession().onContextChanged(ctx);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Unable to notify context changed", e);
+                }
+            }
+
+            // TODO(b/243836005): this should come via ctx
+            final boolean isAwake = getBiometricContext().isAwake();
+            if (isAwake) {
+                mALSProbeCallback.getProbe().enable();
+            } else {
+                mALSProbeCallback.getProbe().disable();
+            }
+        });
+
         if (session.hasContextMethods()) {
-            final OperationContext opContext = getOperationContext();
-            final ICancellationSignal cancel =
-                    session.getSession().authenticateWithContext(mOperationId, opContext);
-            getBiometricContext()
-                    .subscribe(
-                            opContext,
-                            ctx -> {
-                                try {
-                                    session.getSession().onContextChanged(ctx);
-                                } catch (RemoteException e) {
-                                    Slog.e(TAG, "Unable to notify context changed", e);
-                                }
-                            });
-            return cancel;
+            return session.getSession().authenticateWithContext(mOperationId, opContext);
         } else {
             return session.getSession().authenticate(mOperationId);
         }
@@ -360,7 +366,6 @@
         try {
             mIsPointerDown = true;
             mState = STATE_STARTED;
-            mALSProbeCallback.getProbe().enable();
 
             final AidlSession session = getFreshDaemon();
             if (session.hasContextMethods()) {
@@ -389,7 +394,6 @@
         try {
             mIsPointerDown = false;
             mState = STATE_STARTED_PAUSED_ATTEMPTED;
-            mALSProbeCallback.getProbe().disable();
 
             final AidlSession session = getFreshDaemon();
             if (session.hasContextMethods()) {
@@ -424,7 +428,6 @@
 
     @Override
     public void onLockoutTimed(long durationMillis) {
-        super.onLockoutTimed(durationMillis);
         mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
         // Lockout metrics are logged as an error code.
         final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
@@ -448,7 +451,6 @@
 
     @Override
     public void onLockoutPermanent() {
-        super.onLockoutPermanent();
         mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
         // Lockout metrics are logged as an error code.
         final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index 7d2cf9d..e0393b5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -94,7 +94,7 @@
         mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
         mMaxTemplatesPerUser = maxTemplatesPerUser;
 
-        mALSProbeCallback = getLogger().getAmbientLightProbe(false /* startWithClient */);
+        mALSProbeCallback = getLogger().getAmbientLightProbe(true /* startWithClient */);
 
         mEnrollReason = enrollReason;
         if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) {
@@ -216,7 +216,6 @@
     public void onPointerDown(int x, int y, float minor, float major) {
         try {
             mIsPointerDown = true;
-            mALSProbeCallback.getProbe().enable();
 
             final AidlSession session = getFreshDaemon();
             if (session.hasContextMethods()) {
@@ -240,7 +239,6 @@
     public void onPointerUp() {
         try {
             mIsPointerDown = false;
-            mALSProbeCallback.getProbe().disable();
 
             final AidlSession session = getFreshDaemon();
             if (session.hasContextMethods()) {
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 25d0752..c835d2f 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -116,8 +116,10 @@
             luxLevels = getLuxLevels(resources.getIntArray(
                     com.android.internal.R.array.config_autoBrightnessLevelsIdle));
         } else {
-            brightnessLevelsNits = displayDeviceConfig.getAutoBrightnessBrighteningLevelsNits();
-            luxLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevelsLux();
+            brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
+                    com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
+            luxLevels = getLuxLevels(resources.getIntArray(
+                    com.android.internal.R.array.config_autoBrightnessLevels));
         }
 
         // Display independent, mode independent values
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 3b627ef..4f3fd64 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
 import android.os.Environment;
@@ -150,22 +149,12 @@
  *      </quirks>
  *
  *      <autoBrightness>
- *          <brighteningLightDebounceMillis>
+ *           <brighteningLightDebounceMillis>
  *              2000
- *          </brighteningLightDebounceMillis>
+ *           </brighteningLightDebounceMillis>
  *          <darkeningLightDebounceMillis>
  *              1000
  *          </darkeningLightDebounceMillis>
- *          <displayBrightnessMapping>
- *              <displayBrightnessPoint>
- *                  <lux>50</lux>
- *                  <nits>45</nits>
- *              </displayBrightnessPoint>
- *              <displayBrightnessPoint>
- *                  <lux>80</lux>
- *                  <nits>75</nits>
- *              </displayBrightnessPoint>
- *          </displayBrightnessMapping>
  *      </autoBrightness>
  *
  *      <screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease>
@@ -279,39 +268,6 @@
     // for the corresponding values above
     private float[] mBrightness;
 
-
-    /**
-     * Array of desired screen brightness in nits corresponding to the lux values
-     * in the mBrightnessLevelsLux array. The display brightness is defined as the
-     * measured brightness of an all-white image. The brightness values must be non-negative and
-     * non-decreasing. This must be overridden in platform specific overlays
-     */
-    private float[] mBrightnessLevelsNits;
-
-    /**
-     * Array of light sensor lux values to define our levels for auto backlight
-     * brightness support.
-     * The N entries of this array define N + 1 control points as follows:
-     * (1-based arrays)
-     *
-     * Point 1:            (0, value[1]):             lux <= 0
-     * Point 2:     (level[1], value[2]):  0        < lux <= level[1]
-     * Point 3:     (level[2], value[3]):  level[2] < lux <= level[3]
-     * ...
-     * Point N+1: (level[N], value[N+1]):  level[N] < lux
-     *
-     * The control points must be strictly increasing.  Each control point
-     * corresponds to an entry in the brightness backlight values arrays.
-     * For example, if lux == level[1] (first element of the levels array)
-     * then the brightness will be determined by value[2] (second element
-     * of the brightness values array).
-     *
-     * Spline interpolation is used to determine the auto-brightness
-     * backlight values for lux levels between these control points.
-     *
-     */
-    private float[] mBrightnessLevelsLux;
-
     private float mBacklightMinimum = Float.NaN;
     private float mBacklightMaximum = Float.NaN;
     private float mBrightnessDefault = Float.NaN;
@@ -705,20 +661,6 @@
         return mAutoBrightnessBrighteningLightDebounce;
     }
 
-    /**
-     * @return Auto brightness brightening ambient lux levels
-     */
-    public float[] getAutoBrightnessBrighteningLevelsLux() {
-        return mBrightnessLevelsLux;
-    }
-
-    /**
-     * @return Auto brightness brightening nits levels
-     */
-    public float[] getAutoBrightnessBrighteningLevelsNits() {
-        return mBrightnessLevelsNits;
-    }
-
     @Override
     public String toString() {
         return "DisplayDeviceConfig{"
@@ -761,8 +703,6 @@
                 + mAutoBrightnessBrighteningLightDebounce
                 + ", mAutoBrightnessDarkeningLightDebounce= "
                 + mAutoBrightnessDarkeningLightDebounce
-                + ", mBrightnessLevelsLux= " + Arrays.toString(mBrightnessLevelsLux)
-                + ", mBrightnessLevelsNits= " + Arrays.toString(mBrightnessLevelsNits)
                 + "}";
     }
 
@@ -839,7 +779,6 @@
         loadBrightnessRampsFromConfigXml();
         loadAmbientLightSensorFromConfigXml();
         setProxSensorUnspecified();
-        loadAutoBrightnessConfigsFromConfigXml();
         mLoadedFrom = "<config.xml>";
     }
 
@@ -1052,7 +991,6 @@
     private void loadAutoBrightnessConfigValues(DisplayConfiguration config) {
         loadAutoBrightnessBrighteningLightDebounce(config.getAutoBrightness());
         loadAutoBrightnessDarkeningLightDebounce(config.getAutoBrightness());
-        loadAutoBrightnessDisplayBrightnessMapping(config.getAutoBrightness());
     }
 
     /**
@@ -1085,33 +1023,6 @@
         }
     }
 
-    /**
-     * Loads the auto-brightness display brightness mappings. Internally, this takes care of
-     * loading the value from the display config, and if not present, falls back to config.xml.
-     */
-    private void loadAutoBrightnessDisplayBrightnessMapping(AutoBrightness autoBrightnessConfig) {
-        if (autoBrightnessConfig == null
-                || autoBrightnessConfig.getDisplayBrightnessMapping() == null) {
-            mBrightnessLevelsNits = getFloatArray(mContext.getResources()
-                    .obtainTypedArray(com.android.internal.R.array
-                            .config_autoBrightnessDisplayValuesNits));
-            mBrightnessLevelsLux = getFloatArray(mContext.getResources()
-                    .obtainTypedArray(com.android.internal.R.array
-                            .config_autoBrightnessLevels));
-        } else {
-            final int size = autoBrightnessConfig.getDisplayBrightnessMapping()
-                    .getDisplayBrightnessPoint().size();
-            mBrightnessLevelsNits = new float[size];
-            mBrightnessLevelsLux = new float[size];
-            for (int i = 0; i < size; i++) {
-                mBrightnessLevelsNits[i] = autoBrightnessConfig.getDisplayBrightnessMapping()
-                        .getDisplayBrightnessPoint().get(i).getNits().floatValue();
-                mBrightnessLevelsLux[i] = autoBrightnessConfig.getDisplayBrightnessMapping()
-                        .getDisplayBrightnessPoint().get(i).getLux().floatValue();
-            }
-        }
-    }
-
     private void loadBrightnessMapFromConfigXml() {
         // Use the config.xml mapping
         final Resources res = mContext.getResources();
@@ -1337,10 +1248,6 @@
                 com.android.internal.R.string.config_displayLightSensorType);
     }
 
-    private void loadAutoBrightnessConfigsFromConfigXml() {
-        loadAutoBrightnessDisplayBrightnessMapping(null /*AutoBrightnessConfig*/);
-    }
-
     private void loadAmbientLightSensorFromDdc(DisplayConfiguration config) {
         final SensorDetails sensorDetails = config.getLightSensor();
         if (sensorDetails != null) {
@@ -1483,22 +1390,6 @@
         }
     }
 
-    /**
-     * Extracts a float array from the specified {@link TypedArray}.
-     *
-     * @param array The array to convert.
-     * @return the given array as a float array.
-     */
-    public static float[] getFloatArray(TypedArray array) {
-        final int n = array.length();
-        float[] vals = new float[n];
-        for (int i = 0; i < n; i++) {
-            vals[i] = array.getFloat(i, PowerManager.BRIGHTNESS_OFF_FLOAT);
-        }
-        array.recycle();
-        return vals;
-    }
-
     static class SensorData {
         public String type;
         public String name;
diff --git a/services/core/java/com/android/server/logcat/OWNERS b/services/core/java/com/android/server/logcat/OWNERS
index 9588fa9..87d30f3 100644
--- a/services/core/java/com/android/server/logcat/OWNERS
+++ b/services/core/java/com/android/server/logcat/OWNERS
@@ -1,5 +1,7 @@
 cbrubaker@google.com
 eunjeongshin@google.com
+georgechan@google.com
 jsharkey@google.com
 vishwath@google.com
 wenhaowang@google.com
+xiaozhenl@google.com
diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
index c12dc8e..a5c762a 100644
--- a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
+++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
@@ -119,7 +119,7 @@
         ComponentName componentName = getComponentName(pendingIntent, componentType);
         if (componentName != null) {
             if (!TextUtils.equals(componentName.getPackageName(), sessionPackageName)) {
-                EventLog.writeEvent(0x534e4554, "238177121", -1, ""); // SafetyNet Logging.
+                EventLog.writeEvent(0x534e4554, "238177121", -1, "");
                 throw new IllegalArgumentException("ComponentName does not belong to "
                         + "sessionPackageName. sessionPackageName = " + sessionPackageName
                         + ", ComponentName pkg = " + componentName.getPackageName());
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 4f8771a..1ee9a87 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -914,7 +914,16 @@
         }
 
         @Override
-        public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException {
+        public void setMediaButtonReceiver(PendingIntent pi, String sessionPackageName)
+                throws RemoteException {
+            //mPackageName has been verified in MediaSessionService.enforcePackageName().
+            if (!TextUtils.equals(sessionPackageName, mPackageName)) {
+                EventLog.writeEvent(0x534e4554, "238177121", -1, "");
+                throw new IllegalArgumentException("sessionPackageName name does not match "
+                        + "package name provided to MediaSessionRecord. sessionPackageName = "
+                        + sessionPackageName + ", pkg = "
+                        + mPackageName);
+            }
             final long token = Binder.clearCallingIdentity();
             try {
                 if ((mPolicies & MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER)
@@ -922,7 +931,7 @@
                     return;
                 }
                 mMediaButtonReceiverHolder =
-                        MediaButtonReceiverHolder.create(mContext, mUserId, pi, mPackageName);
+                        MediaButtonReceiverHolder.create(mContext, mUserId, pi, sessionPackageName);
                 mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -936,7 +945,7 @@
                 //mPackageName has been verified in MediaSessionService.enforcePackageName().
                 if (receiver != null && !TextUtils.equals(
                         mPackageName, receiver.getPackageName())) {
-                    EventLog.writeEvent(0x534e4554, "238177121", -1, ""); // SafetyNet Logging.
+                    EventLog.writeEvent(0x534e4554, "238177121", -1, "");
                     throw new IllegalArgumentException("receiver does not belong to "
                             + "package name provided to MediaSessionRecord. Pkg = " + mPackageName
                             + ", Receiver Pkg = " + receiver.getPackageName());
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
index 09035cd..15c9ba9 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
@@ -37,6 +37,7 @@
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.util.Log;
+import android.util.SparseArray;
 
 import com.android.internal.util.Preconditions;
 
@@ -829,17 +830,41 @@
             @Override
             public void binderDied() {
                 // This is called whenever our client process dies.
+                SparseArray<ModelState.Activity> cachedMap =
+                        new SparseArray<ModelState.Activity>();
                 synchronized (SoundTriggerMiddlewareValidation.this) {
-                    try {
-                        // Gracefully stop all active recognitions and unload the models.
+                        // Copy the relevant state under the lock, so we can call back without
+                        // holding a lock. This exposes us to a potential race, but the client is
+                        // dead so we don't expect one.
+                        // TODO(240613068) A more resilient fix for this.
                         for (Map.Entry<Integer, ModelState> entry :
                                 mLoadedModels.entrySet()) {
-                            if (entry.getValue().activityState == ModelState.Activity.ACTIVE) {
-                                mDelegate.stopRecognition(entry.getKey());
-                            }
-                            mDelegate.unloadModel(entry.getKey());
+                            cachedMap.put(entry.getKey(), entry.getValue().activityState);
                         }
-                        // Detach.
+                }
+                try {
+                    // Gracefully stop all active recognitions and unload the models.
+                    for (int i = 0; i < cachedMap.size(); i++) {
+                        if (cachedMap.valueAt(i) == ModelState.Activity.ACTIVE) {
+                            mDelegate.stopRecognition(cachedMap.keyAt(i));
+                        }
+                        mDelegate.unloadModel(cachedMap.keyAt(i));
+                    }
+                } catch (Exception e) {
+                    throw handleException(e);
+                }
+                synchronized (SoundTriggerMiddlewareValidation.this) {
+                   // Check if state updated unexpectedly to log race conditions.
+                    for (Map.Entry<Integer, ModelState> entry : mLoadedModels.entrySet()) {
+                        if (cachedMap.get(entry.getKey()) != entry.getValue().activityState) {
+                            Log.e(TAG, "Unexpected state update in binderDied. Race occurred!");
+                        }
+                    }
+                    if (mLoadedModels.size() != cachedMap.size()) {
+                        Log.e(TAG, "Unexpected state update in binderDied. Race occurred!");
+                    }
+                    try {
+                        // Detach
                         detachInternal();
                     } catch (Exception e) {
                         throw handleException(e);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f8f94f6..58e1d05 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1582,13 +1582,6 @@
 
         if (newParent != null && isState(RESUMED)) {
             newParent.setResumedActivity(this, "onParentChanged");
-            if (mStartingWindow != null && mStartingData != null
-                    && mStartingData.mAssociatedTask == null && newParent.isEmbedded()) {
-                // The starting window should keep covering its task when the activity is
-                // reparented to a task fragment that may not fill the task bounds.
-                associateStartingDataWithTask();
-                attachStartingSurfaceToAssociatedTask();
-            }
             mImeInsetsFrozenUntilStartInput = false;
         }
 
@@ -2679,14 +2672,17 @@
         }
     }
 
+    /** Called when the starting window is added to this activity. */
     void attachStartingWindow(@NonNull WindowState startingWindow) {
         startingWindow.mStartingData = mStartingData;
         mStartingWindow = startingWindow;
+        // The snapshot type may have called associateStartingDataWithTask().
         if (mStartingData != null && mStartingData.mAssociatedTask != null) {
             attachStartingSurfaceToAssociatedTask();
         }
     }
 
+    /** Makes starting window always fill the associated task. */
     private void attachStartingSurfaceToAssociatedTask() {
         // Associate the configuration of starting window with the task.
         overrideConfigurationPropagation(mStartingWindow, mStartingData.mAssociatedTask);
@@ -2694,6 +2690,7 @@
                 mStartingData.mAssociatedTask.mSurfaceControl);
     }
 
+    /** Called when the starting window is not added yet but its data is known to fill the task. */
     private void associateStartingDataWithTask() {
         mStartingData.mAssociatedTask = task;
         task.forAllActivities(r -> {
@@ -2703,6 +2700,16 @@
         });
     }
 
+    /** Associates and attaches an added starting window to the current task. */
+    void associateStartingWindowWithTaskIfNeeded() {
+        if (mStartingWindow == null || mStartingData == null
+                || mStartingData.mAssociatedTask != null) {
+            return;
+        }
+        associateStartingDataWithTask();
+        attachStartingSurfaceToAssociatedTask();
+    }
+
     void removeStartingWindow() {
         boolean prevEligibleForLetterboxEducation = isEligibleForLetterboxEducation();
 
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 619d693..9ad62af 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1866,6 +1866,16 @@
         final ActivityRecord targetTaskTop = newTask
                 ? null : targetTask.getTopNonFinishingActivity();
         if (targetTaskTop != null) {
+            // Removes the existing singleInstance activity in another task (if any) while
+            // launching a singleInstance activity on sourceRecord's task.
+            if (LAUNCH_SINGLE_INSTANCE == mLaunchMode && mSourceRecord != null
+                    && targetTask == mSourceRecord.getTask()) {
+                final ActivityRecord activity = mRootWindowContainer.findActivity(mIntent,
+                        mStartActivity.info, false);
+                if (activity != null && activity.getTask() != targetTask) {
+                    activity.destroyIfPossible("Removes redundant singleInstance");
+                }
+            }
             // Recycle the target task for this launch.
             startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
             if (startResult != START_SUCCESS) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1c90bba..6ee0186 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3188,8 +3188,12 @@
             if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
             mPointerEventDispatcher.dispose();
             setRotationAnimation(null);
+            // Unlink death from remote to clear the reference from binder -> mRemoteInsetsDeath
+            // -> this DisplayContent.
+            setRemoteInsetsController(null);
             mWmService.mAnimator.removeDisplayLocked(mDisplayId);
             mOverlayLayer.release();
+            mWindowingLayer.release();
             mInputMonitor.onDisplayRemoved();
             mWmService.mDisplayNotificationController.dispatchDisplayRemoved(this);
             mWmService.mAccessibilityController.onDisplayRemoved(mDisplayId);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index e38f5fe..de135a3 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1436,6 +1436,13 @@
         final TaskFragment childTaskFrag = child.asTaskFragment();
         if (childTaskFrag != null && childTaskFrag.asTask() == null) {
             childTaskFrag.setMinDimensions(mMinWidth, mMinHeight);
+
+            // The starting window should keep covering its task when a pure TaskFragment is added
+            // because its bounds may not fill the task.
+            final ActivityRecord top = getTopMostActivity();
+            if (top != null) {
+                top.associateStartingWindowWithTaskIfNeeded();
+            }
         }
     }
 
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 4078996..24101dd 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -89,6 +89,7 @@
 
 cc_defaults {
     name: "libservices.core-libs",
+    defaults: ["android.hardware.graphics.common-ndk_shared"],
     shared_libs: [
         "libadb_pairing_server",
         "libadb_pairing_connection",
@@ -158,7 +159,6 @@
         "android.hardware.graphics.bufferqueue@1.0",
         "android.hardware.graphics.bufferqueue@2.0",
         "android.hardware.graphics.common@1.2",
-        "android.hardware.graphics.common-V3-ndk",
         "android.hardware.graphics.mapper@4.0",
         "android.hardware.input.processor-V1-ndk",
         "android.hardware.ir@1.0",
diff --git a/services/core/xsd/display-device-config/autobrightness.xsd b/services/core/xsd/display-device-config/autobrightness.xsd
new file mode 100644
index 0000000..477625a
--- /dev/null
+++ b/services/core/xsd/display-device-config/autobrightness.xsd
@@ -0,0 +1,33 @@
+<!--
+    Copyright (C) 2022 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<xs:schema version="2.0"
+           elementFormDefault="qualified"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:complexType name="autoBrightness">
+        <xs:sequence>
+            <!-- Sets the debounce for autoBrightness brightening in millis-->
+            <xs:element name="brighteningLightDebounceMillis" type="xs:nonNegativeInteger"
+                        minOccurs="0" maxOccurs="1">
+                <xs:annotation name="final"/>
+            </xs:element>
+            <!-- Sets the debounce for autoBrightness darkening in millis-->
+            <xs:element name="darkeningLightDebounceMillis" type="xs:nonNegativeInteger"
+                        minOccurs="0" maxOccurs="1">
+                <xs:annotation name="final"/>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+</xs:schema>
\ No newline at end of file
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 98f83d8..bea5e2c 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -23,6 +23,7 @@
 <xs:schema version="2.0"
            elementFormDefault="qualified"
            xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:include schemaLocation="autobrightness.xsd" />
     <xs:element name="displayConfiguration">
         <xs:complexType>
             <xs:sequence>
@@ -342,74 +343,4 @@
             <xs:annotation name="final"/>
         </xs:element>
     </xs:complexType>
-
-    <xs:complexType name="autoBrightness">
-        <xs:sequence>
-            <!-- Sets the debounce for autoBrightness brightening in millis-->
-            <xs:element name="brighteningLightDebounceMillis" type="xs:nonNegativeInteger"
-                        minOccurs="0" maxOccurs="1">
-                <xs:annotation name="final"/>
-            </xs:element>
-            <!-- Sets the debounce for autoBrightness darkening in millis-->
-            <xs:element name="darkeningLightDebounceMillis" type="xs:nonNegativeInteger"
-                        minOccurs="0" maxOccurs="1">
-                <xs:annotation name="final"/>
-            </xs:element>
-            <!-- Sets the brightness mapping of the desired screen brightness in nits to the
-             corresponding lux for the current display -->
-            <xs:element name="displayBrightnessMapping" type="displayBrightnessMapping"
-                        minOccurs="0" maxOccurs="1">
-                <xs:annotation name="final"/>
-            </xs:element>
-        </xs:sequence>
-    </xs:complexType>
-
-    <!-- Represents the brightness mapping of the desired screen brightness in nits to the
-             corresponding lux for the current display -->
-    <xs:complexType name="displayBrightnessMapping">
-        <xs:sequence>
-            <!-- Sets the list of display brightness points, each representing the desired screen
-            brightness in nits to the corresponding lux for the current display
-
-            The N entries of this array define N + 1 control points as follows:
-            (1-based arrays)
-
-            Point 1:            (0, nits[1]):             currentLux <= 0
-            Point 2:     (lux[1], nits[2]):       0 < currentLux <= lux[1]
-            Point 3:     (lux[2], nits[3]):  lux[2] < currentLux <= lux[3]
-            ...
-            Point N+1: (lux[N], nits[N+1]):            lux[N] < currentLux
-
-            The control points must be strictly increasing. Each control point
-            corresponds to an entry in the brightness backlight values arrays.
-            For example, if currentLux == lux[1] (first element of the levels array)
-            then the brightness will be determined by nits[2] (second element
-            of the brightness values array).
-            -->
-            <xs:element name="displayBrightnessPoint" type="displayBrightnessPoint"
-                        minOccurs="1" maxOccurs="unbounded">
-                <xs:annotation name="final"/>
-            </xs:element>
-        </xs:sequence>
-    </xs:complexType>
-
-    <!-- Represents a point in the display brightness mapping, representing the lux level from the
-    light sensor to the desired screen brightness in nits at this level  -->
-    <xs:complexType name="displayBrightnessPoint">
-        <xs:sequence>
-            <!-- The lux level from the light sensor. This must be a non-negative integer -->
-            <xs:element name="lux" type="xs:nonNegativeInteger"
-                        minOccurs="1" maxOccurs="1">
-                <xs:annotation name="final"/>
-            </xs:element>
-
-            <!-- Desired screen brightness in nits corresponding to the suggested lux values.
-             The display brightness is defined as the measured brightness of an all-white image.
-             This must be a non-negative integer -->
-            <xs:element name="nits" type="xs:nonNegativeInteger"
-                        minOccurs="1" maxOccurs="1">
-                <xs:annotation name="final"/>
-            </xs:element>
-        </xs:sequence>
-    </xs:complexType>
 </xs:schema>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index e5d2617..e9a9269 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -5,10 +5,8 @@
     ctor public AutoBrightness();
     method public final java.math.BigInteger getBrighteningLightDebounceMillis();
     method public final java.math.BigInteger getDarkeningLightDebounceMillis();
-    method public final com.android.server.display.config.DisplayBrightnessMapping getDisplayBrightnessMapping();
     method public final void setBrighteningLightDebounceMillis(java.math.BigInteger);
     method public final void setDarkeningLightDebounceMillis(java.math.BigInteger);
-    method public final void setDisplayBrightnessMapping(com.android.server.display.config.DisplayBrightnessMapping);
   }
 
   public class BrightnessThresholds {
@@ -45,19 +43,6 @@
     method public java.util.List<com.android.server.display.config.Density> getDensity();
   }
 
-  public class DisplayBrightnessMapping {
-    ctor public DisplayBrightnessMapping();
-    method public final java.util.List<com.android.server.display.config.DisplayBrightnessPoint> getDisplayBrightnessPoint();
-  }
-
-  public class DisplayBrightnessPoint {
-    ctor public DisplayBrightnessPoint();
-    method public final java.math.BigInteger getLux();
-    method public final java.math.BigInteger getNits();
-    method public final void setLux(java.math.BigInteger);
-    method public final void setNits(java.math.BigInteger);
-  }
-
   public class DisplayConfiguration {
     ctor public DisplayConfiguration();
     method @NonNull public final com.android.server.display.config.Thresholds getAmbientBrightnessChangeThresholds();
diff --git a/services/tests/mockingservicestests/jni/Android.bp b/services/tests/mockingservicestests/jni/Android.bp
index f454ac7..f1dc1fa 100644
--- a/services/tests/mockingservicestests/jni/Android.bp
+++ b/services/tests/mockingservicestests/jni/Android.bp
@@ -10,6 +10,8 @@
 cc_library_shared {
     name: "libmockingservicestestjni",
 
+    defaults: ["android.hardware.graphics.common-ndk_shared"],
+
     cflags: [
         "-Wall",
         "-Werror",
@@ -48,7 +50,6 @@
         "android.hardware.graphics.bufferqueue@1.0",
         "android.hardware.graphics.bufferqueue@2.0",
         "android.hardware.graphics.common@1.2",
-        "android.hardware.graphics.common-V3-ndk",
         "android.hardware.graphics.mapper@4.0",
         "android.hidl.token@1.0-utils",
     ],
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java
index 03eff2a..e170e98 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java
@@ -258,7 +258,7 @@
                                 PROVIDER_A_SERVICE_A,
                                 PROVIDER_A_SERVICE_C));
         FakeGameServiceProviderInstance instanceB =
-                seedConfigurationForUser(USER_10, configurationA);
+                seedConfigurationForUser(USER_10, configurationB);
         Intent intent = new Intent();
         intent.setData(Uri.parse("package:" + PROVIDER_A_PACKAGE_NAME));
         broadcastReceiverArgumentCaptor.getValue().onReceive(mMockContext, intent);
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
index e4f9eaf..3f16a98 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
@@ -28,7 +28,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -36,7 +35,6 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
 
-import android.Manifest;
 import android.annotation.Nullable;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManagerInternal;
@@ -98,7 +96,6 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Objects;
 import java.util.function.Consumer;
 
 
@@ -361,7 +358,6 @@
             throws Exception {
         mGameServiceProviderInstance.start();
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         assertThat(mFakeGameSessionService.getCapturedCreateInvocations()).isEmpty();
@@ -383,7 +379,6 @@
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSessionService.CapturedCreateInvocation capturedCreateInvocation =
@@ -398,7 +393,6 @@
         mGameServiceProviderInstance.start();
         dispatchTaskCreated(10, GAME_A_MAIN_ACTIVITY);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         assertThat(mFakeGameSessionService.getCapturedCreateInvocations()).isEmpty();
@@ -408,7 +402,6 @@
     public void gameTaskStartedAndSessionRequested_createsGameSession() throws Exception {
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -426,9 +419,7 @@
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         CreateGameSessionRequest expectedCreateGameSessionRequest = new CreateGameSessionRequest(10,
@@ -442,7 +433,6 @@
     public void gameSessionSuccessfullyCreated_createsTaskOverlay() throws Exception {
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -462,7 +452,6 @@
         startTask(10, GAME_A_MAIN_ACTIVITY);
         startProcessForPackage(gameProcessId, GAME_A_PACKAGE);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -488,7 +477,6 @@
         startTask(11, GAME_A_MAIN_ACTIVITY);
         startProcessForPackage(gameProcessId, GAME_A_PACKAGE);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
         mFakeGameService.requestCreateGameSession(11);
 
@@ -522,7 +510,6 @@
         startProcessForPackage(firstGameProcessId, GAME_A_PACKAGE);
         startProcessForPackage(secondGameProcessId, GAME_A_PACKAGE);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -551,7 +538,6 @@
         startTask(10, GAME_A_MAIN_ACTIVITY);
         startProcessForPackage(firstGameProcessId, GAME_A_PACKAGE);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -583,7 +569,6 @@
         startTask(11, GAME_A_MAIN_ACTIVITY);
         startProcessForPackage(firstGameProcessId, GAME_A_PACKAGE);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
 
         mFakeGameService.requestCreateGameSession(10);
         mFakeGameService.requestCreateGameSession(11);
@@ -624,7 +609,6 @@
         startTask(10, GAME_A_MAIN_ACTIVITY);
         startProcessForPackage(gameProcessId, GAME_A_PACKAGE);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
 
         // No game session should be created.
         assertThat(mFakeGameSessionService.getCapturedCreateInvocations()).isEmpty();
@@ -636,7 +620,6 @@
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -677,7 +660,6 @@
     public void systemBarsTransientShownDueToGesture_hasGameSession_propagatesToGameSession() {
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -699,7 +681,6 @@
     public void systemBarsTransientShownButNotGesture_hasGameSession_notPropagatedToGameSession() {
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -721,7 +702,6 @@
     public void gameTaskFocused_propagatedToGameSession() throws Exception {
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -747,7 +727,6 @@
 
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -764,7 +743,6 @@
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         dispatchTaskRemoved(10);
@@ -782,7 +760,6 @@
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -800,7 +777,6 @@
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -830,7 +806,6 @@
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -851,7 +826,6 @@
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -879,7 +853,6 @@
         startTask(10, GAME_A_MAIN_ACTIVITY);
         startTask(11, GAME_A_MAIN_ACTIVITY);
 
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -897,7 +870,6 @@
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -925,7 +897,6 @@
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -955,7 +926,6 @@
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -989,19 +959,10 @@
     }
 
     @Test
-    public void createGameSession_failurePermissionDenied() throws Exception {
-        mGameServiceProviderInstance.start();
-        startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionDenied(Manifest.permission.MANAGE_GAME_ACTIVITY);
-        assertThrows(SecurityException.class, () -> mFakeGameService.requestCreateGameSession(10));
-    }
-
-    @Test
     public void gameSessionServiceDies_severalActiveGameSessions_destroysGameSessions() {
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -1030,7 +991,6 @@
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -1058,7 +1018,6 @@
     public void takeScreenshot_failureNoBitmapCaptured() throws Exception {
         mGameServiceProviderInstance.start();
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -1093,7 +1052,6 @@
                 any(), any(), any(), anyInt(), anyInt(), any(), anyInt(), any(), any());
         mGameServiceProviderInstance.start();
         startTask(taskId, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(taskId);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -1113,7 +1071,6 @@
 
     @Test
     public void restartGame_taskIdAssociatedWithGame_restartsTargetGame() throws Exception {
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         Intent launchIntent = new Intent("com.test.ACTION_LAUNCH_GAME_PACKAGE")
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         when(mMockPackageManager.getLaunchIntentForPackage(GAME_A_PACKAGE))
@@ -1122,7 +1079,6 @@
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -1148,11 +1104,9 @@
 
     @Test
     public void restartGame_taskIdNotAssociatedWithGame_noOp() throws Exception {
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mGameServiceProviderInstance.start();
 
         startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
         mFakeGameService.requestCreateGameSession(10);
 
         FakeGameSession gameSession10 = new FakeGameSession();
@@ -1170,21 +1124,6 @@
                 .restartTaskActivityProcessIfVisible(anyInt(), anyString());
     }
 
-    @Test
-    public void restartGame_failurePermissionDenied() throws Exception {
-        mGameServiceProviderInstance.start();
-        startTask(10, GAME_A_MAIN_ACTIVITY);
-        mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
-        mFakeGameService.requestCreateGameSession(10);
-        IGameSessionController gameSessionController = Objects.requireNonNull(getOnlyElement(
-                mFakeGameSessionService.getCapturedCreateInvocations())).mGameSessionController;
-        mockPermissionDenied(Manifest.permission.MANAGE_GAME_ACTIVITY);
-        assertThrows(SecurityException.class,
-                () -> gameSessionController.restartGame(10));
-        verify(mActivityTaskManagerInternal, never())
-                .restartTaskActivityProcessIfVisible(anyInt(), anyString());
-    }
-
     private void startTask(int taskId, ComponentName componentName) {
         addRunningTaskInfo(taskId, componentName);
 
@@ -1261,14 +1200,6 @@
         }
     }
 
-    private void mockPermissionGranted(String permission) {
-        mMockContext.setPermission(permission, PackageManager.PERMISSION_GRANTED);
-    }
-
-    private void mockPermissionDenied(String permission) {
-        mMockContext.setPermission(permission, PackageManager.PERMISSION_DENIED);
-    }
-
     private void dispatchTaskSystemBarsEvent(
             ThrowingConsumer<TaskSystemBarsListener> taskSystemBarsListenerConsumer) {
         for (TaskSystemBarsListener listener : mTaskSystemBarsListeners) {
@@ -1409,42 +1340,12 @@
     }
 
     private final class MockContext extends ContextWrapper {
-        // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
-        private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
-
         MockContext(Context base) {
             super(base);
         }
-
-        /**
-         * Mock checks for the specified permission, and have them behave as per {@code granted}.
-         *
-         * <p>Passing null reverts to default behavior, which does a real permission check on the
-         * test package.
-         *
-         * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or
-         *                {@link PackageManager#PERMISSION_DENIED}.
-         */
-        public void setPermission(String permission, Integer granted) {
-            mMockedPermissions.put(permission, granted);
-        }
-
         @Override
         public PackageManager getPackageManager() {
             return mMockPackageManager;
         }
-
-        @Override
-        public void enforceCallingPermission(String permission, @Nullable String message) {
-            final Integer granted = mMockedPermissions.get(permission);
-            if (granted == null) {
-                super.enforceCallingOrSelfPermission(permission, message);
-                return;
-            }
-
-            if (!granted.equals(PackageManager.PERMISSION_GRANTED)) {
-                throw new SecurityException("[Test] permission denied: " + permission);
-            }
-        }
     }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 60ddeeb..7755552 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -149,12 +149,6 @@
                 .thenReturn(mockArray);
         when(mMockedResources.obtainTypedArray(R.array.config_roundedCornerBottomRadiusArray))
                 .thenReturn(mockArray);
-        when(mMockedResources.obtainTypedArray(
-                com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
-                .thenReturn(mockArray);
-        when(mMockedResources.obtainTypedArray(
-                com.android.internal.R.array.config_autoBrightnessLevels))
-                .thenReturn(mockArray);
     }
 
     @After
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
index e6acc90..dd7aeb7 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
@@ -40,8 +40,6 @@
 import com.android.internal.statusbar.ISessionListener;
 import com.android.internal.statusbar.IStatusBarService;
 
-import com.google.common.collect.ImmutableList;
-
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -89,33 +87,64 @@
 
     @Test
     public void testIsAod() throws RemoteException {
-        mListener.onDozeChanged(true);
+        mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
         assertThat(mProvider.isAod()).isTrue();
-        mListener.onDozeChanged(false);
+        mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
         assertThat(mProvider.isAod()).isFalse();
 
         when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(false);
-        mListener.onDozeChanged(true);
+        mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
         assertThat(mProvider.isAod()).isFalse();
-        mListener.onDozeChanged(false);
+        mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
         assertThat(mProvider.isAod()).isFalse();
     }
 
     @Test
+    public void testIsAwake() throws RemoteException {
+        mListener.onDozeChanged(false /* isDozing */, true /* isAwake */);
+        assertThat(mProvider.isAwake()).isTrue();
+        mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
+        assertThat(mProvider.isAwake()).isFalse();
+        mListener.onDozeChanged(true /* isDozing */, true /* isAwake */);
+        assertThat(mProvider.isAwake()).isTrue();
+        mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
+        assertThat(mProvider.isAwake()).isFalse();
+    }
+
+    @Test
     public void testSubscribesToAod() throws RemoteException {
-        final List<Boolean> expected = ImmutableList.of(true, false, true, true, false);
         final List<Boolean> actual = new ArrayList<>();
 
         mProvider.subscribe(mOpContext, ctx -> {
             assertThat(ctx).isSameInstanceAs(mOpContext);
+            assertThat(mProvider.isAod()).isEqualTo(ctx.isAod);
+            assertThat(mProvider.isAwake()).isFalse();
             actual.add(ctx.isAod);
         });
 
-        for (boolean v : expected) {
-            mListener.onDozeChanged(v);
+        for (boolean v : List.of(true, false, true, true, false, false)) {
+            mListener.onDozeChanged(v /* isDozing */, false /* isAwake */);
         }
 
-        assertThat(actual).containsExactlyElementsIn(expected).inOrder();
+        assertThat(actual).containsExactly(true, false, true, false).inOrder();
+    }
+
+    @Test
+    public void testSubscribesToAwake() throws RemoteException {
+        final List<Boolean> actual = new ArrayList<>();
+
+        mProvider.subscribe(mOpContext, ctx -> {
+            assertThat(ctx).isSameInstanceAs(mOpContext);
+            assertThat(ctx.isAod).isFalse();
+            assertThat(mProvider.isAod()).isFalse();
+            actual.add(mProvider.isAwake());
+        });
+
+        for (boolean v : List.of(true, false, true, true, false, false)) {
+            mListener.onDozeChanged(false /* isDozing */, v /* isAwake */);
+        }
+
+        assertThat(actual).containsExactly(true, false, true, false).inOrder();
     }
 
     @Test
@@ -124,13 +153,13 @@
         mProvider.subscribe(mOpContext, emptyConsumer);
         mProvider.unsubscribe(mOpContext);
 
-        mListener.onDozeChanged(true);
+        mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
 
         final Consumer<OperationContext> nonEmptyConsumer = mock(Consumer.class);
         mProvider.subscribe(mOpContext, nonEmptyConsumer);
-        mListener.onDozeChanged(false);
+        mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
         mProvider.unsubscribe(mOpContext);
-        mListener.onDozeChanged(true);
+        mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
 
         verify(emptyConsumer, never()).accept(any());
         verify(nonEmptyConsumer).accept(same(mOpContext));
@@ -171,7 +200,7 @@
 
     @Test
     public void testUpdate() throws RemoteException {
-        mListener.onDozeChanged(false);
+        mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
         OperationContext context = mProvider.updateContext(mOpContext, false /* crypto */);
 
         // default state when nothing has been set
@@ -186,7 +215,7 @@
             final int id = 40 + type;
             final boolean aod = (type & 1) == 0;
 
-            mListener.onDozeChanged(aod);
+            mListener.onDozeChanged(aod /* isDozing */, false /* isAwake */);
             mSessionListener.onSessionStarted(type, InstanceId.fakeInstanceId(id));
             context = mProvider.updateContext(mOpContext, false /* crypto */);
             assertThat(context).isSameInstanceAs(mOpContext);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
index 45e3b43..eb131419 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
@@ -91,8 +91,7 @@
         mToken = new Binder();
         mScheduler = new BiometricScheduler(TAG, new Handler(TestableLooper.get(this).getLooper()),
                 BiometricScheduler.SENSOR_TYPE_UNKNOWN, null /* gestureAvailabilityTracker */,
-                mBiometricService, LOG_NUM_RECENT_OPERATIONS,
-                CoexCoordinator.getInstance());
+                mBiometricService, LOG_NUM_RECENT_OPERATIONS);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
deleted file mode 100644
index abf992b..0000000
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors;
-
-import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FACE;
-import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FP_OTHER;
-import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_UDFPS;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.hardware.biometrics.BiometricConstants;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-
-import com.android.server.biometrics.sensors.fingerprint.Udfps;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.LinkedList;
-
-@Presubmit
-@SmallTest
-public class CoexCoordinatorTest {
-
-    @Rule
-    public final MockitoRule mockito = MockitoJUnit.rule();
-
-    @Mock
-    private CoexCoordinator.Callback mCallback;
-    @Mock
-    private CoexCoordinator.ErrorCallback mErrorCallback;
-    @Mock
-    private AuthenticationClient mFaceClient;
-    @Mock
-    private AuthenticationClient mFingerprintClient;
-    @Mock(extraInterfaces = {Udfps.class})
-    private AuthenticationClient mUdfpsClient;
-
-    private CoexCoordinator mCoexCoordinator;
-
-    @Before
-    public void setUp() {
-        mCoexCoordinator = CoexCoordinator.getInstance();
-        mCoexCoordinator.setAdvancedLogicEnabled(true);
-        mCoexCoordinator.setFaceHapticDisabledWhenNonBypass(true);
-        mCoexCoordinator.reset();
-    }
-
-    @Test
-    public void testBiometricPrompt_authSuccess() {
-        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
-                mFaceClient, mCallback);
-        verify(mCallback).sendHapticFeedback();
-        verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testBiometricPrompt_authReject_whenNotLockedOut() {
-        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
-                mFaceClient, LockoutTracker.LOCKOUT_NONE, mCallback);
-        verify(mCallback).sendHapticFeedback();
-        verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testBiometricPrompt_authReject_whenLockedOut() {
-        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
-                mFaceClient, LockoutTracker.LOCKOUT_TIMED, mCallback);
-        verify(mCallback).sendHapticFeedback();
-        verify(mCallback, never()).sendAuthenticationResult(anyBoolean());
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testBiometricPrompt_coex_success() {
-        testBiometricPrompt_coex_success(false /* twice */);
-    }
-
-    @Test
-    public void testBiometricPrompt_coex_successWithoutDouble() {
-        testBiometricPrompt_coex_success(true /* twice */);
-    }
-
-    private void testBiometricPrompt_coex_success(boolean twice) {
-        initFaceAndFingerprintForBiometricPrompt();
-        when(mFaceClient.wasAuthSuccessful()).thenReturn(true);
-        when(mUdfpsClient.wasAuthSuccessful()).thenReturn(twice, true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
-                mFaceClient, mCallback);
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
-                mUdfpsClient, mCallback);
-
-        if (twice) {
-            verify(mCallback, never()).sendHapticFeedback();
-        } else {
-            verify(mCallback).sendHapticFeedback();
-        }
-    }
-
-    @Test
-    public void testBiometricPrompt_coex_reject() {
-        initFaceAndFingerprintForBiometricPrompt();
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
-                mFaceClient, LockoutTracker.LOCKOUT_NONE, mCallback);
-
-        verify(mCallback, never()).sendHapticFeedback();
-
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
-                    mUdfpsClient, LockoutTracker.LOCKOUT_NONE, mCallback);
-
-        verify(mCallback).sendHapticFeedback();
-    }
-
-    @Test
-    public void testBiometricPrompt_coex_errorNoHaptics() {
-        initFaceAndFingerprintForBiometricPrompt();
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
-        mCoexCoordinator.onAuthenticationError(mFaceClient,
-                BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
-        mCoexCoordinator.onAuthenticationError(mUdfpsClient,
-                BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
-
-        verify(mErrorCallback, never()).sendHapticFeedback();
-    }
-
-    private void initFaceAndFingerprintForBiometricPrompt() {
-        when(mFaceClient.isKeyguard()).thenReturn(false);
-        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-        when(mFaceClient.wasAuthAttempted()).thenReturn(true);
-        when(mUdfpsClient.isKeyguard()).thenReturn(false);
-        when(mUdfpsClient.isBiometricPrompt()).thenReturn(true);
-        when(mUdfpsClient.wasAuthAttempted()).thenReturn(true);
-    }
-
-    @Test
-    public void testKeyguard_faceAuthOnly_success() {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
-                mFaceClient, mCallback);
-        verify(mCallback).sendHapticFeedback();
-        verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testKeyguard_faceAuth_udfpsNotTouching_faceSuccess() {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-
-        when(mUdfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(false);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
-                mFaceClient, mCallback);
-        // Haptics tested in #testKeyguard_bypass_haptics. Let's leave this commented out (instead
-        // of removed) to keep this context.
-        // verify(mCallback).sendHapticFeedback();
-        verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testKeyguard_faceAuthSuccess_nonBypass_udfpsRunning_noHaptics() {
-        testKeyguard_bypass_haptics(false /* bypassEnabled */,
-                true /* faceAccepted */,
-                false /* shouldReceiveHaptics */);
-    }
-
-    @Test
-    public void testKeyguard_faceAuthReject_nonBypass_udfpsRunning_noHaptics() {
-        testKeyguard_bypass_haptics(false /* bypassEnabled */,
-                false /* faceAccepted */,
-                false /* shouldReceiveHaptics */);
-    }
-
-    @Test
-    public void testKeyguard_faceAuthSuccess_bypass_udfpsRunning_haptics() {
-        testKeyguard_bypass_haptics(true /* bypassEnabled */,
-                true /* faceAccepted */,
-                true /* shouldReceiveHaptics */);
-    }
-
-    @Test
-    public void testKeyguard_faceAuthReject_bypass_udfpsRunning_haptics() {
-        testKeyguard_bypass_haptics(true /* bypassEnabled */,
-                false /* faceAccepted */,
-                true /* shouldReceiveHaptics */);
-    }
-
-    private void testKeyguard_bypass_haptics(boolean bypassEnabled, boolean faceAccepted,
-            boolean shouldReceiveHaptics) {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-        when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
-        when(mUdfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(false);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
-        if (faceAccepted) {
-            mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mFaceClient,
-                    mCallback);
-        } else {
-            mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
-                    LockoutTracker.LOCKOUT_NONE, mCallback);
-        }
-
-        if (shouldReceiveHaptics) {
-            verify(mCallback).sendHapticFeedback();
-        } else {
-            verify(mCallback, never()).sendHapticFeedback();
-        }
-
-        verify(mCallback).sendAuthenticationResult(eq(faceAccepted) /* addAuthTokenIfStrong */);
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testKeyguard_faceAuth_udfpsTouching_faceSuccess_thenUdfpsRejectedWithinBounds() {
-        testKeyguard_faceAuth_udfpsTouching_faceSuccess(false /* thenUdfpsAccepted */,
-                0 /* udfpsRejectedAfterMs */);
-    }
-
-    @Test
-    public void testKeyguard_faceAuth_udfpsTouching_faceSuccess_thenUdfpsRejectedAfterBounds() {
-        testKeyguard_faceAuth_udfpsTouching_faceSuccess(false /* thenUdfpsAccepted */,
-                CoexCoordinator.SUCCESSFUL_AUTH_VALID_DURATION_MS + 1 /* udfpsRejectedAfterMs */);
-    }
-
-    @Test
-    public void testKeyguard_faceAuth_udfpsTouching_faceSuccess_thenUdfpsAccepted() {
-        testKeyguard_faceAuth_udfpsTouching_faceSuccess(true /* thenUdfpsAccepted */,
-                0 /* udfpsRejectedAfterMs */);
-    }
-
-    private void testKeyguard_faceAuth_udfpsTouching_faceSuccess(boolean thenUdfpsAccepted,
-            long udfpsRejectedAfterMs) {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-        when(mUdfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
-        when(mUdfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
-        // For easier reading
-        final CoexCoordinator.Callback faceCallback = mCallback;
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mFaceClient,
-                faceCallback);
-        verify(faceCallback, never()).sendHapticFeedback();
-        verify(faceCallback, never()).sendAuthenticationResult(anyBoolean());
-        // CoexCoordinator requests the system to hold onto this AuthenticationClient until
-        // UDFPS result is known
-        verify(faceCallback, never()).handleLifecycleAfterAuth();
-
-        // Reset the mock
-        CoexCoordinator.Callback udfpsCallback = mock(CoexCoordinator.Callback.class);
-        assertEquals(1, mCoexCoordinator.mSuccessfulAuths.size());
-        assertEquals(mFaceClient, mCoexCoordinator.mSuccessfulAuths.get(0).mAuthenticationClient);
-        if (thenUdfpsAccepted) {
-            mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mUdfpsClient,
-                    udfpsCallback);
-            verify(udfpsCallback).sendHapticFeedback();
-            verify(udfpsCallback).sendAuthenticationResult(true /* addAuthTokenIfStrong */);
-            verify(udfpsCallback).handleLifecycleAfterAuth();
-
-            verify(faceCallback).sendAuthenticationCanceled();
-
-            assertTrue(mCoexCoordinator.mSuccessfulAuths.isEmpty());
-        } else {
-            mCoexCoordinator.onAuthenticationRejected(udfpsRejectedAfterMs, mUdfpsClient,
-                    LockoutTracker.LOCKOUT_NONE, udfpsCallback);
-            if (udfpsRejectedAfterMs <= CoexCoordinator.SUCCESSFUL_AUTH_VALID_DURATION_MS) {
-                verify(udfpsCallback, never()).sendHapticFeedback();
-
-                verify(faceCallback).sendHapticFeedback();
-                verify(faceCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
-                verify(faceCallback).handleLifecycleAfterAuth();
-
-                assertTrue(mCoexCoordinator.mSuccessfulAuths.isEmpty());
-            } else {
-                assertTrue(mCoexCoordinator.mSuccessfulAuths.isEmpty());
-
-                verify(faceCallback, never()).sendHapticFeedback();
-                verify(faceCallback, never()).sendAuthenticationResult(anyBoolean());
-
-                verify(udfpsCallback).sendHapticFeedback();
-                verify(udfpsCallback)
-                        .sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
-                verify(udfpsCallback).handleLifecycleAfterAuth();
-            }
-        }
-    }
-
-    @Test
-    public void testKeyguard_udfpsAuthSuccess_whileFaceScanning() {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-        when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(mUdfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mUdfpsClient,
-                mCallback);
-        verify(mCallback).sendHapticFeedback();
-        verify(mCallback).sendAuthenticationResult(eq(true));
-        verify(mFaceClient).cancel();
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testKeyguard_faceRejectedWhenUdfpsTouching_thenUdfpsRejected() {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-        when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(mUdfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(mUdfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
-                LockoutTracker.LOCKOUT_NONE, mCallback);
-        verify(mCallback, never()).sendHapticFeedback();
-        verify(mCallback).handleLifecycleAfterAuth();
-
-        // BiometricScheduler removes the face authentication client after rejection
-        mCoexCoordinator.removeAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
-        // Then UDFPS rejected
-        CoexCoordinator.Callback udfpsCallback = mock(CoexCoordinator.Callback.class);
-        mCoexCoordinator.onAuthenticationRejected(1 /* currentTimeMillis */, mUdfpsClient,
-                LockoutTracker.LOCKOUT_NONE, udfpsCallback);
-        verify(udfpsCallback).sendHapticFeedback();
-        verify(udfpsCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
-        verify(mCallback, never()).sendHapticFeedback();
-    }
-
-    @Test
-    public void testKeyguard_udfpsRejected_thenFaceRejected_noKeyguardBypass() {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-        when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(false); // TODO: also test "true" case
-        when(mUdfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(mUdfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
-                mUdfpsClient, LockoutTracker.LOCKOUT_NONE, mCallback);
-        // Auth was attempted
-        when(mUdfpsClient.getState())
-                .thenReturn(AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED);
-        verify(mCallback).sendHapticFeedback();
-        verify(mCallback).handleLifecycleAfterAuth();
-
-        // Then face rejected. Note that scheduler leaves UDFPS in the CoexCoordinator since
-        // unlike face, its lifecycle becomes "paused" instead of "finished".
-        CoexCoordinator.Callback faceCallback = mock(CoexCoordinator.Callback.class);
-        mCoexCoordinator.onAuthenticationRejected(1 /* currentTimeMillis */, mFaceClient,
-                LockoutTracker.LOCKOUT_NONE, faceCallback);
-        verify(faceCallback).sendHapticFeedback();
-        verify(faceCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
-        verify(mCallback).sendHapticFeedback();
-    }
-
-    @Test
-    public void testKeyguard_capacitiveAccepted_whenFaceScanning() {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-        when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(mFingerprintClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(mFingerprintClient.isKeyguard()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, mFingerprintClient);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
-                mFingerprintClient, mCallback);
-        verify(mCallback).sendHapticFeedback();
-        verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testKeyguard_capacitiveRejected_whenFaceScanning() {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-        when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(mFingerprintClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(mFingerprintClient.isKeyguard()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, mFingerprintClient);
-
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
-                mFingerprintClient, LockoutTracker.LOCKOUT_NONE, mCallback);
-        verify(mCallback).sendHapticFeedback();
-        verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testNonKeyguard_rejectAndNotLockedOut() {
-        when(mFaceClient.isKeyguard()).thenReturn(false);
-        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
-                LockoutTracker.LOCKOUT_NONE, mCallback);
-
-        verify(mCallback).sendHapticFeedback();
-        verify(mCallback).sendAuthenticationResult(eq(false));
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testNonKeyguard_rejectLockedOut() {
-        when(mFaceClient.isKeyguard()).thenReturn(false);
-        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
-                LockoutTracker.LOCKOUT_TIMED, mCallback);
-
-        verify(mCallback).sendHapticFeedback();
-        verify(mCallback, never()).sendAuthenticationResult(anyBoolean());
-        verify(mCallback).handleLifecycleAfterAuth();
-    }
-
-    @Test
-    public void testCleanupRunnable() {
-        LinkedList<CoexCoordinator.SuccessfulAuth> successfulAuths = mock(LinkedList.class);
-        CoexCoordinator.SuccessfulAuth auth = mock(CoexCoordinator.SuccessfulAuth.class);
-        CoexCoordinator.Callback callback = mock(CoexCoordinator.Callback.class);
-        CoexCoordinator.SuccessfulAuth.CleanupRunnable runnable =
-                new CoexCoordinator.SuccessfulAuth.CleanupRunnable(successfulAuths, auth, callback);
-        runnable.run();
-
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-
-        verify(callback).handleLifecycleAfterAuth();
-        verify(successfulAuths).remove(eq(auth));
-    }
-
-    @Test
-    public void testBiometricPrompt_FaceError() {
-        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-        when(mFaceClient.wasAuthAttempted()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
-        mCoexCoordinator.onAuthenticationError(mFaceClient,
-                BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
-        verify(mErrorCallback).sendHapticFeedback();
-    }
-
-    @Test
-    public void testKeyguard_faceAuthOnly_errorWhenBypassEnabled() {
-        testKeyguard_faceAuthOnly(true /* bypassEnabled */);
-    }
-
-    @Test
-    public void testKeyguard_faceAuthOnly_errorWhenBypassDisabled() {
-        testKeyguard_faceAuthOnly(false /* bypassEnabled */);
-    }
-
-    private void testKeyguard_faceAuthOnly(boolean bypassEnabled) {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-        when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
-        when(mFaceClient.wasAuthAttempted()).thenReturn(true);
-        when(mFaceClient.wasUserDetected()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
-        mCoexCoordinator.onAuthenticationError(mFaceClient,
-                BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
-        verify(mErrorCallback).sendHapticFeedback();
-    }
-
-    @Test
-    public void testKeyguard_coex_faceErrorWhenBypassEnabled() {
-        testKeyguard_coex_faceError(true /* bypassEnabled */);
-    }
-
-    @Test
-    public void testKeyguard_coex_faceErrorWhenBypassDisabled() {
-        testKeyguard_coex_faceError(false /* bypassEnabled */);
-    }
-
-    private void testKeyguard_coex_faceError(boolean bypassEnabled) {
-        when(mFaceClient.isKeyguard()).thenReturn(true);
-        when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
-        when(mFaceClient.wasAuthAttempted()).thenReturn(true);
-        when(mFaceClient.wasUserDetected()).thenReturn(true);
-        when(mUdfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(false);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
-        mCoexCoordinator.onAuthenticationError(mFaceClient,
-                BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
-
-        if (bypassEnabled) {
-            verify(mErrorCallback).sendHapticFeedback();
-        } else {
-            verify(mErrorCallback, never()).sendHapticFeedback();
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
index 0df3028..0815fe5 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
@@ -118,8 +118,7 @@
                                 TEST_SENSOR_ID,  mBiometricLogger, mBiometricContext,
                                 mUserStartedCallback, mStartOperationsFinish);
                     }
-                },
-                CoexCoordinator.getInstance());
+                });
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
index b60324e..518946a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
@@ -35,7 +35,6 @@
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.sensors.BiometricScheduler;
-import com.android.server.biometrics.sensors.CoexCoordinator;
 import com.android.server.biometrics.sensors.LockoutCache;
 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
 import com.android.server.biometrics.sensors.LockoutTracker;
@@ -91,8 +90,7 @@
                 null /* gestureAvailabilityDispatcher */,
                 mBiometricService,
                 () -> USER_ID,
-                mUserSwitchCallback,
-                CoexCoordinator.getInstance());
+                mUserSwitchCallback);
         mHalCallback = new Sensor.HalSessionCallback(mContext, new Handler(mLooper.getLooper()),
                 TAG, mScheduler, SENSOR_ID,
                 USER_ID, mLockoutCache, mLockoutResetDispatcher, mHalSessionCallback);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index 1ed52fc..dea4d4f 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -26,8 +26,8 @@
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.same;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -96,6 +96,7 @@
             InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
     @Rule
     public final MockitoRule mockito = MockitoJUnit.rule();
+
     @Mock
     private ISession mHal;
     @Mock
@@ -213,21 +214,41 @@
     }
 
     @Test
-    public void luxProbeWhenFingerDown() throws RemoteException {
+    public void luxProbeWhenAwake() throws RemoteException {
+        when(mBiometricContext.isAwake()).thenReturn(false, true, false);
+        when(mBiometricContext.isAod()).thenReturn(false);
         final FingerprintAuthenticationClient client = createClient();
         client.start(mCallback);
 
-        client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR);
-        verify(mLuxProbe).enable();
+        verify(mHal).authenticateWithContext(eq(OP_ID), mOperationContextCaptor.capture());
+        OperationContext opContext = mOperationContextCaptor.getValue();
+        verify(mBiometricContext).subscribe(eq(opContext), mContextInjector.capture());
 
-        client.onAcquired(2, 0);
+        mContextInjector.getValue().accept(opContext);
+        verify(mLuxProbe, never()).enable();
+
+        reset(mLuxProbe);
+        mContextInjector.getValue().accept(opContext);
+        verify(mLuxProbe).enable();
         verify(mLuxProbe, never()).disable();
 
-        client.onPointerUp();
+        mContextInjector.getValue().accept(opContext);
         verify(mLuxProbe).disable();
+    }
 
-        client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR);
-        verify(mLuxProbe, times(2)).enable();
+    @Test
+    public void luxProbeDisabledOnAod() throws RemoteException {
+        when(mBiometricContext.isAwake()).thenReturn(false);
+        when(mBiometricContext.isAod()).thenReturn(true);
+        final FingerprintAuthenticationClient client = createClient();
+        client.start(mCallback);
+
+        verify(mHal).authenticateWithContext(eq(OP_ID), mOperationContextCaptor.capture());
+        OperationContext opContext = mOperationContextCaptor.getValue();
+        verify(mBiometricContext).subscribe(eq(opContext), mContextInjector.capture());
+
+        mContextInjector.getValue().accept(opContext);
+        verify(mLuxProbe, never()).enable();
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java
index 97fe9ea..92e1f27a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java
@@ -64,6 +64,7 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.ArrayList;
 import java.util.function.Consumer;
 
 @Presubmit
@@ -196,21 +197,22 @@
     }
 
     @Test
-    public void luxProbeWhenFingerDown() throws RemoteException {
+    public void luxProbeWhenStarted() throws RemoteException {
         final FingerprintEnrollClient client = createClient();
         client.start(mCallback);
 
-        client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR);
         verify(mLuxProbe).enable();
 
         client.onAcquired(2, 0);
-        verify(mLuxProbe, never()).disable();
-
         client.onPointerUp();
-        verify(mLuxProbe).disable();
-
         client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR);
-        verify(mLuxProbe, times(2)).enable();
+        verify(mLuxProbe, never()).disable();
+        verify(mLuxProbe, never()).destroy();
+
+        client.onEnrollResult(new Fingerprint("f", 30 /* fingerId */, 14 /* deviceId */),
+                0 /* remaining */);
+
+        verify(mLuxProbe).destroy();
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
index e1a4a2d..ff636c8 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
@@ -35,7 +35,6 @@
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
 import com.android.server.biometrics.sensors.BiometricScheduler;
-import com.android.server.biometrics.sensors.CoexCoordinator;
 import com.android.server.biometrics.sensors.LockoutCache;
 import com.android.server.biometrics.sensors.LockoutResetDispatcher;
 import com.android.server.biometrics.sensors.LockoutTracker;
@@ -91,8 +90,7 @@
                 null /* gestureAvailabilityDispatcher */,
                 mBiometricService,
                 () -> USER_ID,
-                mUserSwitchCallback,
-                CoexCoordinator.getInstance());
+                mUserSwitchCallback);
         mHalCallback = new Sensor.HalSessionCallback(mContext, new Handler(mLooper.getLooper()),
                 TAG, mScheduler, SENSOR_ID,
                 USER_ID, mLockoutCache, mLockoutResetDispatcher, mHalSessionCallback);
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 261b882..03ea613 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -19,19 +19,16 @@
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyFloat;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -55,16 +52,22 @@
     private Resources mResources;
 
     @Before
-    public void setUp() {
+    public void setUp() throws IOException {
         MockitoAnnotations.initMocks(this);
         when(mContext.getResources()).thenReturn(mResources);
         mockDeviceConfigs();
+        try {
+            Path tempFile = Files.createTempFile("display_config", ".tmp");
+            Files.write(tempFile, getContent().getBytes(StandardCharsets.UTF_8));
+            mDisplayDeviceConfig = new DisplayDeviceConfig(mContext);
+            mDisplayDeviceConfig.initFromFile(tempFile.toFile());
+        } catch (IOException e) {
+            throw new IOException("Failed to setup the display device config.", e);
+        }
     }
 
     @Test
-    public void testConfigValuesFromDisplayConfig() throws IOException {
-        setupDisplayDeviceConfigFromDisplayConfigFile();
-
+    public void testConfigValues() {
         assertEquals(mDisplayDeviceConfig.getAmbientHorizonLong(), 5000);
         assertEquals(mDisplayDeviceConfig.getAmbientHorizonShort(), 50);
         assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000);
@@ -85,24 +88,10 @@
         assertEquals(mDisplayDeviceConfig.getScreenDarkeningMinThreshold(), 0.002, 0.000001f);
         assertEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLightDebounce(), 2000);
         assertEquals(mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounce(), 1000);
-        assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
-                float[]{50.0f, 80.0f}, 0.0f);
-        assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
-                float[]{45.0f, 75.0f}, 0.0f);
+
         // Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
         // HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
-    }
-
-    @Test
-    public void testConfigValuesFromDeviceConfig() {
-        setupDisplayDeviceConfigFromDeviceConfigFile();
-        assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
-                float[]{0.0f, 110.0f, 500.0f}, 0.0f);
-        assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
-                float[]{2.0f, 200.0f, 600.0f}, 0.0f);
-        // Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
-        // HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
-
+        // Also add test for the case where optional display configs are null
     }
 
     private String getContent() {
@@ -125,16 +114,6 @@
                 +   "<autoBrightness>\n"
                 +       "<brighteningLightDebounceMillis>2000</brighteningLightDebounceMillis>\n"
                 +       "<darkeningLightDebounceMillis>1000</darkeningLightDebounceMillis>\n"
-                +       "<displayBrightnessMapping>\n"
-                +            "<displayBrightnessPoint>\n"
-                +                "<lux>50</lux>\n"
-                +                "<nits>45</nits>\n"
-                +            "</displayBrightnessPoint>\n"
-                +            "<displayBrightnessPoint>\n"
-                +                "<lux>80</lux>\n"
-                +                "<nits>75</nits>\n"
-                +            "</displayBrightnessPoint>\n"
-                +       "</displayBrightnessMapping>\n"
                 +   "</autoBrightness>\n"
                 +   "<highBrightnessMode enabled=\"true\">\n"
                 +       "<transitionPoint>0.62</transitionPoint>\n"
@@ -206,64 +185,4 @@
         when(mResources.getFloat(com.android.internal.R.dimen
                 .config_screenBrightnessSettingMaximumFloat)).thenReturn(1.0f);
     }
-
-    private void setupDisplayDeviceConfigFromDisplayConfigFile() throws IOException {
-        Path tempFile = Files.createTempFile("display_config", ".tmp");
-        Files.write(tempFile, getContent().getBytes(StandardCharsets.UTF_8));
-        mDisplayDeviceConfig = new DisplayDeviceConfig(mContext);
-        mDisplayDeviceConfig.initFromFile(tempFile.toFile());
-    }
-
-    private void setupDisplayDeviceConfigFromDeviceConfigFile() {
-        TypedArray screenBrightnessNits = createFloatTypedArray(new float[]{2.0f, 250.0f, 650.0f});
-        when(mResources.obtainTypedArray(
-                com.android.internal.R.array.config_screenBrightnessNits))
-                .thenReturn(screenBrightnessNits);
-        TypedArray screenBrightnessBacklight = createFloatTypedArray(new
-                float[]{0.0f, 120.0f, 255.0f});
-        when(mResources.obtainTypedArray(
-                com.android.internal.R.array.config_screenBrightnessBacklight))
-                .thenReturn(screenBrightnessBacklight);
-        when(mResources.getIntArray(com.android.internal.R.array
-                .config_screenBrightnessBacklight)).thenReturn(new int[]{0, 120, 255});
-
-        when(mResources.getIntArray(com.android.internal.R.array
-                .config_autoBrightnessLevels)).thenReturn(new int[]{30, 80});
-        when(mResources.getIntArray(com.android.internal.R.array
-                .config_autoBrightnessDisplayValuesNits)).thenReturn(new int[]{25, 55});
-
-        TypedArray screenBrightnessLevelNits = createFloatTypedArray(new
-                float[]{2.0f, 200.0f, 600.0f});
-        when(mResources.obtainTypedArray(
-                com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
-                .thenReturn(screenBrightnessLevelNits);
-        TypedArray screenBrightnessLevelLux = createFloatTypedArray(new
-                float[]{0.0f, 110.0f, 500.0f});
-        when(mResources.obtainTypedArray(
-                com.android.internal.R.array.config_autoBrightnessLevels))
-                .thenReturn(screenBrightnessLevelLux);
-
-        mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
-
-    }
-
-    private TypedArray createFloatTypedArray(float[] vals) {
-        TypedArray mockArray = mock(TypedArray.class);
-        when(mockArray.length()).thenAnswer(invocation -> {
-            return vals.length;
-        });
-        when(mockArray.getFloat(anyInt(), anyFloat())).thenAnswer(invocation -> {
-            final float def = (float) invocation.getArguments()[1];
-            if (vals == null) {
-                return def;
-            }
-            int idx = (int) invocation.getArguments()[0];
-            if (idx >= 0 && idx < vals.length) {
-                return vals[idx];
-            } else {
-                return def;
-            }
-        });
-        return mockArray;
-    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 4449483..25c8f14 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2869,6 +2869,7 @@
                 mAtm, null /* fragmentToken */, false /* createdByOrganizer */);
         fragmentSetup.accept(taskFragment1, new Rect(0, 0, width / 2, height));
         task.addChild(taskFragment1, POSITION_TOP);
+        assertEquals(task, activity1.mStartingData.mAssociatedTask);
 
         final TaskFragment taskFragment2 = new TaskFragment(
                 mAtm, null /* fragmentToken */, false /* createdByOrganizer */);
@@ -2890,7 +2891,6 @@
                 eq(task.mSurfaceControl));
         assertEquals(activity1.mStartingData, startingWindow.mStartingData);
         assertEquals(task.mSurfaceControl, startingWindow.getAnimationLeashParent());
-        assertEquals(task, activity1.mStartingData.mAssociatedTask);
         assertEquals(taskFragment1.getBounds(), activity1.getBounds());
         // The activity was resized by task fragment, but starting window must still cover the task.
         assertEquals(taskBounds, activity1.mStartingWindow.getBounds());
@@ -2898,7 +2898,6 @@
         // The starting window is only removed when all embedded activities are drawn.
         final WindowState activityWindow = mock(WindowState.class);
         activity1.onFirstWindowDrawn(activityWindow);
-        assertNotNull(activity1.mStartingWindow);
         activity2.onFirstWindowDrawn(activityWindow);
         assertNull(activity1.mStartingWindow);
     }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
index 3853af2..1a40f82 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
@@ -164,7 +164,6 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                     .getConfigNonRotationTests(
-                            repetitions = 1,
                             supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
                             supportedNavigationModes = listOf(
                                     WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index 9cc1bfe..ec2b4fa 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -95,7 +95,7 @@
         @JvmStatic
         fun getParams(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index 58a8011..55d4129 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -103,7 +103,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
index f6f3f58..725c10a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
@@ -113,8 +113,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 3,
-                    // b/190352379 (IME doesn't show on app launch in 90 degrees)
+                                        // b/190352379 (IME doesn't show on app launch in 90 degrees)
                     supportedRotations = listOf(Surface.ROTATION_0),
                     supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index 52f561e..8832686 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -123,7 +123,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = 3,
+                .getConfigNonRotationTests(
                     // b/190352379 (IME doesn't show on app launch in 90 degrees)
                     supportedRotations = listOf(Surface.ROTATION_0),
                     supportedNavigationModes = listOf(
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
index c6e25d3..71e0aa1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
@@ -141,7 +141,6 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 2,
                     supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
                         WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
index 23bd220..0f91fd5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
@@ -121,7 +121,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index 8ce1840..007a4f1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -134,8 +134,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 3,
-                    supportedRotations = listOf(Surface.ROTATION_0),
+                                        supportedRotations = listOf(Surface.ROTATION_0),
                     supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
                         WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
index a04a50f..216e0eda 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
@@ -127,14 +127,13 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(
-                            repetitions = 3,
-                            supportedRotations = listOf(Surface.ROTATION_0),
-                            supportedNavigationModes = listOf(
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
-                                    WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
-                            )
+                .getConfigNonRotationTests(
+                    supportedRotations = listOf(Surface.ROTATION_0),
+                    supportedNavigationModes = listOf(
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
+                        WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
                     )
+                )
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
index 04e4bc9..868290e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
@@ -141,8 +141,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 3,
-                    supportedRotations = listOf(Surface.ROTATION_0),
+                                        supportedRotations = listOf(Surface.ROTATION_0),
                     supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
                         WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
index b10aed3..16c23b9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
@@ -82,8 +82,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 3,
-                    supportedRotations = listOf(Surface.ROTATION_0),
+                                        supportedRotations = listOf(Surface.ROTATION_0),
                     supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
                         WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
index d900815..e587492 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
@@ -117,8 +117,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 3,
-                    supportedRotations = listOf(Surface.ROTATION_90),
+                                        supportedRotations = listOf(Surface.ROTATION_90),
                     supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
                     )
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
index fdc2193..c1f17f3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
@@ -95,8 +95,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 3,
-                    supportedRotations = listOf(Surface.ROTATION_0),
+                                        supportedRotations = listOf(Surface.ROTATION_0),
                     supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
                         WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
index 9475734..5fd9442 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
@@ -265,7 +265,6 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 1,
                     supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
                     supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
index 2e22e62..0281a60 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
@@ -192,8 +192,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 3,
-                    supportedRotations = listOf(Surface.ROTATION_0)
+                                        supportedRotations = listOf(Surface.ROTATION_0)
                 )
         }
     }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
index 4f47ec4..85bf6d7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
@@ -200,8 +200,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 3,
-                    supportedNavigationModes = listOf(
+                                        supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
                     ),
                     supportedRotations = listOf(Surface.ROTATION_0)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
index 33c280e..eb9acc4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
@@ -142,7 +142,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
index bfc7b39..b3db5b70 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
@@ -171,7 +171,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(repetitions = 3)
+                    .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
index f93d7a0..8c1d244 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
@@ -221,7 +221,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(repetitions = 3)
+                    .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
index 75311ea..caf2e2d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
@@ -127,7 +127,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                    .getConfigNonRotationTests(repetitions = 3)
+                    .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
index dbe5418..e744d44 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
@@ -157,7 +157,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
index 915b702..4ea4243 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
@@ -284,7 +284,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index 7c07ace..a3dd0cb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -130,7 +130,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index 53be7d4..82e30ac 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -233,8 +233,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 3,
-                    supportedNavigationModes =
+                                        supportedNavigationModes =
                     listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY),
                     supportedRotations = listOf(Surface.ROTATION_0)
                 )
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
index fe5e74b..5f342a0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
@@ -263,7 +263,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigNonRotationTests(repetitions = 3)
+                .getConfigNonRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
index 181767b..f85bad3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
@@ -278,8 +278,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                 .getConfigNonRotationTests(
-                    repetitions = 3,
-                    supportedNavigationModes = listOf(
+                                        supportedNavigationModes = listOf(
                         WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
                     ),
                     supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index 0f05622..f6392ca 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -298,8 +298,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                     .getConfigNonRotationTests(
-                            repetitions = 3,
-                            supportedNavigationModes = listOf(
+                                                        supportedNavigationModes = listOf(
                                     WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
                             ),
                             supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index d1f356c..a714111 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -324,8 +324,7 @@
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
                     .getConfigNonRotationTests(
-                            repetitions = 3,
-                            supportedNavigationModes = listOf(
+                                                        supportedNavigationModes = listOf(
                                     WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
                             ),
                             // TODO: Test with 90 rotation
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 4be8963..e6c1eac 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -146,7 +146,7 @@
         @JvmStatic
         fun getParams(): Collection<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigRotationTests(repetitions = 3)
+                .getConfigRotationTests()
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index 0912812..07c2130 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -241,7 +241,7 @@
         @JvmStatic
         private fun getConfigurations(): List<FlickerTestParameter> {
             return FlickerTestParameterFactory.getInstance()
-                .getConfigRotationTests(repetitions = 2)
+                .getConfigRotationTests()
                 .flatMap { sourceConfig ->
                     val defaultRun = createConfig(sourceConfig, starveUiThread = false)
                     val busyUiRun = createConfig(sourceConfig, starveUiThread = true)
diff --git a/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java b/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
index 8b69db7..dc34cb6 100644
--- a/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
+++ b/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
@@ -15,21 +15,25 @@
  */
 package com.google.android.test.handwritingime;
 
+import android.R;
 import android.annotation.Nullable;
 import android.graphics.PointF;
 import android.graphics.RectF;
 import android.inputmethodservice.InputMethodService;
-import android.os.Bundle;
 import android.util.Log;
-import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
-import android.view.inputmethod.CursorAnchorInfo;
+import android.view.inputmethod.DeleteGesture;
+import android.view.inputmethod.HandwritingGesture;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InsertGesture;
+import android.view.inputmethod.SelectGesture;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.FrameLayout;
+import android.widget.LinearLayout;
 import android.widget.Spinner;
 import android.widget.Toast;
 
@@ -39,19 +43,19 @@
 
     public static final int HEIGHT_DP = 100;
 
-
     private static final int OP_NONE = 0;
     private static final int OP_SELECT = 1;
     private static final int OP_DELETE = 2;
-    private static final int OP_DELETE_SPACE = 3;
-    private static final int OP_INSERT = 4;
+    private static final int OP_INSERT = 3;
 
     private Window mInkWindow;
     private InkView mInk;
 
     static final String TAG = "HandwritingIme";
     private int mRichGestureMode = OP_NONE;
+    private int mRichGestureGranularity = -1;
     private Spinner mRichGestureModeSpinner;
+    private Spinner mRichGestureGranularitySpinner;
     private PointF mRichGestureStartPoint;
 
 
@@ -86,13 +90,45 @@
         switch (event.getAction()) {
             case MotionEvent.ACTION_UP: {
                 if (areRichGesturesEnabled()) {
-                    Bundle bundle = new Bundle();
-                    bundle.putInt("operation", mRichGestureMode);
-                    bundle.putFloat("left", mRichGestureStartPoint.x);
-                    bundle.putFloat("top", mRichGestureStartPoint.y);
-                    bundle.putFloat("right", event.getX());
-                    bundle.putFloat("bottom", event.getY());
-                    performPrivateCommand("android.widget.RichGesture", bundle);
+                    HandwritingGesture gesture = null;
+                    switch(mRichGestureMode) {
+                        case OP_SELECT:
+                            SelectGesture.Builder builder = new SelectGesture.Builder();
+                            builder.setGranularity(mRichGestureGranularity)
+                                    .setSelectionArea(new RectF(mRichGestureStartPoint.x,
+                                            mRichGestureStartPoint.y, event.getX(), event.getY()))
+                                    .setFallbackText("fallback text");
+                            gesture = builder.build();
+                            break;
+                        case OP_DELETE:
+                            DeleteGesture.Builder builder1 = new DeleteGesture.Builder();
+                            builder1.setGranularity(mRichGestureGranularity)
+                                    .setDeletionArea(new RectF(mRichGestureStartPoint.x,
+                                            mRichGestureStartPoint.y, event.getX(), event.getY()))
+                                    .setFallbackText("fallback text");
+                            gesture = builder1.build();
+                            break;
+                        case OP_INSERT:
+                            InsertGesture.Builder builder2 = new InsertGesture.Builder();
+                            builder2.setInsertionPoint(
+                                    new PointF(mRichGestureStartPoint.x, mRichGestureStartPoint.y))
+                                    .setTextToInsert(" ")
+                                    .setFallbackText("fallback text");
+                            gesture = builder2.build();
+
+                    }
+                    if (gesture == null) {
+                        // This shouldn't happen
+                        Log.e(TAG, "Unrecognized gesture mode: " + mRichGestureMode);
+                        return;
+                    }
+                    InputConnection ic = getCurrentInputConnection();
+                    if (getCurrentInputStarted() && ic != null) {
+                        ic.performHandwritingGesture(gesture, null, null);
+                    } else {
+                        // This shouldn't happen
+                        Log.e(TAG, "No active InputConnection");
+                    }
 
                     Log.d(TAG, "Sending RichGesture " + mRichGestureMode + " (Screen) Left: "
                             + mRichGestureStartPoint.x + ", Top: " + mRichGestureStartPoint.y
@@ -123,8 +159,15 @@
         view.addView(inner, new FrameLayout.LayoutParams(
                 FrameLayout.LayoutParams.MATCH_PARENT, height));
 
-        view.addView(getRichGestureActionsSpinner());
-        inner.setBackgroundColor(getColor(R.color.abc_tint_spinner));
+        LinearLayout layout = new LinearLayout(this);
+        layout.setLayoutParams(new LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+        layout.setOrientation(LinearLayout.VERTICAL);
+        layout.addView(getRichGestureActionsSpinner());
+        layout.addView(getRichGestureGranularitySpinner());
+
+        view.addView(layout);
+        inner.setBackgroundColor(getColor(R.color.holo_green_light));
 
         return view;
     }
@@ -133,14 +176,12 @@
         if (mRichGestureModeSpinner != null) {
             return mRichGestureModeSpinner;
         }
-        //get the spinner from the xml.
         mRichGestureModeSpinner = new Spinner(this);
         mRichGestureModeSpinner.setPadding(100, 0, 100, 0);
         mRichGestureModeSpinner.setTooltipText("Handwriting IME mode");
         String[] items =
                 new String[] { "Handwriting IME - Rich gesture disabled", "Rich gesture SELECT",
-                        "Rich gesture DELETE", "Rich gesture DELETE SPACE",
-                        "Rich gesture INSERT" };
+                        "Rich gesture DELETE", "Rich gesture INSERT" };
         ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
                 android.R.layout.simple_spinner_dropdown_item, items);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
@@ -149,17 +190,52 @@
             @Override
             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                 mRichGestureMode = position;
+                mRichGestureGranularitySpinner.setEnabled(
+                        mRichGestureMode != OP_INSERT && mRichGestureMode != OP_NONE);
                 Log.d(TAG, "Setting RichGesture Mode " + mRichGestureMode);
             }
 
             @Override
             public void onNothingSelected(AdapterView<?> parent) {
                 mRichGestureMode = OP_NONE;
+                mRichGestureGranularitySpinner.setEnabled(false);
             }
         });
+        mRichGestureModeSpinner.setSelection(0); // default disabled
         return mRichGestureModeSpinner;
     }
 
+    private View getRichGestureGranularitySpinner() {
+        if (mRichGestureGranularitySpinner != null) {
+            return mRichGestureGranularitySpinner;
+        }
+        mRichGestureGranularitySpinner = new Spinner(this);
+        mRichGestureGranularitySpinner.setPadding(100, 0, 100, 0);
+        mRichGestureGranularitySpinner.setTooltipText(" Granularity");
+        String[] items =
+                new String[] { "Granularity - UNDEFINED",
+                        "Granularity - WORD", "Granularity - CHARACTER"};
+        ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
+                android.R.layout.simple_spinner_dropdown_item, items);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mRichGestureGranularitySpinner.setAdapter(adapter);
+        mRichGestureGranularitySpinner.setOnItemSelectedListener(
+                new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+                mRichGestureGranularity = position;
+                Log.d(TAG, "Setting RichGesture Granularity " + mRichGestureGranularity);
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+                mRichGestureGranularity = 0;
+            }
+        });
+        mRichGestureGranularitySpinner.setSelection(1);
+        return mRichGestureGranularitySpinner;
+    }
+
     public void onPrepareStylusHandwriting() {
         Log.d(TAG, "onPrepareStylusHandwriting ");
         if (mInk == null) {
@@ -190,15 +266,6 @@
         return false;
     }
 
-    boolean performPrivateCommand(String action, Bundle bundle) {
-        if (!getCurrentInputStarted()) {
-            Log.e(TAG, "Input hasnt started, can't performPrivateCommand");
-            return false;
-        }
-
-        return getCurrentInputConnection().performPrivateCommand(action, bundle);
-    }
-
     private boolean areRichGesturesEnabled() {
         return mRichGestureMode != OP_NONE;
     }
diff --git a/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java b/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
index c9e429b..94b1f86 100644
--- a/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
+++ b/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
@@ -30,7 +30,7 @@
 import android.view.WindowMetrics;
 
 class InkView extends View {
-    private static final long FINISH_TIMEOUT = 600;
+    private static final long FINISH_TIMEOUT = 1500;
     private final HandwritingIme.HandwritingFinisher mHwCanceller;
     private final HandwritingIme.StylusConsumer mConsumer;
     private final int mTopInset;
diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp
index 9f6ce4e..b7c4c5b 100644
--- a/tests/RollbackTest/Android.bp
+++ b/tests/RollbackTest/Android.bp
@@ -61,6 +61,7 @@
     static_libs: ["RollbackTestLib", "frameworks-base-hostutils"],
     test_suites: ["general-tests"],
     test_config: "NetworkStagedRollbackTest.xml",
+    data: [":RollbackTest"],
 }
 
 java_test_host {
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index 1709e15..ffde8c7 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -58,6 +58,7 @@
         ":apex.apexd_test",
         ":com.android.apex.apkrollback.test_v1",
         ":com.android.apex.apkrollback.test_v2",
+        ":StagedInstallInternalTestApp",
         ":StagedInstallTestApexV2",
         ":StagedInstallTestApexV2_WrongSha",
         ":TestAppAv1",
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index 46a846b..4fb7ed1 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -369,9 +369,13 @@
 
     bool sparse_encode = use_sparse_entries_;
 
-    // Only sparse encode if the entries will be read on platforms O+.
-    sparse_encode =
-        sparse_encode && (context_->GetMinSdkVersion() >= SDK_O || config.sdkVersion >= SDK_O);
+    if (context_->GetMinSdkVersion() == 0 && config.sdkVersion == 0) {
+      // Sparse encode if sdk version is not set in context and config.
+    } else {
+      // Otherwise, only sparse encode if the entries will be read on platforms S_V2+.
+      sparse_encode = sparse_encode &&
+                      (context_->GetMinSdkVersion() >= SDK_S_V2 || config.sdkVersion >= SDK_S_V2);
+    }
 
     // Only sparse encode if the offsets are representable in 2 bytes.
     sparse_encode =
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index e48fca6..f551bf6 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -330,7 +330,7 @@
   std::unique_ptr<IAaptContext> context = test::ContextBuilder()
                                               .SetCompilationPackage("android")
                                               .SetPackageId(0x01)
-                                              .SetMinSdkVersion(SDK_O)
+                                              .SetMinSdkVersion(SDK_S_V2)
                                               .Build();
 
   const ConfigDescription sparse_config = test::ParseConfigOrDie("en-rGB");
@@ -376,7 +376,7 @@
                                               .SetMinSdkVersion(SDK_LOLLIPOP)
                                               .Build();
 
-  const ConfigDescription sparse_config = test::ParseConfigOrDie("en-rGB-v26");
+  const ConfigDescription sparse_config = test::ParseConfigOrDie("en-rGB-v32");
   auto table_in = BuildTableWithSparseEntries(context.get(), sparse_config, 0.25f);
 
   TableFlattenerOptions options;
@@ -391,6 +391,46 @@
   EXPECT_GT(no_sparse_contents.size(), sparse_contents.size());
 }
 
+TEST_F(TableFlattenerTest, FlattenSparseEntryWithSdkVersionNotSet) {
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder().SetCompilationPackage("android").SetPackageId(0x01).Build();
+
+  const ConfigDescription sparse_config = test::ParseConfigOrDie("en-rGB");
+  auto table_in = BuildTableWithSparseEntries(context.get(), sparse_config, 0.25f);
+
+  TableFlattenerOptions options;
+  options.use_sparse_entries = true;
+
+  std::string no_sparse_contents;
+  ASSERT_TRUE(Flatten(context.get(), {}, table_in.get(), &no_sparse_contents));
+
+  std::string sparse_contents;
+  ASSERT_TRUE(Flatten(context.get(), options, table_in.get(), &sparse_contents));
+
+  EXPECT_GT(no_sparse_contents.size(), sparse_contents.size());
+
+  // Attempt to parse the sparse contents.
+
+  ResourceTable sparse_table;
+  BinaryResourceParser parser(context->GetDiagnostics(), &sparse_table, Source("test.arsc"),
+                              sparse_contents.data(), sparse_contents.size());
+  ASSERT_TRUE(parser.Parse());
+
+  auto value = test::GetValueForConfig<BinaryPrimitive>(&sparse_table, "android:string/foo_0",
+                                                        sparse_config);
+  ASSERT_THAT(value, NotNull());
+  EXPECT_EQ(0u, value->value.data);
+
+  ASSERT_THAT(test::GetValueForConfig<BinaryPrimitive>(&sparse_table, "android:string/foo_1",
+                                                       sparse_config),
+              IsNull());
+
+  value = test::GetValueForConfig<BinaryPrimitive>(&sparse_table, "android:string/foo_4",
+                                                   sparse_config);
+  ASSERT_THAT(value, NotNull());
+  EXPECT_EQ(4u, value->value.data);
+}
+
 TEST_F(TableFlattenerTest, DoNotUseSparseEntryForDenseConfig) {
   std::unique_ptr<IAaptContext> context = test::ContextBuilder()
                                               .SetCompilationPackage("android")